package application.editor.stages;

import application.editor.FlowCellEditor;
import com.mxgraph.model.mxCell;
import com.mxgraph.model.mxIGraphModel;
import com.mxgraph.swing.mxGraphComponent;
import com.mxgraph.util.mxConstants;
import com.mxgraph.util.mxUtils;
import models.algebra.Expression;
import models.dataFlowModel.DataTransferChannel;
import models.dataFlowModel.DataTransferModel;
import models.visualModel.FormulaChannel;
import parser.Parser;
import parser.exceptions.ExpectedColon;
import parser.exceptions.ExpectedDoubleQuotation;
import parser.exceptions.ExpectedRightBracket;
import parser.exceptions.WrongJsonExpression;

import javax.swing.*;
import java.awt.*;
import java.util.EventObject;

public class DataFlowCellEditor extends FlowCellEditor {

    public DataFlowCellEditor(DataFlowModelingStage stage, mxGraphComponent graphComponent) {
        super(stage, graphComponent);
    }

    @Override
    public void startEditing(Object cellObj, EventObject eventObj) {
        if (editingCell != null) {
            stopEditing(true);
        }
        if (graphComponent.getGraph().getModel().isEdge(cellObj)) {
            return;
        }
        DataTransferModel model = stage.getModel();
        DataTransferChannel ch = (DataTransferChannel) model.getChannel((String) ((mxCell) cellObj).getValue());
        if (ch == null) {
            ch = (DataTransferChannel) model.getInputChannel((String) ((mxCell) cellObj).getValue());
            if (ch == null) {
                // selected cell is a resource
                return;
            }
        }
        JPanel panel = new JPanel();
        if (ch instanceof FormulaChannel) {
            JLabel label1 = new JLabel("Formula: ");
            JLabel label2 = new JLabel("Source: ");
            GridBagLayout layout = new GridBagLayout();
            panel.setLayout(layout);
            GridBagConstraints gbc = new GridBagConstraints();

            gbc.gridx = 0;
            gbc.gridy = 0;
            layout.setConstraints(label1, gbc);
            panel.add(label1);

            gbc.gridx = 1;
            gbc.gridy = 0;
            JTextField formulaText = new JTextField(((FormulaChannel) ch).getFormula(), 15);
            layout.setConstraints(formulaText, gbc);
            panel.add(formulaText);

            gbc.gridx = 0;
            gbc.gridy = 1;
            layout.setConstraints(label2, gbc);
            panel.add(label2);

            gbc.gridx = 1;
            gbc.gridy = 1;
            JTextArea textArea = new JTextArea(ch.getSourceText(), 7, 15);
            textArea.setEditable(false);
            layout.setConstraints(textArea, gbc);
            panel.add(textArea);

            int option = JOptionPane.showConfirmDialog(null, panel, "Edit Formula Channel", JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE);
            if (option == JOptionPane.OK_OPTION) {
                Parser.TokenStream stream = new Parser.TokenStream();
                Parser parser = new Parser(stream);

                String formula = formulaText.getText();
                stream.addLine(formula.split(Parser.EQUALS)[1]);

                try {
                    Expression exp = parser.parseTerm(stream, stage.getModel());
                    ((FormulaChannel) ch).setFormula(formula);
                    ((FormulaChannel) ch).setFormulaTerm(exp);
                } catch (ExpectedRightBracket | WrongJsonExpression | ExpectedColon | ExpectedDoubleQuotation e) {
                    e.printStackTrace();
                }
            }
        } else {
            JTextArea textArea = new JTextArea(ch.getSourceText(), 10, 20);
            panel.add(textArea);

            int option = JOptionPane.showConfirmDialog(null, panel, "Channel Code", JOptionPane.OK_CANCEL_OPTION);
            if (option == JOptionPane.OK_OPTION) {
                ((DataFlowModelingStage) stage).setChannelCode(ch, textArea.getText());
            }
        }
    }

    @Override
    public void stopEditing(boolean cancel) {
    }
}
