package co.dc.aptiv;

import co.dc.aptiv.mina.CollectorMina;
import co.dc.aptiv.mina.ComMinaA;
import co.dc.aptiv.mina.PLCMina;
import co.dc.aptiv.mina.TestMachineCollectorMina;
import co.dc.aptiv.pojo.BillPojo;
import co.dc.aptiv.pojo.MaterielPojo;
import co.dc.aptiv.pojo.UserPojo;
import co.dc.aptiv.service.*;
import co.dc.aptiv.utils.CharacterConversionUtil;
import co.dc.aptiv.utils.KeyboardUtil;
import co.dc.aptiv.utils.ResetJButton;
import co.dc.aptiv.utils.WindowUtil;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.FontUIResource;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.RandomAccessFile;
import java.net.UnknownHostException;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.Arrays;
import java.util.Enumeration;

/**
 * @describe: 主程序
 * @author: liuxinglong
 * @version: 2018/4/17 15:21
 */
public class AptivApp {
    public static UserPojo session = null;

    private static final Log log = LogFactory.getLog(AptivApp.class);
    private JFrame frmv;
    private JPanel contentPane;
    private JTextField textField;
    private JTextField textField_1;
    private JLabel lblNewLabel;
    public static QueryRunner queryRunner;
    public static UserService userService;
    public static BillService billService;
    public static BillDetailService billDetailService;
    public static PropertiesConfiguration configuration;
    public static MaterielService materielService;
    public static QrCodeService qrcodeService;
    public static WindowUtil windowUtil;
    /**
     * plc
     */
    public static PLCMina plcMina;
    /**
     * 采集器
     */
    public static CollectorMina collectorMina;
    /**
     * 激光机
     */
    public static ComMinaA printMina;
    /**
     * 测试机
     */
    public static TestMachineCollectorMina testMachineCollectorMina;

    public static String loginToken = null;

    /**
     * 物料信息
     */
    public static MaterielPojo nowMaterielPojo;
    /**
     * 当前打印状态 false 停止 true 开始
     */
    public static boolean flag = false;
    /**
     * 单据Id
     */
    public static BillPojo billPojo;
    /**
     * 生成的二维码
     */
    public static String qrCode;
    /**
     * 激光机是否可打印
     */
//    public static boolean printStatus = true;
    /**
     * 采集器是否可采集
     */
//    public static boolean scanStatus = false;
    /**
     * 字符转换工具类
     */
    public static CharacterConversionUtil ccu = new CharacterConversionUtil();

