package com.its.pis.ui;

import com.intellij.uiDesigner.core.GridConstraints;
import com.intellij.uiDesigner.core.GridLayoutManager;
import com.intellij.uiDesigner.core.Spacer;
import com.its.pis.domain.NET;
import com.its.pis.entity.TbVdsCtlr;
import com.its.pis.service.VdsCtlrService;
import com.sun.management.OperatingSystemMXBean;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

import javax.swing.*;
import javax.swing.plaf.FontUIResource;
import javax.swing.text.StyleContext;
import java.awt.*;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.lang.management.ManagementFactory;
import java.util.Locale;

@Slf4j
@Getter
public abstract class SubUI {
    private VdsCtlrService vdsCtlrService = null;
    OperatingSystemMXBean osBean = null;
    private TbVdsCtlr selObj = null;

    private JPanel rootPanel;
    private JPanel pnlCtlr;
    private JPanel pnlLog;
    private JPanel pnlLogTitle;
    private JPanel pnlCtlrTitlex;
    private JButton btnLogDirOpen;
    private JButton btnLogPause;
    private JCheckBox chkLogPause;
    private JTextArea taLog;
    private JButton btnLogCopy;
    private JPanel pnlControl;
    private JButton btnImage;
    private JButton btnInitialize;
    private JButton btnReset;
    private JButton btnDisconnect;
    private JTextField txtName;
    private JTextField txtId;
    private JTextField textField1;
    private JTextField textField2;

    protected abstract void actionButtonClicked();

