/* This software was developed within the context of the project Metaphor for Science
   Museums (Mesmuses) in the framework of the Information Society Technology
   Programme, part of the Fifth Research And Technological Development
	Framework Programme of the European Community, under the Consortium
   Agreement dated <June 30, 2001>, between INRIA, Finsiel Spa, IMSS,
   Valoris , CSI, ICS-FORTH, ENSTB, EDW International.
*/

package gr.forth.ics.vrp.vrpgui;

import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

import gr.forth.ics.vrp.corevrp.*;
import gr.forth.ics.vrp.corevrp.model.*;

/**
 * Containing  the main panel of the VRP GUI.
 *
 * @author Karsten Tolle & Sofia Alexaki
 * @version 2.5  (30 Januar 2003)
 */

public class VRPPanel extends MyPanel{
	// File Variables
	private JTextField file = new JTextField("",20);
	private JTextField output = new JTextField("",20);
	private JButton select_file = new JButton("Select Input File or URL");
	private JButton select_output = new JButton("Select Output File");

	//Input options variables
	private JCheckBox syntax = new JCheckBox("Syntactic Validation" ,false);
	private JCheckBox validation = new JCheckBox("Semantic Validation" ,false);
	private JLabel val_label = new JLabel("Choose Constraints:");

	//Validation Constraints
	private JCheckBox classLoop = new JCheckBox("Class Hierarchy Loops", false);
	private JCheckBox propertyLoop = new JCheckBox("Propery Hierarchy Loops", false);
	private JCheckBox subsetSubpropertyDomainRange = new JCheckBox("Domain/Range of SubProperties", false);
	private JCheckBox sourceTargetTypes = new JCheckBox("Source/Target Resources of properties", false);
	private JCheckBox typing = new JCheckBox("Types of Resources", false);
/*	private JButton allbut = new JButton("All");
	private JButton nonebut = new JButton("None");*/

	//Extend Model options
	private JLabel extModel = new JLabel("Extend Model with triples from ");
	private  JCheckBox fetch_all = new JCheckBox("External Namespaces", false);
	private JCheckBox typeInferCB = new JCheckBox("Type Inference", false);
	private JCheckBox inheritance = new JCheckBox("Domain/Range Inference", false);

	// Output options pane Variables
   private JCheckBox debug = new JCheckBox("Debug",false);
   private JCheckBox triple= new JCheckBox("Triples",false);
	private JCheckBox verbose= new JCheckBox("Verbose", false);
	private JCheckBox graph= new JCheckBox("Graph",false);
	private JCheckBox statement= new JCheckBox("Statements",false);
	private JCheckBox svg= new JCheckBox("SVG",false);
	private JButton svg_option = new JButton("Options");
 	private JButton statistics = new JButton("Statistics Options");

   //Output Area Variables
	private JLabel result_label = new JLabel("Results:");
	private JLabel message_label = new JLabel("Messages:");

  	private JButton start = new JButton("START");
  	private JButton clear = new JButton("CLEAR OUTPUT");
  	private JButton exit = new JButton("EXIT");

	private Model model;
   public static Dialog cfr;
	public static boolean clean_file;
	public JButton yes = new JButton("YES");
	public JButton no = new JButton("NO");
	private ArrayList valconst = new ArrayList();
	public static Main main = new Main();
  	private JFrame jf= null;

