/*
 * MainPanel.java
 *
 * Created on Ketvirtadienis, 2007, Sausio 25, 17.16
 *
 * To change this template, choose Tools | Template Manager
 * and open the template in the editor.
 */

package Main.panels;

import java.io.*;
import java.net.*;
import Main.algorithms.*;
import Main.data.*;
import Main.equation.*;
import Main.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;

public class MainPanel extends JPanel
{
	public int indeksas2;
        public int indeksas3 = 5;
        private final String DEFAULT_URL= "Default";
	private final String SPECIFIED_URL= "Load URL";
	private final String USE_URL= "Use URL";
	private final String SOLVE= "Solve";
	private final String ALGORITHMS= "Algorithms";
	
	private final String CGI_SAVER= "writer.cgi";
	
	public static final String DSA= "Direct Search Algorithm";
    public static final String IFA= "Irrelevant Fraud Algorithm";
	public static final String NSCA= "Necessary And Sufficient Conditions";
	public static final String SEA= "Strategy Elimination Algorithm";
	public static final String QSEA= "Quadratic Strategy Elimination Algorithm";
	public static final String Altruistic = "Altruistic Algorithm";
	
	public static final String LOAD_DATA= "Load Data";
	public static final String BAD_URL_FORMAT= "Bad URL format.";
	public static final String CANT_ESTABLISH_CONECTION= "Can't establish connection!";
	public static final String DATA_LOAD_SUCCESSFUL= "Data loaded successfully!";
	public static final String DATA_SAVE_SUCCESSFUL= "Data saved successfully!";
	public static final String HEADER_MARK= "PGQ";
	public static final String FILE_FORMAT_NOT_RECOGNIZED= "File format not recognized!";
	public static final String SAVE_DATA= "Save Data";
	public static final String SAVE_REZULTS= "Save Rezults";
	public static final String WRITE_ERROR= "Savaing failed!";
	public static final String REZULTS_SAVE_SUCCESSFUL= "Results saved successfully";
	//private final String[] ALGORITHMS_LIST =	{DSA,IFA,SEA, QSEA, MAX_MIN};
//	private final String[] ALGORITHMS_LIST =	{DSAA, IFA , Altruistic, QSEA};
private final String[] ALGORITHMS_LIST =	{IFA , QSEA};	
	JTextField mSpecifiedURL;
	JTextField mSaveDataURL;
	JTextField mSaveRezultsURL;
	JButton mLoadURLButton;
	JButton mSaveURLButton;
	JButton mSaveRezultsURLButton;
	JCheckBox useData;
	JButton solve;
	JComboBox mAlgorithms;
	
