package com.handheld.LF125K;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import cn.pda.serialport.SerialPort;
import cn.pda.serialport.Tools;

public class Lf125KManager {
	public static int Port = 14; //
	public static int Power = SerialPort.Power_3v3;
	/**
	 * open device 
	 * @param mHandler
	 * @return
	 */
	public boolean open(Handler mHandler) {
		startFlag = false;
		runFlag = true;
		handler = mHandler;
		try {
			mSerialPort = new SerialPort();
			mSerialPort = new SerialPort(Port, BaudRate, 0);
			switch (Power) {
			case SerialPort.Power_Scaner:
				mSerialPort.scaner_poweron();
				break;
			case SerialPort.Power_3v3:
				mSerialPort.power3v3on();
				mSerialPort.psam_poweron();
				break;
			case SerialPort.Power_5v:
				mSerialPort.power_5Von();
				break;
			case SerialPort.Power_Psam:
				mSerialPort.psam_poweron();
				break;
			case SerialPort.Power_Rfid:
				mSerialPort.rfid_poweron();
				break;
			}
			mInputStream = mSerialPort.getInputStream();
			mReadThread = new ReadThread();
			mReadThread.start();
			//Log.e("open", Port+":"+Power+":"+BaudRate+"");
		} catch (SecurityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return true;
	}
	public void setHandler(Handler handler) {
		this.handler =handler;
	}
	/**
	 * pause search card 
	 */
	public void pause() {
		startFlag = false;
//		if (mInputStream!=null) {
//			try {
//				mInputStream.read(new byte[4906]);
//			} catch (IOException e) {
//				// TODO Auto-generated catch block
//				e.printStackTrace();
//			}
//		}
	}
	// start search card or continue search card
	public void start() {
		if (mInputStream!=null) {
			try {
				mInputStream.read(new byte[4906]);
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		startFlag = true;
	}
	public boolean close() {
		//Log.e("125K", "close"+Port+Power);
		if (mReadThread!=null) {
			startFlag = false;
			runFlag = false;
			mReadThread.interrupt();
		}
		try {
			mInputStream.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
		if (mSerialPort!=null) {
			mSerialPort.close(Port);
		}
		switch (Power) {
		case SerialPort.Power_Scaner:
			mSerialPort.scaner_poweroff();
			break;
		case SerialPort.Power_3v3:
			mSerialPort.power_3v3off();
			mSerialPort.psam_poweroff();
			break;
		case SerialPort.Power_5v:
			mSerialPort.power_5Voff();
			break;
		case SerialPort.Power_Psam:
			mSerialPort.psam_poweroff();
			break;
		case SerialPort.Power_Rfid:
			mSerialPort.rfid_poweroff();
			break;
		}
		return true;
	}
	private static Handler handler;
	private boolean runFlag = true;
	private boolean startFlag = false;

	public static boolean Hex = false; //hex

	  public static int BaudRate = 9600;
	private static SerialPort mSerialPort;//
//	protected OutputStream mOutputStream;
	private static InputStream mInputStream;
	private static ReadThread mReadThread;
	public static int LF = 1004;
	private class ReadThread extends Thread {
		int size;
		int available;
		byte[] buffer;
		byte[] respBytes;
		byte[] idBytes = new byte[4];
		@Override
		public void run() {
			super.run();
			while(runFlag) {
				buffer = new byte[128];
				if (startFlag) {
					if (mInputStream == null) return;
//					//Log.e(Port+":"+Power, "isStart");
					respBytes = read();
					if(respBytes != null){
						String id_hex = handleData2hex(respBytes);
						String id_d = handleData(respBytes);
						if(id_hex != null && checkByte(respBytes)){
							if (Hex) {
								sendMSG(id_hex);
							}else {
								sendMSG(id_d);
							}
						}
						}
						try {
							Thread.sleep(10);
						} catch (InterruptedException e) {
							e.printStackTrace();
						}
				}
				
//				}
			}
		}


		private void sendMSG(String id_d) {
			// TODO Auto-generated method stub
			Bundle bundle = new Bundle();
			bundle.putString("data", id_d);
			Message msg = new Message();
			msg.what = 	LF;
			msg.setData(bundle);
			handler.sendMessage(msg);
		}
	}
	private String handleData2hex(byte[] data){
		byte[] idBytesASC = new byte[10];
		byte[] idBytes = new byte[5];
		if(data == null){
			return null;
		}
		//��ͷ����
		if(data[0] != 0x02){
			return null;
		}
		if(data.length > 10){
			System.arraycopy(data, 1, idBytesASC, 0, 10);
			try {
				String id = new String(idBytesASC,"ASC-II");
//				String id = new String(idBytes, Charset.forName("ASC-II"));
				return id;
			} catch (UnsupportedEncodingException e) {
				e.printStackTrace();
				return null;
			}
//			String id = Tools.Bytes2HexString(idBytes, idBytes.length);

		}
		return null;
	}
	private static String handleData(byte[] data){
		byte[] idBytes = new byte[6];
		if(data == null){
			return null;
		}
		//
		if(data[0] != 0x02){
			return null;
		}
		if(data.length > 10){
			//ASCII type id  
//			System.arraycopy(data, 1, idBytes, 0, 10);
//			String idAsc = new String(idBytes) ;
//			String id = Bytes2HexString(idBytes, idBytes.length) ;
//			return idAsc;
			//int type id
			System.arraycopy(data, 5, idBytes, 0, 6);
			String id = new String(idBytes);
			int idInt = Integer.parseInt(id, 16);
			id = "" + idInt;
			switch (id.length()) {
			case 9:
				id = "0"+id;
				break;
			case 8:
				id = "00"+id;
				break;
			case 7:
				id = "000"+id;
				break;
			case 6:
				id = "0000"+id;
				break;
			case 5:
				id = "00000"+id;
				break;
			default:
				break;
			}
			return id;
		}
		
		return null;
	}
	
	private static String handleData2d(byte[] data){
		byte[] idBytes = new byte[10];
		if(data == null){
			return null;
		}
		//data packager head error
		if(data[0] != 0x02){
			return null;
		}
		if(data.length > 10){
			System.arraycopy(data, 1, idBytes, 0, 10);
				String id;
				try {
					id = new String(idBytes,"ASC-II");
//					int idInt = Integer.parseInt(id, 16);
//					id = "" + idInt;
					return id;
				} catch (UnsupportedEncodingException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
		}
		return null;
	}
	private static byte[] read(){
		int count;
		int size;
		int allCount = 0;
		byte[] buffer = new byte[128];
		byte[] bytes = new byte[64];
			try {
//				while(true){
					count = mInputStream.available();
					if(count > 0){
						//Log.e("ReadThread", ""+count);
						Thread.sleep(10);
						int dataSize = mInputStream.available();
						byte[] resp = new byte[dataSize];
						mInputStream.read(resp);
						//Log.e("MainActivity ReadThread", Tools.Bytes2HexString(resp, resp.length));
						if(dataSize > 3){
							return resp;
						}
					}
					Thread.sleep(10);
//				}
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		
		return null;
	}
	private static boolean checkByte(byte[] bs){
		byte[] idBytes = new byte[10];
			System.arraycopy(bs, 1, idBytes, 0, 10);
		byte[] bytes = {(byte)0x30,(byte)0x31,(byte)0x32,(byte)0x33,(byte)0x34,
				(byte)0x35,(byte)0x36,(byte)0x37,(byte)0x38,(byte)0x39,(byte)0x40,
				(byte)0x41,(byte)0x42,(byte)0x43,(byte)0x44,(byte)0x45,(byte)0x46};
		//Log.e("idb", Tools.Bytes2HexString(idBytes, idBytes.length));
		for (byte b :idBytes) {
			if (!bsContainB(b, bytes)) {
				return false;
			}
		}
		return true;
	}
	private static boolean bsContainB(byte b,byte[] bs){
		for (int i = 0; i < bs.length; i++) {
			if (b == bs[i]) {
				return true;
			}
		}
		return false;
	}
}
