/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * UseCaseEditor.java
 *
 * Created on May 1, 2010, 11:11:31 PM
 */
package uce.ui;

import dowser.Const;
import dowser.ui.ImagePanel;
import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import javax.swing.JFrame;
import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.CharStream;
import org.antlr.runtime.CommonTokenStream;
import org.antlr.runtime.NoViableAltException;
import org.antlr.runtime.RecognitionException;
import org.antlr.runtime.tree.CommonTree;
import uce.parser.CGLexer;
import uce.parser.CGParser;
import uce.parser.CGParser.statement_return;
import uce.parser.DynamicModelValidator;
import uce.parser.ExtendedRecognitionException;
import uce.parser.SequenceDiagramGenerator;
import uce.parser.UseCasePrinter;
import usecase.UseCase;
import usecase.UseCase.NormalCourse;

/**
 *
 * @author chepa
 */
public class UseCaseEditor extends javax.swing.JFrame {

	private HashMap<String, String[]> hsSuggestions;
	private int iUCCounter = 0;

	public static UseCaseEditor getInstance() {
		if (m_Instance == null) {
			m_Instance = new UseCaseEditor();
		}
		return m_Instance;
	}

	/** Creates new form UseCaseEditor */
	public UseCaseEditor() {
		initComponents();
		this.addWindowListener(new WindowAdapter() {

			@Override
			public void windowOpened(WindowEvent e) {
				setExtendedState(JFrame.MAXIMIZED_BOTH);
			}
		});

		hsSuggestions = new HashMap<String, String[]>();

		hsSuggestions.put("compUAP", new String[]{"DOMAIN ACTION", "end"});

		hsSuggestions.put("oP,v,0", new String[]{"DOMAIN CONCEPT", "DOMAIN SLOT", "every", "specific"});
		hsSuggestions.put("oP,v,1", new String[]{"of", "till", "for", "into", "from"});
		hsSuggestions.put("oP,v,2", new String[]{"DOMAIN CONCEPT", "every", "specific"});
		hsSuggestions.put("oP,v,3", new String[]{"by", "to", "till", "for", "into", "from"});
		hsSuggestions.put("oP,v,5", new String[]{"till", "for", "and", "or"});

		hsSuggestions.put("pseudoOP,v,0", new String[]{"DOMAIN SLOT"});
		hsSuggestions.put("pseudoOP,v,1", new String[]{"of"/*, "for"*/});
		hsSuggestions.put("pseudoOP,v,2", new String[]{"DOMAIN CONCEPT", "every", "specific"});
		hsSuggestions.put("pseudoOP,v,3", new String[]{"DOMAIN CONCEPT"});
		hsSuggestions.put("pseudoOP,v,4", new String[]{"having"});

		hsSuggestions.put("oVHSP,v,0", new String[]{"or", "and"});

		hsSuggestions.put("action,v,0", new String[]{"DOMAIN ACTION", "DOMAIN DUTY"});
		hsSuggestions.put("action,v,2", new String[]{"DOMAIN CONCEPT", "DOMAIN SLOT", "every", "specific", "till", "for"});
		hsSuggestions.put("action,v,3", new String[]{"of", "till", "for", "into", "from"});
		hsSuggestions.put("action,v,4", new String[]{"DOMAIN CONCEPT", "every", "specific"});

		hsSuggestions.put("cxaction,v,3", new String[]{"DOMAIN CONCEPT"});
		hsSuggestions.put("cxaction,v,4", new String[]{"having", "till", "for", "into", "from"});
		hsSuggestions.put("cxaction,v,5", new String[]{"DOMAIN CONCEPT"});
		hsSuggestions.put("cxaction,v,6", new String[]{"having", "till", "for", "into", "from"});

		hsSuggestions.put("oVCP,v,0", new String[]{"or", "and", "then"});

		hsSuggestions.put("oVCP1,v,0", new String[]{"DOMAIN SLOT"});
		hsSuggestions.put("oVCP1,v,1", new String[]{"of"/*, "for"*/});
		hsSuggestions.put("oVCP1,v,2", new String[]{"DOMAIN CONCEPT"});
		hsSuggestions.put("oVCP1,v,3", new String[]{"DOMAIN SLOT"});
		hsSuggestions.put("oVCP1,v,4", new String[]{"DOMAIN SLOT"});
		hsSuggestions.put("oVCP1,v,5", new String[]{"of"});
		hsSuggestions.put("oVCP1,v,6", new String[]{"DOMAIN SLOT"});
		hsSuggestions.put("oVCP1,v,7", new String[]{"of"});
		hsSuggestions.put("oVCP1,v,8", new String[]{"DOMAIN CONCEPT"});
		hsSuggestions.put("oVCP1,v,9", new String[]{"is", "is_part_of", "isnot", "equal_to"});
		hsSuggestions.put("oVCP1,v,10", new String[]{"and", "or"});

		hsSuggestions.put("oVHSP1", new String[]{"of"});
		hsSuggestions.put("oVHSP1,v,0", new String[]{"DOMAIN SLOT"});
		hsSuggestions.put("oVHSP1,v,1", new String[]{"as", "as_part_of", "not_equal_to", "equal_to"});
		hsSuggestions.put("oVHSP1,v,2", new String[]{"DOMAIN SLOT"});
		hsSuggestions.put("oVHSP1,v,3", new String[]{"of" /*, "for" */});
		hsSuggestions.put("oVHSP1,v,4", new String[]{"DOMAIN CONCEPT"});
		hsSuggestions.put("oVHSP1,v,5", new String[]{"and", "or", "for", "till", "into", "from"});

		hsSuggestions.put("statement,v,0", new String[]{"DOMAIN ACTOR", "if"});
		hsSuggestions.put("statement", new String[]{"DOMAIN ACTOR", "end"});

		hsSuggestions.put("uAP,v,0", new String[]{"DOMAIN ACTOR"});
		hsSuggestions.put("uAP,v,1", new String[]{"DOMAIN ACTION", "DOMAIN DUTY", "does_following"});
		hsSuggestions.put("uAP,v,2", new String[]{"DOMAIN CONCEPT", "DOMAIN SLOT"});

		hsSuggestions.put("allOC,v,0", new String[]{"having", "from", "into"});

		hsSuggestions.put("specOC,v,0", new String[]{"having", "from", "into"});

		//hsSuggestions.put("ext", new String[]{"secs", "mins", "hrs"});
		hsSuggestions.put("ext,v,0", new String[]{"till", "for", "into", "from"});

		hsSuggestions.put("wext", new String[]{"secs", "mins", "hrs"});
		hsSuggestions.put("wext,v,0", new String[]{"till", "for", "into", "from", "and", "or"});

		hsSuggestions.put("oVP,v,0", new String[]{"DOMAIN SLOT"});
		hsSuggestions.put("oVP,v,1", new String[]{"of", "for"});
		hsSuggestions.put("oVP,v,2", new String[]{"DOMAIN CONCEPT"});
		hsSuggestions.put("oVP,v,3", new String[]{"by", "to", "till", "for"});

		hsSuggestions.put("oV", new String[]{"DOMAIN VALUE", "NUMBER"});

		hsSuggestions.put("oAP,v,0", new String[]{"of"/*, "for"*/});
		hsSuggestions.put("oAP", new String[]{"of"/*, "for"*/});

		hsSuggestions.put("uA", new String[]{"DOMAIN ACTION", "DOMAIN DUTY"});
		hsSuggestions.put("act", new String[]{"DOMAIN ACTOR"});
		hsSuggestions.put("oC", new String[]{"DOMAIN CONCEPT"});
		hsSuggestions.put("oA", new String[]{"DOMAIN SLOT"});

		hsSuggestions.put("num", new String[]{"NUMBER"});

		hsSuggestions.put("allOC", new String[]{"having"});
		hsSuggestions.put("specOC", new String[]{"having"});

        hsSuggestions.put("cP", new String[]{"and", "or", "then\n"});
    }

    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        jSplitPane1 = new javax.swing.JSplitPane();
        tbUcases = new javax.swing.JTabbedPane();
        jScrollPane1 = new javax.swing.JScrollPane();
        pnlSeqDiag = new ImagePanel();
        jMenuBar1 = new javax.swing.JMenuBar();
        mnuFile = new javax.swing.JMenu();
        mnuNewUC = new javax.swing.JMenuItem();
        mnuUC = new javax.swing.JMenu();
        mnuValidateUC = new javax.swing.JMenuItem();

