package cilico.tools.barcode;

import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;

import java.io.IOException;
import java.util.regex.Pattern;

import cn.net.cpzslibs.label.LabelUtils;
import cn.net.handsetlib.utils.ReadDeviceIDUtil;

public class Scanner {
	private static String TAG = "echoScanner";
	/**
	 * Tab建作为分隔符，商城模式的商铺id
	 */
	public static String splitStr = "	";
	/**
	 * 是设置设备id的界面
	 */
	public static boolean isDeviceId = false;
	public static boolean isForTestData = false;//读取的数据不做任何处理，直接返回
	/**
	 * 扫描内容
	 */
	static public final int BARCODE_READ = 10;
	/**
	 * 未扫描到内容
	 */
	static public final int BARCODE_NOREAD = 12;
	/**
	 * 扫描非16位追溯码
	 */
	static public final int BARCODE_ERR_LABEL = 13;
	/**
	 * 扫描设备id错误
	 */
	static public final int BARCODE_ERR_DeviceID = 14;

	static Boolean m_bASYC = false;
	static int m_nCommand = 0;
	static public Handler m_handler = null;

	/**
	 * 同步扫描一维/二维码，扫描不到将等待一段时间，摩托罗拉的扫描头等待最长3秒，
	 * 自主研发扫描头最长等待10秒，自动识别是自主研发扫描头还是摩托罗拉的扫描头
	 * 
	 * @return ：返回扫描到的条码，如果没扫到将为空字符串
	 */
	static public native String ReadSCAAuto();

	/**
	 * 同步扫描一维/二维码，扫描不到将等待一段时间，摩托罗拉的扫描头等待最长3秒， 自主研发扫描头最长等待10秒
	 * 
	 * @param nCode
	 *            ：扫描头标示，自主研发扫描头0x55,摩托罗拉扫描头0x00
	 * @return ：返回扫描到的条码，如果没扫到将为空字符串
	 */
	static public native String ReadSCA(int nCode);

	/**
	 * 同步扫描一维/二维码，扫描不到将等待一段时间，摩托罗拉的扫描头等待最长3秒， 自主研发扫描头最长等待10秒
	 * 
	 * @param nCommand
	 *            :扫描头标示，自主研发扫描头0x55,摩托罗拉扫描头0x00
	 * @param nCode
	 *            :条码的编码方式，GB2312为1,UTF为0
	 * @return ：返回扫描到的条码，如果没扫到将为空字符串
	 */
	static public native String ReadSCAEx(int nCommand, int nCode);

	/**
	 * 同步扫描一维/二维码，扫描不到将等待一段时间，摩托罗拉的扫描头等待最长3秒， 自主研发扫描头最长等待10秒
	 * 
	 * @param nCommand
	 *            :扫描头标示，自主研发扫描头0x55,摩托罗拉扫描头0x00
	 * @param buf
	 *            :存放条码内容，读回来后根据条码本身格式转成字符串
	 * @return ：返回扫描到的条码，如果没扫到将为空字符串
	 */
	static public native int ReadDataSCA(int nCommand, byte[] buf);

	/**
	 * 同步扫描一维/二维码，扫描不到将等待一段时间，摩托罗拉的扫描头等待最长3秒， 自主研发扫描头最长等待10秒
	 * 
	 * @param nCommand
	 *            :扫描头标示，自主研发扫描头0x55,摩托罗拉扫描头0x00
	 * @return :返回扫描到的条码内容
	 */
	static public native byte[] ReadData(int nCommand);

	/**
	 * 初始化设备
	 * 
	 * @return ：成功返回0
	 */
	static public native int InitSCA();

	/**
	 * 异步扫描，调用该函数会创建一个扫描线程去扫描， 扫描到条码或者扫描超时都会通过handle发送消息给接受者，
	 * 所以使用异步扫描的话必须在你的接收代码里创建个handle, 并把handle赋给m_handler，扫描到条码发送Message
	 * BARCODE_READ， 超时发送Message BARCODE_NOREAD
	 */
	static public void Read() {
//		Log.e("echo", "m_bASYC:" + m_bASYC);
		if (m_bASYC) {
			return;
		} else {
			// m_nCommand=nCode;
			StartASYC();
		}
	}