	public MainPanel()
	{
		setLayout(new GridBagLayout());
		
		JPanel tempPanel= new JPanel();
		tempPanel.setLayout(new GridBagLayout());
		
		mLoadURLButton= new JButton(LOAD_DATA);
		GridBagConstraints gbc= new GridBagConstraints();
		gbc.gridx= 1;
		gbc.gridy= 1;
		gbc.weighty= 0;
		//gbc.weightx=1;
		gbc.fill= GridBagConstraints.NONE;
		gbc.anchor= GridBagConstraints.NORTHWEST;
		gbc.insets = new Insets(5,5,5,5);
		((GridBagLayout)tempPanel.getLayout()).setConstraints(mLoadURLButton, gbc);
		tempPanel.add(mLoadURLButton);
		
		mLoadURLButton.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				loadData();
			}
		}
		);
		
		mSpecifiedURL= new JTextField(DEFAULT_URL);
		gbc= new GridBagConstraints();
		gbc.gridx= 2;
		gbc.gridy= 1;
		gbc.weighty= 0;
		gbc.weightx=1;
		gbc.fill= GridBagConstraints.HORIZONTAL;
		gbc.anchor= GridBagConstraints.NORTHWEST;
		gbc.insets = new Insets(5,5,5,5);
		((GridBagLayout)tempPanel.getLayout()).setConstraints(mSpecifiedURL, gbc);
		tempPanel.add(mSpecifiedURL);
		
		mSaveURLButton= new JButton(SAVE_DATA);
		gbc= new GridBagConstraints();
		gbc.gridx= 1;
		gbc.gridy= 2;
		gbc.weighty= 0;
		//gbc.weightx=1;
		gbc.fill= GridBagConstraints.NONE;
		gbc.anchor= GridBagConstraints.NORTHWEST;
		gbc.insets = new Insets(5,5,5,5);
		((GridBagLayout)tempPanel.getLayout()).setConstraints(mSaveURLButton, gbc);
		tempPanel.add(mSaveURLButton);
		
		mSaveURLButton.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				saveData();
			}
		}
		);
		
		mSaveDataURL= new JTextField(DEFAULT_URL);
		gbc= new GridBagConstraints();
		gbc.gridx= 2;
		gbc.gridy= 2;
		gbc.weighty= 0;
		gbc.weightx=1;
		gbc.fill= GridBagConstraints.HORIZONTAL;
		gbc.anchor= GridBagConstraints.NORTHWEST;
		gbc.insets = new Insets(5,5,5,5);
		((GridBagLayout)tempPanel.getLayout()).setConstraints(mSaveDataURL, gbc);
		tempPanel.add(mSaveDataURL);
		
		mSaveRezultsURLButton= new JButton(SAVE_REZULTS);
		gbc= new GridBagConstraints();
		gbc.gridx= 1;
		gbc.gridy= 3;
		gbc.weighty= 0;
		//gbc.weightx=1;
		gbc.fill= GridBagConstraints.NONE;
		gbc.anchor= GridBagConstraints.NORTHWEST;
		gbc.insets = new Insets(5,5,5,5);
		((GridBagLayout)tempPanel.getLayout()).setConstraints(mSaveRezultsURLButton, gbc);
		tempPanel.add(mSaveRezultsURLButton);
		
		mSaveRezultsURLButton.addActionListener(new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				saveRezults();
			}
		}
		);
		
		mSaveRezultsURL= new JTextField(DEFAULT_URL);
		gbc= new GridBagConstraints();
		gbc.gridx= 2;
		gbc.gridy= 3;
		gbc.weighty= 0;
		gbc.weightx=1;
		gbc.fill= GridBagConstraints.HORIZONTAL;
		gbc.anchor= GridBagConstraints.NORTHWEST;
		gbc.insets = new Insets(5,5,5,5);
		((GridBagLayout)tempPanel.getLayout()).setConstraints(mSaveRezultsURL, gbc);
		tempPanel.add(mSaveRezultsURL);
		
		gbc= new GridBagConstraints();
		gbc.gridwidth= GridBagConstraints.REMAINDER;
		gbc.weighty= 0;
		gbc.weightx=1;
		gbc.fill= GridBagConstraints.HORIZONTAL;
		gbc.anchor= GridBagConstraints.NORTH;
		((GridBagLayout)getLayout()).setConstraints(tempPanel, gbc);
		add(tempPanel);
		
		
		JLabel algorithm= new JLabel(ALGORITHMS+":");
		gbc= new GridBagConstraints();
		gbc.gridx= 1;
		gbc.gridy= 3;
		gbc.weightx=1;
		gbc.weighty=0;
		gbc.fill= GridBagConstraints.NONE;
		gbc.anchor= GridBagConstraints.NORTHWEST;
		gbc.insets = new Insets(5,5,5,5);
		((GridBagLayout)getLayout()).setConstraints(algorithm, gbc);
		add(algorithm);
		
		mAlgorithms= new JComboBox(ALGORITHMS_LIST);
		gbc= new GridBagConstraints();
		gbc.gridx= 2;
		gbc.gridy= 3;
		gbc.weightx=1;
		gbc.weighty=0;
		gbc.fill= GridBagConstraints.HORIZONTAL;
		gbc.anchor= GridBagConstraints.NORTHWEST;
		gbc.insets = new Insets(5,5,5,5);
		((GridBagLayout)getLayout()).setConstraints(mAlgorithms, gbc);
		add(mAlgorithms);
		
		mAlgorithms.addItemListener(new ItemListener()
		{
			public void itemStateChanged(ItemEvent e)
			{
				AbstractAlgorithm alg= null;
				Object value= mAlgorithms.getSelectedItem();
				if(value.equals(DSA))
				{
					alg= new DSAAlgorithm();
				}
				else if(value.equals(IFA))
				{
					alg= new IFAlgorithm();
				}
				else if(value.equals(SEA))
				{
					alg= new SEAlgorithm();
				}
				else if(value.equals(QSEA))
				{
					alg= new QSEAlgorithm();
				}
				else if(value.equals(Altruistic))
				{
					alg= new MaxMinAlgorithm();
				}
				MainWindow.getInstance().setAlgorithm(alg);				
			}
		}
		);
		
		solve= new JButton(SOLVE);
		gbc= new GridBagConstraints();
		gbc.gridx= 1;
		gbc.gridy= 4;
		//gbc.weightx=1;
		//gbc.weighty=1;
		gbc.fill= GridBagConstraints.NONE;
		gbc.anchor= GridBagConstraints.NORTHWEST;
		gbc.insets = new Insets(5,5,5,5);
		((GridBagLayout)getLayout()).setConstraints(solve, gbc);
		add(solve);
		
		solve.addActionListener( new ActionListener()
		{
			public void actionPerformed(ActionEvent e)
			{
				solve();
			}
		}
		);
		
		
	
		
	}
	
	private void solve()
	{
		AbstractAlgorithm algorithm= MainWindow.getInstance().getAlgorithm();
		if(algorithm == null)
		{
			return;
		}
		algorithm.setMatrix(MainWindow.getInstance().getInputDataPanel().getInputDataModel().getDataAsArray());
                
		algorithm.solve();
                evaluation(algorithm);
                algorithm.solve();
                //evaluation(algorithm);
                algorithm.solveFineProblem();
                
/*CIA */        MainWindow.getInstance().getOutputDataPanel().getOutputModel().setDataAsArray(algorithm.getResult());
                
		
		
		
		
	}
	
	private void loadData()
	{
		URL urlString= null;
		
		InputStream stream= null;
		URLConnection con= null;
		try{
			if( (con= getURLConnection(mSpecifiedURL.getText())) == null)
			{
				return;
			}
			con.setDoInput(true);
			stream= con.getInputStream();
		}
		catch(Exception e)
		{
			showError(CANT_ESTABLISH_CONECTION);
			e.printStackTrace();
			return;
		}
		
		java.util.List list= MainWindow.getInstance().readData(stream);
		MainWindow.getInstance().getInputDataPanel().getInputDataModel().setColumns(InputDataSlot.DATA_NAMES);
		MainWindow.getInstance().getInputDataPanel().getInputDataModel().setData( list);
		//readData( new DataInputStream(stream) );
		
	}
	
	private URLConnection getURLConnection(String url)
	{
		URL urlString= null;
		try{
		urlString= new URL(url);
		}
		catch(MalformedURLException e)
		{
			showError(BAD_URL_FORMAT);
			return null;
		}

		URLConnection con= null;
		try{
			con= urlString.openConnection();
			if(con instanceof HttpURLConnection)
				con= (HttpURLConnection)con;
		}
		catch(Exception e)
		{
			showError(CANT_ESTABLISH_CONECTION);
			e.printStackTrace();
			return null;
		}
		
		return con;
	}
	
	/*private void readData(DataInputStream stream)
	{
		boolean checkHeader= true;
		try{
			String header= stream.readLine();
			if(!header.equalsIgnoreCase(HEADER_MARK))
			{
				checkHeader= false;
			}
		}
		catch(Exception e)
		{
			checkHeader= false;
		}
		
		if(!checkHeader)
		{
			showError(FILE_FORMAT_NOT_RECOGNIZED);
			return;
		}
		
		Vector data= new Vector(10);
		for(;;)
		{
			float p, g, q;
			try{
				String line= stream.readLine();
				StringTokenizer tokenizer= new StringTokenizer(line, " ");

				String str= tokenizer.nextToken();	
				p= Float.parseFloat(str);
				
				str= tokenizer.nextToken();
				g= Float.parseFloat(str);
				
				str= tokenizer.nextToken();
				q= Float.parseFloat(str);
			}
			catch(Exception e)
			{
				break;
			}
			
			InputDataSlot slot= new InputDataSlot(p, g, q);
			data.add(slot);
		}

		try{
		stream.close();
		}
		catch(Exception e)
		{
			showError(e.getMessage());
		}
		MainWindow.getInstance().getInputDataPanel().getInputDataModel().setData(data);
		showInfo(DATA_LOAD_SUCCESSFUL);
	}*/
	
	private void writeData(DataOutputStream stream, String data)
	{
		
		try{

		stream.writeBytes(InputDataSlot.createRepresentationString()+"\n");
		writeString(stream, data);
		                                                      
		}
		catch(Exception e)
		{
			showError(WRITE_ERROR);
		}

		finally
		{
			try{
			stream.close();
			}
			catch(Exception e)
			{
				showError(e.getMessage());
				return;
			}
			//showInfo(DATA_SAVE_SUCCESSFUL);
		}
		
		showInfo(DATA_SAVE_SUCCESSFUL);
	}
	
	private void writeRezults(DataOutputStream stream, String data)
	{
		try{

		writeString(stream, data);
		                                                      
		}
		catch(Exception e)
		{
			showError(WRITE_ERROR);
		}

		finally
		{
			try{
			stream.close();
			}
			catch(Exception e)
			{
				showError(e.getMessage());
				return;
			}
			//showInfo(DATA_SAVE_SUCCESSFUL);
		}
		
		showInfo(REZULTS_SAVE_SUCCESSFUL);
	}
	
	private void writeString(DataOutputStream stream, String data) throws Exception
	{
		stream.writeBytes(data);                                         
	}
	
	private void saveData()
	{
		URLConnection con= null;
		OutputStream stream= null;
		try{
			if( (con= getURLConnection(mSaveDataURL.getText())) == null )
			{
				return;
			}
			
			//con.setDoOutput(true);		
		
			File output= new File(con.getURL().getFile());
	
			//stream= con.getOutputStream();
			stream= new FileOutputStream(output);
		}
		catch(Exception e)
		{
			showError(CANT_ESTABLISH_CONECTION);
			e.printStackTrace();
			return;
		}
		
		writeData( new DataOutputStream(stream), getStringForDataSaving() );
	}
	
	private String getStringForDataSaving()
	{
		java.util.List data= MainWindow.getInstance().getInputDataPanel().getInputDataModel().getData();
		StringBuffer buf= new StringBuffer();
		if(data != null)
			for(Iterator it= data.iterator();it.hasNext();)
			{
				InputDataSlot slot= (InputDataSlot)it.next();
				buf.append(slot.createDataString()+"\n");
				//buf.append(URLEncoder.encode(slot.getP()+"::"+slot.getG()+"::"+slot.getQ()+"&&"));
				//String save= new String(slot.getP()+" "+slot.getG()+" "+slot.getQ()+"\n");
				//stream.writeUTF(save);
				
			}
		
		return buf.toString();
	}
	
	private String getStringForRezultSaving()
	{
		java.util.List data= MainWindow.getInstance().getOutputDataPanel().getOutputModel().getData();
		StringBuffer buf= new StringBuffer();
		if(data != null)
			for(Iterator it= data.iterator();it.hasNext();)
			{
				OutputDataSlotXY slot= (OutputDataSlotXY)it.next();
				buf.append(slot.getX()+" "+slot.getY()+"\n");
			}
		
		return buf.toString();
	}
	
	private void saveRezults()
	{
		URLConnection con= null;
		OutputStream stream= null;
		try{
			if( (con= getURLConnection(mSaveRezultsURL.getText())) == null )
			{
				return;
			}
			
			//con.setDoOutput(true);		
		
			File output= new File(con.getURL().getFile());
	
			//stream= con.getOutputStream();
			stream= new FileOutputStream(output);
		}
		catch(Exception e)
		{
			showError(CANT_ESTABLISH_CONECTION);
			e.printStackTrace();
			return;
		}
		
		writeRezults( new DataOutputStream(stream), getStringForRezultSaving() );
	}
	
	public static void showError(String s)
	{
		JOptionPane.showMessageDialog(new Frame(),s ,"ERROR", JOptionPane.ERROR_MESSAGE);
	}
	
	public static void showInfo(String s)
	{
		JOptionPane.showMessageDialog(new Frame(),s ,"INFORMATION", JOptionPane.INFORMATION_MESSAGE);
	}
	
	private void evaluation(AbstractAlgorithm a)
	{
		
		if(a.isSolved())
		{
			
			Evaluation evaluation= new Evaluation();
			evaluation.setMatrix(a.getMatrix());
			evaluation.setMatrixXY(a.getResult());
			evaluation.setAlgorithm(a);
			
			double[][] rezult= a.getResult();
			//a.reset();
			
			evaluation.solve();
			
			double[][] evaluationResult= evaluation.getResult();
			
			Object[][] matrixToShow= new Object[rezult.length][5];
			
			for(int i=0; i< matrixToShow.length; i++)
			{
				matrixToShow[i][0]= new Integer(i);
				matrixToShow[i][1]= new Double(evaluationResult[i][0]);
				matrixToShow[i][2]= new Double(evaluationResult[i][1]);
				matrixToShow[i][3]= new Double(rezult[i][0]- evaluationResult[i][0]);
				matrixToShow[i][4]= new Double(rezult[i][1]- evaluationResult[i][1]);
			}
			MainWindow.getInstance().getRezultsComparingPanel().setData(matrixToShow);
			
		}
		else
		{
			MainWindow.getInstance().getRezultsComparingPanel().setData(null);
		//	MainWindow.getInstance().getOutputStreamPanel().logn("No solution - no evaluation");
		}
		
		
	}
	
	public String getDataLoadURL()
	{
		return mSpecifiedURL.getText();
	}
	
	public void setDataLoadURL(String s)
	{
		mSpecifiedURL.setText(s);
	}
	
	public String getDataSaveURL()
	{
		return mSaveDataURL.getText();
	}
	
	public void setDataSaveURL(String s)
	{
		mSaveDataURL.setText(s);
	}
	
	public String getResultsSaveURL()
	{
		return mSaveRezultsURL.getText();
	}
	
	public void setResultsSaveURL(String s)
	{
		mSaveRezultsURL.setText(s);
	}
	
}