        jSplitPane1.setDividerSize(3);
        jSplitPane1.setResizeWeight(0.7);

        tbUcases.setPreferredSize(new java.awt.Dimension(800, 150));
        jSplitPane1.setLeftComponent(tbUcases);

        javax.swing.GroupLayout pnlSeqDiagLayout = new javax.swing.GroupLayout(pnlSeqDiag);
        pnlSeqDiag.setLayout(pnlSeqDiagLayout);
        pnlSeqDiagLayout.setHorizontalGroup(
            pnlSeqDiagLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 668, Short.MAX_VALUE)
        );
        pnlSeqDiagLayout.setVerticalGroup(
            pnlSeqDiagLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 498, Short.MAX_VALUE)
        );

        jScrollPane1.setViewportView(pnlSeqDiag);

        jSplitPane1.setRightComponent(jScrollPane1);

        mnuFile.setText("File");

        mnuNewUC.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_N, java.awt.event.InputEvent.CTRL_MASK));
        mnuNewUC.setText("Create New Use-Case");
        mnuNewUC.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnuNewUCActionPerformed(evt);
            }
        });
        mnuFile.add(mnuNewUC);

        jMenuBar1.add(mnuFile);

        mnuUC.setText("Use Case");

        mnuValidateUC.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_F9, java.awt.event.InputEvent.CTRL_MASK));
        mnuValidateUC.setText("Validate Use-Case");
        mnuValidateUC.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                mnuValidateUCActionPerformed(evt);
            }
        });
        mnuUC.add(mnuValidateUC);

        jMenuBar1.add(mnuUC);

        setJMenuBar(jMenuBar1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 1669, Short.MAX_VALUE)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 1669, Short.MAX_VALUE))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 498, Short.MAX_VALUE)
            .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                .addComponent(jSplitPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 498, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

	private void mnuValidateUCActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuValidateUCActionPerformed
				for (int i = 0; i < tbUcases.getComponentCount(); i++) {
			Component cmpnt = tbUcases.getComponent(i);
			if (!(cmpnt instanceof jpnUseCase)) {
				continue;
			}
			jpnUseCase uc = (jpnUseCase) cmpnt;

			UseCasePrinter printer = new UseCasePrinter();
			UseCase useCase = printer.getObjectFactory().createUseCase();
			NormalCourse normalCourse = printer.getObjectFactory().createUseCaseNormalCourse();
			useCase.setNormalCourse(normalCourse);
			for (String stmt : uc.getSentences()) {
				printer.processStatement(uc.getNormalCourseValidator().ValidateText(stmt), normalCourse.getStatement());
			}
			//System.out.println(printer.getXmlFromUseCase(useCase));
			printer.getXmlFromUseCase(useCase);
//			if (!DynamicModelValidator.ValidateModel(useCase)) {
//				return;
//			}
			DynamicModelValidator.ValidateModel(useCase);
			SequenceDiagramGenerator generator = new SequenceDiagramGenerator();
			String seqDiagram = generator.createSequenceDiagram(useCase);
			//System.out.println(seqDiagram);
			//
			String scriptFile = System.getProperty(Const.SEQ_DIAGRAM_SCRIPT_KEY);
			File workDir = new File(scriptFile).getParentFile();
			try {
				File tempFile = File.createTempFile("dowser_", ".pic", workDir);
				PrintStream psTemp = new PrintStream(tempFile);
				psTemp.print(seqDiagram);
				psTemp.close();
				String strImg = workDir.getAbsolutePath() + File.separator + "seq_diag.png";
				String strCommand = new File(scriptFile).getAbsolutePath() + " " + tempFile.getAbsolutePath() + " " + strImg;
				Process p = Runtime.getRuntime().exec(strCommand, null, workDir);
				p.waitFor();
				tempFile.delete();
				File flImage = new File(strImg);
				((ImagePanel) pnlSeqDiag).setImageFile(flImage);
				pnlSeqDiag.repaint();
				flImage.delete();
			} catch (IOException ex) {
				ex.printStackTrace(System.err);
			} catch (InterruptedException ex) {
				ex.printStackTrace(System.err);
			}
			//
		}
	}//GEN-LAST:event_mnuValidateUCActionPerformed

	private void mnuNewUCActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_mnuNewUCActionPerformed
				jpnUseCase uc = new jpnUseCase();
		tbUcases.add("Use Case " + (++iUCCounter), uc);
		uc.setNormalCourseValidator(new CellValidator() {

			public CommonTree ValidateText(String text) {
				jpnUseCase uc = (jpnUseCase) tbUcases.getSelectedComponent();
				String sentence = text;
				CharStream ch_stream = new ANTLRStringStream(sentence);
				CGLexer lexer = new CGLexer(ch_stream);
				CGParser parser = new CGParser(new CommonTokenStream(lexer));
				try {
					statement_return result = parser.statement();
					CommonTree ast = (CommonTree) result.getTree();
					uc.setSuggestions(null);
					return ast;
				} catch (RecognitionException exRec) {
					if (!(exRec instanceof ExtendedRecognitionException)) {
						return null;
					}
					ExtendedRecognitionException ex = (ExtendedRecognitionException) exRec;
					String stack = ex.getExceptionData("rule");
					String strRuleName = stack.split(",")[0];
					String strIndex = "";
					if (!(ex.getRecognitionException() instanceof NoViableAltException)) {
						strIndex = strRuleName;
					} else {
						int cnt;
						if (sentence.isEmpty()) {
							cnt = 0;
						} else {
							String[] arrStatement = sentence.split("\n");
							if (arrStatement[arrStatement.length - 1].isEmpty()) {
								cnt = 0;
							} else {
								String strProc = arrStatement[arrStatement.length - 1];
								int strt = ex.getRecognitionException().charPositionInLine <= 0 ? strProc.length() : ex.charPositionInLine;
								String unParsedString = strProc.substring(0, strt);
								cnt = unParsedString.isEmpty() ? 0 : unParsedString.replaceAll("[^ ]", "").length();
							}
						}
						strIndex = strRuleName + ",v," + cnt;
					}
					List<String> lstBLSuggestions = new ArrayList<String>();
					lstBLSuggestions.clear();

					if (hsSuggestions.containsKey(strIndex)) {
						String[] arr = hsSuggestions.get(strIndex);
						//                        System.out.println("### Suggestions : ");
						for (String s : arr) {
							lstBLSuggestions.add(s);
							//                            System.out.println(s);
						}
					}
					uc.setSuggestions(lstBLSuggestions);
				}
				return null;
			}
		});
	}//GEN-LAST:event_mnuNewUCActionPerformed

	private static UseCaseEditor m_Instance;

	/**
	 * @param args the command line arguments
	 */
	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {

			public void run() {
				getInstance().setVisible(true);
			}
		});
	}

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JMenuBar jMenuBar1;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JSplitPane jSplitPane1;
    private javax.swing.JMenu mnuFile;
    private javax.swing.JMenuItem mnuNewUC;
    private javax.swing.JMenu mnuUC;
    private javax.swing.JMenuItem mnuValidateUC;
    private javax.swing.JPanel pnlSeqDiag;
    private javax.swing.JTabbedPane tbUcases;
    // End of variables declaration//GEN-END:variables

}