    public SubUI() {
        System.setProperty("awt.useSystemAAFontSettings", "false"); // AntiAliasing false

        osBean = ManagementFactory.getPlatformMXBean(OperatingSystemMXBean.class);
        try {
            Font font = Font.createFont(Font.TRUETYPE_FONT, new File("fonts/D2Coding.ttc"));
            GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
            ge.registerFont(font);
        } catch (FontFormatException e) {
        } catch (IOException e) {
        }

        //taLog.setFont(new Font(Font.MONOSPACED, Font.PLAIN, 14));
        Font d2font = new Font("D2Coding", Font.PLAIN, 14);
        if (d2font != null) {
            taLog.setFont(d2font);
        }
        taLog.setText(null);

        chkLogPause.setFocusable(false);
        btnLogPause.setFocusable(false);
        btnLogDirOpen.setFocusable(false);
        btnLogCopy.setFocusable(false);

        btnLogPause.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                taLog.setText(null);
            }
        });
        btnLogDirOpen.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                Runtime rt = Runtime.getRuntime();
                try {
                    rt.exec("explorer.exe logs");
                } catch (IOException ex) {
                    throw new RuntimeException(ex);
                }
            }
        });
        chkLogPause.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                JTextAreaOutputStream.isLoggingPause = chkLogPause.isSelected();
            }
        });
        btnLogCopy.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                StringSelection stringSelection = new StringSelection(taLog.getText());
                Clipboard clpBrd = Toolkit.getDefaultToolkit().getSystemClipboard();
                clpBrd.setContents(stringSelection, null);
            }
        });

        btnDisconnect.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                controlController(1);
            }
        });
        btnReset.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                controlController(2);
            }
        });
        btnInitialize.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                controlController(3);
            }
        });
        btnImage.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                controlController(4);
            }
        });
    }

    public void updateInfo(TbVdsCtlr selObj) {
        this.selObj = selObj;
        txtId.setText("");
        txtName.setText("");
        if (selObj != null) {
            txtId.setText(selObj.getVDS_CTLR_ID());
            txtName.setText(selObj.getVDS_NM());
        }
    }

    /**
     * 제어기 명령 처리
     *
     * @param type
     */
    public void controlController(int type) {
        if (selObj == null) {
            JOptionPane.showMessageDialog(getRootPanel(), "제어기가 선택되지 않았습니다. 목록을 더블클릭하여 제어기를 선택하세요.", "제어기 선택", JOptionPane.ERROR_MESSAGE);
            return;
        }
        if (selObj.getNetState() == NET.CLOSED) {
            JOptionPane.showMessageDialog(getRootPanel(), "제어기가 현재 연결이 되어 있지 않습니다.", "제어기 연결 상태", JOptionPane.ERROR_MESSAGE);
            return;
        }
        String message, title;
        switch (type) {
            case 1:
                message = "제어기와의 연결을 종료 하시겠습니까?";
                title = "제어기 연결 종료";
                break;
            case 2:
                message = "제어기를 리셋 하시겠습니까?";
                title = "제어기 리셋";
                break;
            case 3:
                message = "제어기를 초기화 하시겠습니까?";
                title = "제어기 초기화";
                break;
            case 4:
                message = "제어기의 정지영상 정보를 요청하시겠습니까?";
                title = "제어기 정지영상 요청";
                break;
            default:
                return;
        }
        if (JOptionPane.showConfirmDialog(getRootPanel(), message, title, JOptionPane.YES_NO_OPTION) != 0) {
            return;
        }

        boolean result = false;
        switch (type) {
            case 1:
                result = selObj.channelClose();
                break;
            case 2:
                result = selObj.reset();
                break;
            case 3:
                result = selObj.initialize();
                break;
            case 4:
                result = selObj.stopImage((byte) 0x01);
                break;
            default:
                return;
        }
        if (!result) {
            JOptionPane.showMessageDialog(getRootPanel(), "명령 전송이 실패 하였습니다.", title, JOptionPane.ERROR_MESSAGE);
        }
    }

    {
// GUI initializer generated by IntelliJ IDEA GUI Designer
// >>> IMPORTANT!! <<<
// DO NOT EDIT OR ADD ANY CODE HERE!
        $$$setupUI$$$();
    }

    /**
     * Method generated by IntelliJ IDEA GUI Designer
     * >>> IMPORTANT!! <<<
     * DO NOT edit this method OR call it in your code!
     *
     * @noinspection ALL
     */
    private void $$$setupUI$$$() {
        rootPanel = new JPanel();
        rootPanel.setLayout(new GridLayoutManager(2, 1, new Insets(0, 0, 0, 0), -1, -1));
        pnlCtlr = new JPanel();
        pnlCtlr.setLayout(new GridLayoutManager(2, 2, new Insets(10, 4, 0, 4), -1, -1));
        rootPanel.add(pnlCtlr, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        pnlCtlrTitlex = new JPanel();
        pnlCtlrTitlex.setLayout(new GridLayoutManager(1, 2, new Insets(0, 0, 0, 2), -1, -1));
        pnlCtlr.add(pnlCtlrTitlex, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_FIXED, 1, null, null, null, 0, false));
        final JLabel label1 = new JLabel();
        Font label1Font = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, label1.getFont());
        if (label1Font != null) label1.setFont(label1Font);
        label1.setHorizontalAlignment(2);
        label1.setHorizontalTextPosition(11);
        label1.setIcon(new ImageIcon(getClass().getResource("/static/image/controller.png")));
        label1.setText("제어기 정보");
        pnlCtlrTitlex.add(label1, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        final Spacer spacer1 = new Spacer();
        pnlCtlrTitlex.add(spacer1, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
        pnlControl = new JPanel();
        pnlControl.setLayout(new GridLayoutManager(4, 2, new Insets(0, 0, 0, 2), 1, 1));
        pnlCtlr.add(pnlControl, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        btnDisconnect = new JButton();
        Font btnDisconnectFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, btnDisconnect.getFont());
        if (btnDisconnectFont != null) btnDisconnect.setFont(btnDisconnectFont);
        btnDisconnect.setText("연결끊기");
        pnlControl.add(btnDisconnect, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        final JPanel panel1 = new JPanel();
        panel1.setLayout(new GridLayoutManager(4, 2, new Insets(0, 0, 0, 0), -1, -1));
        pnlControl.add(panel1, new GridConstraints(0, 0, 4, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        txtId = new JTextField();
        txtId.setEditable(false);
        Font txtIdFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, txtId.getFont());
        if (txtIdFont != null) txtId.setFont(txtIdFont);
        txtId.setHorizontalAlignment(0);
        txtId.setText("ID");
        panel1.add(txtId, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(100, -1), new Dimension(100, -1), new Dimension(100, -1), 0, false));
        txtName = new JTextField();
        txtName.setEditable(false);
        Font txtNameFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, txtName.getFont());
        if (txtNameFont != null) txtName.setFont(txtNameFont);
        txtName.setHorizontalAlignment(2);
        txtName.setText("제어기 명칭");
        panel1.add(txtName, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(200, -1), null, 0, false));
        final JLabel label2 = new JLabel();
        label2.setText("ㅣ관리번호");
        panel1.add(label2, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        textField1 = new JTextField();
        panel1.add(textField1, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false));
        textField2 = new JTextField();
        panel1.add(textField2, new GridConstraints(3, 1, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0, false));
        btnReset = new JButton();
        Font btnResetFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, btnReset.getFont());
        if (btnResetFont != null) btnReset.setFont(btnResetFont);
        btnReset.setText("리셋");
        pnlControl.add(btnReset, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        btnInitialize = new JButton();
        Font btnInitializeFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, btnInitialize.getFont());
        if (btnInitializeFont != null) btnInitialize.setFont(btnInitializeFont);
        btnInitialize.setText("초기화");
        pnlControl.add(btnInitialize, new GridConstraints(3, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        btnImage = new JButton();
        Font btnImageFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, btnImage.getFont());
        if (btnImageFont != null) btnImage.setFont(btnImageFont);
        btnImage.setText("정지영상");
        pnlControl.add(btnImage, new GridConstraints(2, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        final JPanel panel2 = new JPanel();
        panel2.setLayout(new GridLayoutManager(1, 1, new Insets(0, 0, 0, 0), -1, -1));
        pnlCtlr.add(panel2, new GridConstraints(1, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        pnlLog = new JPanel();
        pnlLog.setLayout(new GridLayoutManager(2, 1, new Insets(0, 4, 0, 4), -1, -1));
        rootPanel.add(pnlLog, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        pnlLogTitle = new JPanel();
        pnlLogTitle.setLayout(new GridLayoutManager(1, 6, new Insets(0, 0, 0, 2), 1, 1));
        pnlLog.add(pnlLogTitle, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0, false));
        final JLabel label3 = new JLabel();
        Font label3Font = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, label3.getFont());
        if (label3Font != null) label3.setFont(label3Font);
        label3.setHorizontalAlignment(2);
        label3.setIcon(new ImageIcon(getClass().getResource("/static/image/logging.png")));
        label3.setText("제어기 로그");
        pnlLogTitle.add(label3, new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        final Spacer spacer2 = new Spacer();
        pnlLogTitle.add(spacer2, new GridConstraints(0, 1, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_HORIZONTAL, GridConstraints.SIZEPOLICY_WANT_GROW, 1, null, null, null, 0, false));
        btnLogDirOpen = new JButton();
        Font btnLogDirOpenFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, btnLogDirOpen.getFont());
        if (btnLogDirOpenFont != null) btnLogDirOpen.setFont(btnLogDirOpenFont);
        btnLogDirOpen.setHorizontalTextPosition(0);
        btnLogDirOpen.setText("로그 폴더");
        pnlLogTitle.add(btnLogDirOpen, new GridConstraints(0, 5, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        btnLogPause = new JButton();
        Font btnLogPauseFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, btnLogPause.getFont());
        if (btnLogPauseFont != null) btnLogPause.setFont(btnLogPauseFont);
        btnLogPause.setHorizontalTextPosition(0);
        btnLogPause.setText("지우기");
        pnlLogTitle.add(btnLogPause, new GridConstraints(0, 3, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        chkLogPause = new JCheckBox();
        Font chkLogPauseFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, chkLogPause.getFont());
        if (chkLogPauseFont != null) chkLogPause.setFont(chkLogPauseFont);
        chkLogPause.setHorizontalAlignment(0);
        chkLogPause.setHorizontalTextPosition(11);
        chkLogPause.setText("멈춤");
        pnlLogTitle.add(chkLogPause, new GridConstraints(0, 2, 1, 1, GridConstraints.ANCHOR_WEST, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        btnLogCopy = new JButton();
        Font btnLogCopyFont = this.$$$getFont$$$("Malgun Gothic", Font.PLAIN, 12, btnLogCopy.getFont());
        if (btnLogCopyFont != null) btnLogCopy.setFont(btnLogCopyFont);
        btnLogCopy.setText("복사");
        pnlLogTitle.add(btnLogCopy, new GridConstraints(0, 4, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_NONE, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0, false));
        final JScrollPane scrollPane1 = new JScrollPane();
        Font scrollPane1Font = this.$$$getFont$$$("D2Coding", Font.PLAIN, 12, scrollPane1.getFont());
        if (scrollPane1Font != null) scrollPane1.setFont(scrollPane1Font);
        pnlLog.add(scrollPane1, new GridConstraints(1, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0, false));
        taLog = new JTextArea();
        taLog.setBackground(new Color(-16777216));
        taLog.setCaretColor(new Color(-1));
        taLog.setEditable(false);
        Font taLogFont = this.$$$getFont$$$("D2Coding", Font.PLAIN, 14, taLog.getFont());
        if (taLogFont != null) taLog.setFont(taLogFont);
        taLog.setForeground(new Color(-1));
        taLog.setMargin(new Insets(4, 4, 4, 4));
        taLog.setText("[10:50:08.561] [ INFO] ************************************************************************************\n[10:50:08.561] [ INFO] **                   Center Communication Server Information                      **\n[10:50:08.561] [ INFO] **     bindAddress: 0.0.0.0\n[10:50:08.561] [ INFO] **      listenPort: 9901\n[10:50:08.561] [ INFO] **         backlog: 1024\n[10:50:08.561] [ INFO] **   acceptThreads: 16\n[10:50:08.561] [ INFO] **   workerThreads: 16\n[10:50:08.561] [ INFO] ************************************************************************************\n");
        scrollPane1.setViewportView(taLog);
    }

    /**
     * @noinspection ALL
     */
    private Font $$$getFont$$$(String fontName, int style, int size, Font currentFont) {
        if (currentFont == null) return null;
        String resultName;
        if (fontName == null) {
            resultName = currentFont.getName();
        } else {
            Font testFont = new Font(fontName, Font.PLAIN, 10);
            if (testFont.canDisplay('a') && testFont.canDisplay('1')) {
                resultName = fontName;
            } else {
                resultName = currentFont.getName();
            }
        }
        Font font = new Font(resultName, style >= 0 ? style : currentFont.getStyle(), size >= 0 ? size : currentFont.getSize());
        boolean isMac = System.getProperty("os.name", "").toLowerCase(Locale.ENGLISH).startsWith("mac");
        Font fontWithFallback = isMac ? new Font(font.getFamily(), font.getStyle(), font.getSize()) : new StyleContext().getFont(font.getFamily(), font.getStyle(), font.getSize());
        return fontWithFallback instanceof FontUIResource ? fontWithFallback : new FontUIResource(fontWithFallback);
    }

    /**
     * @noinspection ALL
     */
    public JComponent $$$getRootComponent$$$() {
        return rootPanel;
    }

}