	/**
	 * 扫描线程
	 */
	static void StartASYC() {
		m_bASYC = true;
		Thread thread = new Thread(new Runnable() {
			public void run() {

				if (m_handler != null) {
					// ----------------------add by echo at 2016-10-9
					// 15:05:19------用于有些扫描头读取慢，读取数据不全的问题------------------------------------------------------------------------------------
					/*
					 * try { Thread.sleep(100); } catch (InterruptedException e)
					 * { // TODO Auto-generated catch block e.printStackTrace();
					 * }
					 */
					// ----------------------add by echo at 2016-10-9
					// 15:05:19------------------------------------------------------------------------------------------
//					--------------------测试回车使用---------------------------------------------------------
//					StringBuffer sb = new StringBuffer();
//					boolean end = false;
//					while(!end){
//						String str1 = ReadSCAAuto().trim();
//						if (str1.endsWith("\n")) {
//							end = true;
//						}
//						sb.append(str1);
//					}
//					String str = sb.toString().trim();
//					--------------------测试回车使用---------------------------------------------------------
					
					String str = ReadSCAAuto().trim();
					Message msg = new Message();
					msg.what = str.length() > 0 ? BARCODE_READ : BARCODE_NOREAD;
					Log.d(TAG, "StartASYC  ReadSCAAuto: 读取数据完成" + str);
					/*if (str.endsWith("\n")) {
						Log.i("Scanner", "换行符");
					}*/
					if (str.length() <= 0) {
						m_handler.sendMessage(msg);
						m_bASYC = false;
						return;
					}
					
					//------------------------------------测试使用---------------------------------
					//读取的数据不做任何处理，直接返回
					if (isForTestData) {
						m_bASYC = false;
						msg.obj = str;
						m_handler.sendMessage(msg);
						return;
					}
					
					str = LabelUtils.getLabelSplits(str);
					if (isNumber(str)) {
						// 这里要判断扫描的是否为数字
						if (LabelUtils.checkLabelLength(str)) {// 简单验证追溯码的合法性
							msg.obj = str;
						} else {
							msg.what = BARCODE_ERR_LABEL;
							msg.obj = str;
						}
					} else {
						if (isDeviceId) {
							String deviceId = ReadDeviceIDUtil.readScanDecrypt(str);
							if (isNumber(deviceId) || deviceId.contains(splitStr)) {
								// 是设备id加密文件||商城模式,tab前为设备id，后为产品id
								msg.obj = str;
							} else {
								msg.what = BARCODE_ERR_DeviceID;
								msg.obj = "扫描设备id错误";
							}
						} else {
							msg.what = BARCODE_ERR_LABEL;
							msg.obj = str;
						}
					}
					m_handler.sendMessage(msg);
				}
				m_bASYC = false;
			}
		});
		thread.start();
	}

	/**
	 * 虚拟键盘消息，可以把String按键盘消息方式发送给系统
	 * 
	 * @param str
	 *            ：要发送的字符串
	 */
	static public void SendString(String str) {
		try {
			Runtime.getRuntime().exec("input keyevent 66");
			Runtime.getRuntime().exec("input text " + str);

		} catch (IOException e) {
			// Auto-generated catch block
			e.printStackTrace();
			Log.i("run", e.toString());
		}
	}

	static private void showToast(String str) {
		Toast.makeText(null, str, Toast.LENGTH_SHORT).show();
	}

	static {
		// System.loadLibrary("Cilico-Scan");
//		System.loadLibrary("tiny-tools");
	}

	/**
	 * 
	 * 发送内容<br/>
	 * 2015-1-29下午12:59:34
	 * 
	 * @param m_handler
	 * @param scanContent
	 *            扫描到的内容
	 */
	public static void sendHandler(String scanContent) {
		if (m_handler != null) {
			Message msg = new Message();
			msg.what = scanContent.length() > 0 ? BARCODE_READ : BARCODE_NOREAD;
			// --------------修改扫码相关-------------------------------------------------
			Log.d(TAG, "sendHandler:" + scanContent);
			if (isDeviceId) {
				msg.what = BARCODE_READ;
				msg.obj = scanContent;
				m_handler.sendMessage(msg);
				return;
			}
			scanContent = LabelUtils.getLabelSplits(scanContent);

			if (isNumber(scanContent)) {
				// 这里要判断扫描的是否为数字
				if (scanContent.length() >= 16) {// 简单验证追溯码的合法性
					msg.obj = scanContent;
				} else if (scanContent.length() > 0) {
					msg.what = BARCODE_ERR_LABEL;
					msg.obj = scanContent;
				}
			} else {
				String deviceId = ReadDeviceIDUtil.readScanDecrypt(scanContent).trim();
				if (isDeviceId) {
					if (isNumber(deviceId) || deviceId.contains(splitStr)) {
						// 是设备id加密文件||//商城模式,tab前为设备id，后为产品id
						msg.obj = scanContent;
					} else {
						msg.what = BARCODE_ERR_DeviceID;
						msg.obj = "扫描设备id错误";
					}
				} else {
					msg.what = BARCODE_ERR_LABEL;
					msg.obj = scanContent;
				}
			}
			m_handler.sendMessage(msg);

		}
	}

	/**
	 * 判断是不是数字 2014-5-28下午1:56:22
	 * 
	 * @param str
	 * @return
	 */
	public static boolean isNumber(String str) {
		return Pattern.compile("^\\d*$").matcher(str).matches();
	}
}