	private SVGOutputDialog svg_dialog;
	// generating and packing the frame
  	public VRPPanel(JFrame jf) {
       this.jf = jf;

	   svg_dialog = new SVGOutputDialog(jf);
	   //svg_dialog.setSize(330, 280);

  	   setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
       //File Pane
		   JPanel filePane1 = new JPanel();
       select_file.setBorder(BorderFactory.createBevelBorder(0));
       filePane1.add(select_file);
  		 filePane1.add(file);

    	 JPanel filePane2 = new JPanel();
       select_output.setBorder(BorderFactory.createBevelBorder(0));
       filePane2.add(select_output);
  		 filePane2.add(output);

    	 JPanel filePane = new JPanel();
		filePane.setLayout(new BoxLayout(filePane, BoxLayout.X_AXIS));
		filePane.add(filePane1);
		filePane.add(Box.createRigidArea(new Dimension(15,0)));
      filePane.add(Box.createHorizontalGlue());
    	filePane.add(filePane2);
     	filePane.setBorder(BorderFactory.createTitledBorder("Input/Output File"));

      //validation constraints are added in valconst list
      valconst.add(classLoop);
		valconst.add(propertyLoop);
		valconst.add(subsetSubpropertyDomainRange);
      valconst.add(typing);
      valconst.add(sourceTargetTypes);

      //This pane contains input options
      JPanel inputPane = new JPanel();
		inputPane.setLayout(new BoxLayout(inputPane, BoxLayout.Y_AXIS));
    	inputPane.setBorder(BorderFactory.createTitledBorder("Input Options"));
      syntax.setAlignmentX(JComponent.LEFT_ALIGNMENT);
      inputPane.add(syntax);
      validation.setAlignmentX(JComponent.LEFT_ALIGNMENT);
      inputPane.add(validation);
      //Contains Validation Constraints and Model extension options
      JPanel pane1 = new JPanel();
      pane1.setLayout(new BoxLayout(pane1, BoxLayout.X_AXIS));
      pane1.setAlignmentX(JComponent.LEFT_ALIGNMENT);
	   inputPane.add(pane1);

      //Contains validation constraints
      JPanel constraintpane = new JPanel();
		constraintpane.setLayout(new BoxLayout(constraintpane, BoxLayout.Y_AXIS));
      constraintpane.add(val_label);
      for (int i = 0; i< valconst.size(); i++) {
			JCheckBox but = (JCheckBox)valconst.get(i);
			constraintpane.add(but);
		}

      //Contains buttons for selecting validation constraints
/*      JPanel buttonpane = new JPanel(new FlowLayout());
		buttonpane.add(allbut);
      buttonpane.add(nonebut);*/

      JPanel valoptpane = new JPanel();
		valoptpane.setLayout(new BoxLayout(valoptpane, BoxLayout.Y_AXIS));
		valoptpane.add(constraintpane);
//		valoptpane.add(buttonpane);

      //Contains options to extend RDF Model
      JPanel extendModel = new JPanel();
		extendModel.setLayout(new BoxLayout(extendModel, BoxLayout.Y_AXIS));
      extendModel.add(extModel);
      extendModel.add(fetch_all);
      extendModel.add(typeInferCB);
      extendModel.add(inheritance);
      extendModel.add(Box.createVerticalGlue());

      pane1.add(Box.createRigidArea(new Dimension(30,0)));
      pane1.add(valoptpane);
      pane1.add(extendModel);
      pane1.add(Box.createHorizontalGlue());

      //Output Options Pane
     	JPanel outoptpane = new JPanel(new GridLayout(6,1));
		outoptpane.add(debug);
		outoptpane.add(verbose);
		outoptpane.add(triple);
		outoptpane.add(statement);
        outoptpane.add(graph);
  		JPanel svgPane = new JPanel();
  		svgPane.setLayout(new BoxLayout(svgPane, BoxLayout.X_AXIS));
		svgPane.add(svg);
		svgPane.add(svg_option);
		svg_option.setBorder(BorderFactory.createBevelBorder(0));
		outoptpane.add(svgPane);
		JPanel statisticsPane = new JPanel();
	    statisticsPane.setLayout(new BoxLayout(statisticsPane, BoxLayout.X_AXIS));
        statistics.setBorder(BorderFactory.createBevelBorder(0));
        statisticsPane.add(statistics);
        outoptpane.add(statisticsPane);
		outoptpane.setBorder(BorderFactory.createTitledBorder("Output Options"));

      //Input & Output Options Pane
		JPanel optpane = new JPanel();
      optpane.setLayout(new BoxLayout(optpane, BoxLayout.X_AXIS));
		optpane.add(inputPane);
      optpane.add(Box.createHorizontalGlue());
		optpane.add(outoptpane);

      //Output Area Pane
      Results.setLineWrap(true);
      Results.setWrapStyleWord(false);

      Messages.setLineWrap(true);

      Messages.setWrapStyleWord(false);

  		JPanel outputArea = new JPanel();
		outputArea.setLayout(new BoxLayout(outputArea, BoxLayout.X_AXIS));
    	outputArea.setBorder(BorderFactory.createTitledBorder("Output Area"));
  		JPanel res = new JPanel(new BorderLayout(2,5));
		res.add("North", result_label);
		JScrollPane scrollPane = new JScrollPane(Results);
		res.add("Center", scrollPane);

		JPanel msg = new JPanel(new BorderLayout(2,5));
		msg.add("North", message_label);
		JScrollPane scrollPane2 = new JScrollPane(Messages);
		msg.add("Center", scrollPane2);

  		outputArea.add(res);
		outputArea.add(Box.createRigidArea(new Dimension(10,0)));
      outputArea.add(msg);

      //Functions buttons pane
      JPanel functionPane = new JPanel();
      functionPane.setLayout(new GridLayout(1,7));
    	outputArea.setBorder(BorderFactory.createTitledBorder("Output Area"));
      functionPane.add(Box.createRigidArea(new Dimension(0,20)));
      functionPane.add(start);
      functionPane.add(Box.createRigidArea(new Dimension(0,20)));
      functionPane.add(clear);
      functionPane.add(Box.createRigidArea(new Dimension(0,20)));
      functionPane.add(exit);
      functionPane.add(Box.createRigidArea(new Dimension(0,20)));

  		start.setBorder(BorderFactory.createBevelBorder(0));
   		clear.setBorder(BorderFactory.createBevelBorder(0));
 	  	exit.setBorder(BorderFactory.createBevelBorder(0));

      //Add components to this pane
      add(filePane);
      add(Box.createRigidArea(new Dimension(0,15)));
      add(optpane);
      add(Box.createRigidArea(new Dimension(0,15)));
  		add(outputArea);
      add(Box.createRigidArea(new Dimension(0,15)));
  		add(functionPane);

      //Add check boxes listeners
		CheckBoxListener myListener = new CheckBoxListener();
		debug.addItemListener(myListener);
		triple.addItemListener(myListener);
		verbose.addItemListener(myListener);
		statement.addItemListener(myListener);
		graph.addItemListener(myListener);
		svg.addItemListener(myListener);
		syntax.addItemListener(myListener);
    validation.addItemListener(myListener);
 		fetch_all.addItemListener(myListener);
    typeInferCB.addItemListener(myListener);
  	inheritance.addItemListener(myListener);
		for (int i = 0; i< valconst.size(); i++)
		   ((JCheckBox)valconst.get(i)).addItemListener(myListener);

       //Add check boxes tooltips
		debug.setToolTipText("Forces the lexical analyser to print generated token-names and token-values.");
		triple.setToolTipText("The triples of the parser will be printed.");
		verbose.setToolTipText("Causes VRP to print a feedback of it's activities.");
		statement.setToolTipText("The triples of the model will be printed.");
		graph.setToolTipText("A textual representation of the VRP model will be printed.");
		svg.setToolTipText("SVG graphic representation of the VRP model will be generated");

    	fetch_all.setToolTipText("The descriptions of the external namespaces that are declared in the input file will be inserted in the model!");
      typeInferCB.setToolTipText("The triples which can be inferred for the types of the VRP objects will be inserted in the model!");
      inheritance.setToolTipText("The triples which can be inferred for subproperties with unspecified domain and range  will be inserted in the model!");
      syntax.setToolTipText("Syntactic validation of input file is enabled!");
      validation.setToolTipText("Semantic validation of the input file is enabled!");

      classLoop.setToolTipText("Checks if there is loop in the class hierarchy!");
      propertyLoop.setToolTipText("Checks if there is loop in the property hierarchy!");
 	   subsetSubpropertyDomainRange.setToolTipText("Checks if the domain/range of the subproperty is subset of the domain/range of the superproperty!");
      sourceTargetTypes.setToolTipText("Checks if the source/target resource of a property belongs to the domain/range of the property!");
      typing.setToolTipText("Enables type checking!");

   	JButtonListener jlis = new JButtonListener();
		select_file.addActionListener(jlis);
  		select_output.addActionListener(jlis);
	/*	allbut.addActionListener(jlis);
		nonebut.addActionListener(jlis);*/
		statistics.addActionListener(jlis);
		svg_option.addActionListener(jlis);
      clear.addActionListener(jlis);
      exit.addActionListener(jlis);
    	start.addActionListener(jlis);

      //Add buttons boxes tooltips
		select_file.setToolTipText("Select the file or enter the URL you want to parse-validate!");
    	select_output.setToolTipText("Select the file or enter a new file for saving the output!");
/*      allbut.setToolTipText("Selects all validation constraints!");
      nonebut.setToolTipText("Unselects all validation constraints!");*/
      statistics.setToolTipText("Choose what statistics you need!");
     	start.setToolTipText("Starts the parsing & validation!");
     	exit.setToolTipText("Closes the application!");
      clear.setToolTipText("Clears the Output Area!");

//      subsetSubpropertyDomainRange.setEnabled(false);
     syntax.doClick();
     validation.doClick();
   }


class CheckBoxListener implements ItemListener {
   public void itemStateChanged(ItemEvent e) {
      Object source = e.getItemSelectable();
	   boolean d = false;
		if (e.getStateChange() == ItemEvent.DESELECTED) d = true;
      if (source == debug) {
		   if (d) main.setdebug(false); else main.setdebug(true);
      } else if (source == triple) {
		if (d) main.settriples(false); else main.settriples(true);
        } else if (source == verbose) {
		if (d) main.setverbose(false); else main.setverbose(true);
        } else if (source == statement) {
		if (d) main.setstatements(false); else main.setstatements(true);
        } else if (source == graph) {
			if (d) main.setgraph(false); else main.setgraph(true);
		} else if (source == svg) {
				if (d) main.setsvg(false); else main.setsvg(true);
		} else if (source == fetch_all) {
			if (d) main.setfetch_all(false); else main.setfetch_all(true);
      }  else
         if (source == syntax) {
			if (d) {
            if  (validation.isSelected())
               validation.doClick();
            if  (debug.isSelected())
               debug.doClick();
            if  (verbose.isSelected())
               verbose.doClick();
            if  (triple.isSelected())
               triple.doClick();
            if  (statement.isSelected())
               statement.doClick();
            debug.setEnabled(false);
            verbose.setEnabled(false);
            triple.setEnabled(false);
            statistics.setEnabled(false);
			} else {
			 	main.setonly(true);
            debug.setEnabled(!d);
            verbose.setEnabled(!d);
            triple.setEnabled(!d);
            statistics.setEnabled(true);

         }
	   }  else if (source == validation) {
			if (d) {
            unSelectAllValidationOptions();
            enableAllValidationOptions(false);
          	main.setonly(true);
            if  (statement.isSelected())
               statement.doClick();
            if  (graph.isSelected())
               graph.doClick();
            if  (svg.isSelected())
               svg.doClick();
            statement.setEnabled(false);
            graph.setEnabled(false);
			svg.setEnabled(false);
//            statistics.setEnabled(false);

         } else {
            if  (!syntax.isSelected())
               syntax.doClick();
        	 	main.setonly(false);
            enableAllValidationOptions(true);
            selectAllConst();
            statement.setEnabled(true);
            graph.setEnabled(true);
			svg.setEnabled(true);
//            statistics.setEnabled(true);
         }
      } else if (source == classLoop) {
    		if (d) main.setclassLoop(false); else main.setclassLoop(true);
	    } else if (source == propertyLoop) {
			if (d) {
          main.setpropertyLoop(false);
          if (inheritance.isSelected())
			    inheritance.doClick();
          inheritance.setEnabled(!d);
          if (subsetSubpropertyDomainRange.isSelected())
			    subsetSubpropertyDomainRange.doClick();
          subsetSubpropertyDomainRange.setEnabled(!d);
         } else {
          main.setpropertyLoop(true);
          inheritance.setEnabled(!d);
          subsetSubpropertyDomainRange.setEnabled(!d);
         }
	    }	 else if (source == inheritance) {
			if (d) main.setinheritance(false); else main.setinheritance(true);
	    }	 else if (source == typeInferCB) {
			if (d) main.setTypeInfer(false); else main.setTypeInfer(true);
	    }	 else if (source == subsetSubpropertyDomainRange) {
			if (d) main.setsubsetSubpropertyDomainRange(false); else main.setsubsetSubpropertyDomainRange(true);
	 	} else if (source == typing) {
			if (d) main.settyping(false); else main.settyping(true);
		}  else if (source == sourceTargetTypes) {
			if (d) main.setsourceTargetTypes(false);
          else main.setsourceTargetTypes(true);
		}
	 }
	}