    /**
     * 程序入口
     */
    public static void main(String[] args) {
        //检查文件锁--用于限制程序多开
        try {
            boolean runFlag = isRunning("德尔福激光工控V1.2.exe");
            log.info("is running " + runFlag);
            if (runFlag) {
                JOptionPane.showMessageDialog(null, "程序已打开，不可多开。", "提示", JOptionPane.ERROR_MESSAGE);
                //退出程序
                System.exit(0);
            }
        } catch (Exception e) {
            log.error("检查文件锁异常。", e);
        }

        //新建进度条对象
        JWindowLoding jWindowLoding = new JWindowLoding(500, 300, Color.white, Color.green, 100, 200, 300, 15);
        jWindowLoding.start();

        //操作配置文件
        String exePath = System.getProperty("exe.path");
        if (StringUtils.isEmpty(exePath)) {
            String path = AptivApp.class.getResource("/").getPath();
            exePath = path;
        }
        System.setProperty("exe.path", exePath + "config.properties");

        //进度条进度设定
        jWindowLoding.setProgress("正在初始化系统配置", 5);

        //加载各种bean
        ApplicationContext cxt = new ClassPathXmlApplicationContext("applicationContent.xml");
        //数据库管理
        queryRunner = (QueryRunner) cxt.getBean("queryRunner");
        //用户管理
        userService = (UserService) cxt.getBean("userService");
        //单据管理
        billService = (BillService) cxt.getBean("billService");
        //单据详情管理
        billDetailService = (BillDetailService) cxt.getBean("billDetailService");
        //PLC
        plcMina = (PLCMina) cxt.getBean("plcMina");
        //采集器
        collectorMina = (CollectorMina) cxt.getBean("collectorMina");
        //测试机设备管理
        testMachineCollectorMina = (TestMachineCollectorMina) cxt.getBean("testMachineCollectorMina");
        //配置管理
        configuration = (PropertiesConfiguration) cxt.getBean("configuration");
        //产品管理
        materielService = (MaterielService) cxt.getBean("materielService");
        //二维码
        qrcodeService = (QrCodeService) cxt.getBean("qrCodesService");
        windowUtil = (WindowUtil) cxt.getBean("windowUtil");

        jWindowLoding.setProgress("正在连接系统数据库", 10);
        //检查数据库连接
        boolean dbFlag = userService.checkDb();
        if (dbFlag == false) {
            jWindowLoding.setProgress("系统数据库连接失败", 30);
            JOptionPane.showMessageDialog(null, "系统数据库连接失败.", "提示", JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        }

        //检查PLC
        jWindowLoding.setProgress("正在连接PLC", 40);
        //tcp配置--检查设备
        plcMina.startConnection();
        if (plcMina.isConnect() == false) {
            plcMina.closeConnection();
            jWindowLoding.setProgress("PLC连接失败", 90);
            JOptionPane.showMessageDialog(null, "PLC连接失败.", "提示", JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        }

        //检查激光机
        jWindowLoding.setProgress("正在连接激光器", 50);
        //tcp配置--检查设备
        printMina = new ComMinaA(configuration.getString("com"), Integer.parseInt(configuration.getString("bot")));
        printMina.startConnection();
        if (printMina.isConnect() == false) {
            printMina.closeConnection();
            jWindowLoding.setProgress("激光器连接失败", 80);
            JOptionPane.showMessageDialog(null, "激光器连接失败.", "提示", JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        }

        //检查采集器
        jWindowLoding.setProgress("正在连接采集器", 70);
        //tcp配置--检查设备
        collectorMina.startConnection();
        if (collectorMina.isConnect() == false) {
            collectorMina.closeConnection();
            jWindowLoding.setProgress("采集器连接失败", 90);
            JOptionPane.showMessageDialog(null, "采集器连接失败.", "提示", JOptionPane.ERROR_MESSAGE);
            System.exit(0);
        }

        jWindowLoding.setProgress("初始化完成正在启动控制界面", 100);
        jWindowLoding.finish();

        //加载页面
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    AptivApp window = new AptivApp();
                    window.frmv.setVisible(true);
                } catch (Exception e) {
                    log.error("系统启动界面异常：", e);
                }
            }
        });

    }

    /**
     * Create the application.
     */
    public AptivApp() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    public void initialize() {
        //禁止使用本地默认窗口样式，便于下方设置圆角窗口
        //JFrame.setDefaultLookAndFeelDecorated(true);
        frmv = new JFrame();
        frmv.setUndecorated(true);
        frmv.setResizable(false);
        frmv.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //程序置顶
//		frmv.setAlwaysOnTop(!frmv.isAlwaysOnTop());

        /*
         * 统一所有子窗口设置字体样式
         */
        FontUIResource fontRes = new FontUIResource(new Font("微软雅黑", Font.PLAIN, 16));
        for (Enumeration<Object> keys = UIManager.getDefaults().keys(); keys.hasMoreElements(); ) {
            Object key = keys.nextElement();
            Object value = UIManager.get(key);
            if (value instanceof FontUIResource) {
                UIManager.put(key, fontRes);
            }
        }

        frmv.setBounds(100, 100, 420, 460);
        frmv.setLocationRelativeTo(null);

        contentPane = new JPanel() {
            @Override
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                //登陆背景
                Image image = new ImageIcon(MainFrame.class.getResource("img/loginbg.png")).getImage();
                g.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), this);
            }
        };
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setBackground(Color.white);
        frmv.setContentPane(contentPane);
        contentPane.setLayout(null);

        /*
         * 关闭按钮
         */
        JButton jButton = new ResetJButton("/co/dc/aptiv/img/close.png", "/co/dc/aptiv/img/close.png", "/co/dc/aptiv/img/close.png");
        jButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                System.exit(0);
            }
        });
        jButton.setBounds(368, 0, 52, 52);
        contentPane.add(jButton);

        /*
         * 用户名框
         */
        textField = new JTextField();
        KeyboardUtil kk2 = KeyboardUtil.getInstance();
        kk2.register(textField);
        textField.setBorder(new EmptyBorder(0, 0, 0, 0));
        textField.setBounds(120, 185, 220, 40);
        contentPane.add(textField);
        textField.setColumns(10);

        //加载最近一次登录的用户名
        String lastname = configuration.getString("lastname", "");
        if (StringUtils.isNotEmpty(lastname)) {
            textField.setText(lastname);
        }

        /*
         * 密码框
         */
        textField_1 = new JPasswordField();
        KeyboardUtil kk = KeyboardUtil.getInstance();
        kk.register(textField_1, true);
        textField_1.setBorder(new EmptyBorder(0, 0, 0, 0));
        textField_1.setColumns(10);
        textField_1.setBounds(120, 240, 220, 40);
        contentPane.add(textField_1);
        textField_1.addKeyListener(new KeyListener() {
            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                    //保存登录名
                    try {
                        AptivApp.configuration.setProperty("lastname", textField.getText());
                        AptivApp.configuration.save();
                    } catch (ConfigurationException ee) {
                        log.equals("保存登录名称异常" + ee);
                    }
                    //执行登陆
                    UserPojo _user = userService.checklogin(textField.getText(), textField_1.getText());
                    if (_user != null) {
                        lblNewLabel.setText("");
                        configuration.setProperty("lastname", textField.getText());
                        AptivApp.session = _user;
                        //进入下一个界面
                        new MainFrame().setVisible(true);
                        frmv.dispose();
                    } else {
                        //提示有误，重新登录
                        lblNewLabel.setText("登录名或密码有误，请重新登录.");
                    }
                }
            }

            public void keyReleased(KeyEvent e) {
            }

            public void keyTyped(KeyEvent e) {
            }
        });

        /*
         * 登录按钮
         */
        JButton button = new ResetJButton("/co/dc/aptiv/img/btn.png", "/co/dc/aptiv/img/btn-h.png", "/co/dc/aptiv/img/btn-h.png");
        button.addActionListener(new ActionListener() {
            //点击执行登陆操作
            public void actionPerformed(ActionEvent arg0) {
                //保存登录名
                try {
                    AptivApp.configuration.setProperty("lastname", textField.getText());
                    AptivApp.configuration.save();
                } catch (ConfigurationException e) {
                    log.equals("保存登录名称异常" + e);
                }
                //执行登陆
                UserPojo _user = userService.checklogin(textField.getText(), textField_1.getText());
                if (_user != null) {
                    lblNewLabel.setText("");
                    configuration.setProperty("lastname", textField.getText());
                    //进入下一个界面
                    new MainFrame().setVisible(true);
                    AptivApp.session = _user;
                    frmv.dispose();
                } else {
                    //提示有误，重新登录
                    lblNewLabel.setText("登录名或密码有误，请重新登录.");
                }
            }
        });
        button.setBounds(60, 346, 300, 50);
        contentPane.add(button);

        /*
         * 提示信息块
         */
        lblNewLabel = new JLabel("");
        lblNewLabel.setForeground(Color.RED);
        lblNewLabel.setBounds(95, 320, 248, 15);
        contentPane.add(lblNewLabel);
    }

    /**
     * 检查时候有文件锁
     *
     * @param singleId
     * @return
     * @throws UnknownHostException
     */
    public static boolean isUsing(int singleId) throws UnknownHostException {
        try {
            RandomAccessFile raf = null;
            FileChannel channel = null;
            FileLock lock = null;
            // 在临时文件夹创建一个临时文件，锁住这个文件用来保证应用程序只有一个实例被创建.
            File sf = new File(System.getProperty("java.io.tmpdir") + singleId + ".single");
            sf.deleteOnExit();
            sf.createNewFile();

            raf = new RandomAccessFile(sf, "rw");
            channel = raf.getChannel();
            lock = channel.tryLock();
            if (lock == null) {
                // 如果没有得到锁，则程序退出.
                // 没有必要手动释放锁和关闭流，当程序退出时，他们会被关闭的.
                return false;
            }
            return true;
        } catch (Exception e) {
            log.error("检查时候有文件锁--异常", e);
            return false;
        }
    }

    public static boolean isRunning(String processName) {
        BufferedReader bufferedReader = null;
        try {
            Process proc = Runtime.getRuntime().exec("tasklist /FI \"IMAGENAME eq " + processName + "\"");
            bufferedReader = new BufferedReader(new InputStreamReader(proc.getInputStream()));
            String line = null;
            int i = 0;
            while ((line = bufferedReader.readLine()) != null) {
                //判断是否存在
                if (line.contains(processName)) {
                    log.info("running info " + line);
                    i++;
                }
            }
            if (i > 1) {
                return true;
            }
            return false;
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        } finally {
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (Exception ex) {
                }
            }
        }
    }

    public static String httpStr(String code) {
        if (code.indexOf("http") != -1) {
            int begin = code.indexOf("=");
            if (begin == -1) {
                begin = code.indexOf("?");
            }
            return code.substring(begin + 1, code.length());
        } else {
            return code;
        }

    }

    public void Test1() {
        CharacterConversionUtil ccu = new CharacterConversionUtil();

        System.out.println("abc 转成ascii码后结果为 " + Arrays.toString(ccu.String2ASCII("abc")));
        System.out.println("abc 转成十六进制 ascii码后结果为 " + ccu.String2HexString("abc"));
        System.out.println("[97, 98, 99] 转成字符串后结果为 " + ccu.ASCII2String(new int[]{97, 98, 99}));
        System.out.println("十六进制 ascii码 02 41 42 43 0D 0A 转成字符串后结果为 " + ccu.HexString2String("02 41 42 43 0D 0A"));

//        System.out.println(AptivApp.qrcodeService.getQrCode(1L));


        //退出程序
        System.exit(0);
    }


}