   	// implements the button actions
	class JButtonListener implements ActionListener{
		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == start) start();
			else if (e.getSource() == select_file)
            laden(1);
			else if (e.getSource() == select_output)
            laden(2);
  		else if (e.getSource() == clear) {
          Results.setText("");
          Messages.setText("");
			}
  			else if (e.getSource() == exit)
            System.exit(0);
         else if (e.getSource() == yes)  {
            clean_file = true;
            cfr.dispose();
         }else if (e.getSource() == no) {
            clean_file = false;
            cfr.dispose();
         } else if (e.getSource() == statistics) {
				 new StatisticsDialog(null, areAllConstraintsEnabled());
			} else if (e.getSource() == svg_option) {
				 svg_dialog.show();
			}
		}
	}

	// for the button "select file"
	void laden(int i) {
		JFileChooser fc = new JFileChooser();
		fc.setDialogTitle("Select file");
		int rVal = fc.showDialog(this, "Ok");
		if (rVal == JFileChooser.APPROVE_OPTION) {
		    StringBuffer sb = new StringBuffer();
		    sb.append(fc.getCurrentDirectory().toString());
			sb.append(File.separator);
		    sb.append(fc.getSelectedFile().getName());
			if (i == 1) file.setText(sb.toString());
		    if (i == 2) output.setText(sb.toString());
	    }
		if (rVal == JFileChooser.CANCEL_OPTION)  {
		     if (i == 1) file.setText("");
		     if (i == 2) output.setText("");
		}
	}

	// for the button "start parsing"
	void start() {
		if (file.getText().equals(""))
         Messages.append("\nselect an input file first\n");
      else if (!syntax.isSelected())
          Messages.append("\nSelect the kind of validation that will be performed on the input file i.e., syntactic or/and semantic.");
		else {
         //Call explicitly garbage collector to free memory
			//used for parsing and validation
		   System.runFinalization();
		   System.gc();
         main.setGUI(this);
		 //	main.setsimple(simple.getState());
			if (!(output.getText().equals("")))
				main.setOutputFile(output.getText());
			else  main.setOutputFile(null);
    		main.start(file.getText());
     initMainVariables();
      }
	}

   void initMainVariables() {
      Main.error_counter = 0 ;
      Main.warning_counter = 0;
      main.setnoerrormsg(false);
      main.settimeStatistics(false);
		main.enableModelStatistics(0, false);
		main.enableModelStatistics(1, false);
		main.enableModelStatistics(2, false);
		main.enableModelStatistics(3, false);
/*      main.enableModelStatistics(4, false);
		main.enableModelStatistics(5, false);*/
   }

	public void clean_file_request(String file) {
	    String s = "Overwrite File ?";
	    cfr = new Dialog(jf,s);
	    cfr.setModal(true);
	    cfr.setLayout(new GridLayout(2,1,10,10));

	    cfr.add(new Label("Do you want to overwrite the existing file: "+file));
	    Panel dp = new Panel(new FlowLayout());
    	    dp.add(yes);
	    dp.add(no);
	    cfr.add(dp);
       	cfr.pack();
	    JButtonListener jbis = new JButtonListener();

	    yes.setToolTipText("The selected file will be replaced!");
//	    yes.setActionCommand("yes");
	    yes.addActionListener(jbis);

	    no.setToolTipText("Output will be saved in the file!");
//	    no.setActionCommand("no");
	    no.addActionListener(jbis);
	    cfr.setLocation(150,200);
	    cfr.show();
	}

	void selectAllConst() {
      for (int i = 0; i< valconst.size(); i++)  {
		   JCheckBox cb = (JCheckBox)valconst.get(i);
		      if (!cb.isSelected())
			      cb.doClick();
		}
	}

	void unSelectAllConst() {
		for (int i = 0; i< valconst.size(); i++) {
			JCheckBox cb = (JCheckBox)valconst.get(i);
		    if (cb.isSelected())
			    cb.doClick();
		}
	}

  /**
   * Returns true if all samantic constraints are selected
   */
  boolean areAllConstraintsEnabled() {
      boolean enable = true;
		for (int i = 0; i< valconst.size(); i++) {
			JCheckBox cb = (JCheckBox)valconst.get(i);
         enable = enable && cb.isSelected();
		}
      return enable;
	}


 	void unSelectAllValidationOptions() {
      unSelectAllConst();
      if (typeInferCB.isSelected())
		   typeInferCB.doClick();
      if (inheritance.isSelected())
		   inheritance.doClick();
      if (fetch_all.isSelected())
 	      fetch_all.doClick();
 	}

	void enableAllConst(boolean b) {
		for (int i = 0; i< valconst.size(); i++)
		    ((JCheckBox)valconst.get(i)).setEnabled(b);
      if ( b )
         subsetSubpropertyDomainRange.setEnabled(false);
   }

   void enableAllValidationOptions(boolean b) {
		for (int i = 0; i< valconst.size(); i++)
		    ((JCheckBox)valconst.get(i)).setEnabled(b);
      if ( b )
         subsetSubpropertyDomainRange.setEnabled(false);
      typeInferCB.setEnabled(b);
      fetch_all.setEnabled(b);

   }

	public Insets getInsets() {
		return new Insets(14,14,14,14);
	}
}



