/* BEGIN_HEADER                                              Java TreeView
 *
 * $Author: alokito $
 * $RCSfile: LinkedViewFrame.java,v $
 * $Revision: 1.51 $
 * $Date: 2008-06-11 01:58:57 $
 * $Name:  $
 *s
 * This file is part of Java TreeView
 * Copyright (C) 2001-2014 Alok Saldanha, All Rights Reserved. Modifications Copyright (C) Lawrence Berkeley Lab.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 * END_HEADER 
 */
package edu.stanford.genetics.treeview;


import java.io.File;
import java.util.Observer;

import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import edu.stanford.genetics.treeview.app.LinkedViewApp;
import edu.stanford.genetics.treeview.core.PluginManager;
import edu.stanford.genetics.treeview.model.KnnModel;

/** 
 * This class implements the GUI portion of the LinkedView application 
 * 
 */
public class LinkedViewFrame extends TreeViewFrame implements Observer
{




	private static String appName = "Java TreeView";
	public String getAppName() {
		return appName;
	}
	public LinkedViewFrame(LinkedViewApp treeview)
	{
		super(treeview, appName);
	}
	public LinkedViewFrame(TreeViewApp treeview, String subName)
	{
		// sorry this is so ugly, but can't call getAppName until
		// superclass constructor's done.
		super(treeview, subName);
	}
	
	

	private String getStyle(FileSet fileSet) {
		if (fileSet.getStyle() == FileSet.AUTO_STYLE) {
			return "auto";
		}
		if (fileSet.getStyle() == FileSet.CLASSIC_STYLE) {
			return "classic";
		}
		if (fileSet.getStyle() == FileSet.KMEANS_STYLE) {
			return "kmeans";
		}
		if (fileSet.getStyle() == FileSet.LINKED_STYLE) {
			return "linked";
		}
		return "unknown";
	}
	
	/**
	 r     * This is the workhorse. It creates a new DataModel of the
	 * file, and then sets the Datamodel. 
	 * A side effect of setting the datamodel is to
	 * update the running window.
	 */
	public void loadFileSet(FileSet fileSet)  throws LoadException {
		LogBuffer.println("initial style " + getStyle(fileSet));
		if (fileSet.getStyle() == FileSet.AUTO_STYLE) {
			if (fileSet.getKag().equals("") && fileSet.getKgg().equals("")) {
				super.loadFileSet(fileSet); // loads into TVModel.
			} else {
				loadKnnModel(fileSet);
			}
		} else {
			if (fileSet.getStyle() == FileSet.KMEANS_STYLE) {
				loadKnnModel(fileSet);
			} else {
				super.loadFileSet(fileSet);
			}
		}
	} 
	
	private void loadKnnModel(FileSet fileSet) throws LoadException {
		KnnModel knnModel = new KnnModel();
		knnModel.setFrame(this);
		try {
			knnModel.loadNew(fileSet);
			fileSet.setStyle(FileSet.KMEANS_STYLE);
			setDataModel(knnModel);
		} catch (LoadException e) {
			JOptionPane.showMessageDialog(this, e);
			throw e;
		}
	}
	
	 protected void setupRunning() {
		 FileSet fileSet = getDataModel().getFileSet();
		 if (fileSet == null) {
		 	//default to linked
		 	fileSet = new FileSet(null,null);
		 	fileSet.setStyle(FileSet.LINKED_STYLE);
		 } else if (fileSet.getStyle() == FileSet.AUTO_STYLE) {
			 if (getDataModel().getDocumentConfigRoot().fetchFirst("Views") != null) {
				 fileSet.setStyle(FileSet.LINKED_STYLE);
			 } else {
				 HeaderInfo geneHeaders = getDataModel().getGeneHeaderInfo();
				 HeaderInfo arrayHeaders = getDataModel().getArrayHeaderInfo();

				 if ((geneHeaders.getNumNames() > 4) || (arrayHeaders.getNumNames() > 3)) {
					 fileSet.setStyle(FileSet.LINKED_STYLE);
				 } else {
					 fileSet.setStyle(FileSet.CLASSIC_STYLE);
				 }
			 }
		 }
		 
		 
		 if (fileSet.getStyle() == FileSet.LINKED_STYLE) {
			 LinkedPanel linkedPanel  = new LinkedPanel(this);
			 linkedPanel.addChangeListener(new ChangeListener() {
				 public void stateChanged(ChangeEvent e) {
					 // rebulid menus...?
					 //				 menuBar.rebuildMainPanel();
					 rebuildMainPanelMenu();
				 }
			 });
			 ConfigNode documentConfig = getDataModel().getDocumentConfigRoot();
			 linkedPanel.setConfigNode(documentConfig.fetchOrCreate("Views"));
			 running = linkedPanel;
		 } else if (fileSet.getStyle() == FileSet.KMEANS_STYLE) {
			// make sure selection objects are set up before instantiating plugins
			 PluginFactory [] plugins = PluginManager.getPluginManager().getPluginFactories();
			 for (int j =0; j < plugins.length; j++) {
				 if ("KnnDendrogram".equals(plugins[j].getPluginName())) {
					 running = plugins[j].restorePlugin(null, this);
					 break;
				 }
			 }
		 } else  {
			// make sure selection objects are set up before instantiating plugins
			 PluginFactory [] plugins = PluginManager.getPluginManager().getPluginFactories();
			 for (int j =0; j < plugins.length; j++) {
				 if ("Dendrogram".equals(plugins[j].getPluginName())) {
					 running = plugins[j].restorePlugin(null, this);
					 break;
				 }
			 }
		 }
		LogBuffer.println("final style " + getStyle(fileSet));
    }
	 
	 /**
	  * This class implements controls for file opening options.
	  * It is factored into a separate class because it is used by
	  * both the offerSelection() and offerUrlSelection dialogs.
	  * 
	  * @author aloksaldanha
	  *
	  */
	 private class FileOptionsPanel extends Box {
		 private JComboBox dataList;
		 private JCheckBox quoteBox;
		 public FileOptionsPanel() {
			 super(BoxLayout.Y_AXIS);
			 dataList = new JComboBox(FileSet.getStyles());	
			 dataList.setEditable(false);
			 
			 JPanel stylePanel = new JPanel();
			 JLabel style = new JLabel("Style:");
			 stylePanel.add(style);
			 stylePanel.add(dataList);
				
			 JPanel quotePanel = new JPanel();
			 quoteBox = new JCheckBox("Parse quoted strings");
			 quotePanel.add(quoteBox);

			 // values from last time...
			 quoteBox.setSelected(fileMru.getParseQuotedStrings());
			 dataList.setSelectedIndex(fileMru.getStyle());
				
			 add(stylePanel);
			 add(quotePanel);
			 add(Box.createGlue());
			 try {
				 setBorder(BorderFactory.createTitledBorder("Options"));
			 } catch (Exception e) {
				 LogBuffer.println("Could not create border in LinkedViewFrame.offerSelection");
			 }
		 }
		 public int getSelectedStyleIndex() {
			 fileMru.setStyle(dataList.getSelectedIndex());
			 return dataList.getSelectedIndex();
		 }
		public boolean isQuoteSelected() {
			fileMru.setParseQuotedStrings(quoteBox.isSelected());
			return quoteBox.isSelected();
		}

	 }
	/**
	* Open a dialog which allows the user to select a new data file
	*
	* @return The fileset corresponding to the dataset.
	*/
	protected FileSet offerSelection()
	throws LoadException
	{
		FileSet fileSet1; // will be chosen...
		JFileChooser fileDialog = new JFileChooser();
		setupFileDialog(fileDialog);
		FileOptionsPanel boxPanel = new FileOptionsPanel();
		fileDialog.setAccessory(boxPanel); 
		int retVal = fileDialog.showOpenDialog(this);
		if (retVal == JFileChooser.APPROVE_OPTION) {
			File chosen = fileDialog.getSelectedFile();
			
			fileSet1 = new FileSet(chosen.getName(), chosen.getParent()+File.separator);
		} else {
			throw new LoadException("File Dialog closed without selection...", LoadException.NOFILE);
		}
		fileSet1.setStyle(boxPanel.getSelectedStyleIndex());
		fileSet1.setParseQuotedStrings(boxPanel.isQuoteSelected());
		return fileSet1;
	}

	  protected FileSet offerUrlSelection()
	  throws LoadException
	  {
		  FileSet fileSet1;
		  // get string from user...
		  FileOptionsPanel boxPanel = new FileOptionsPanel();
		  Box panel = new Box(BoxLayout.Y_AXIS);
		  panel.add(boxPanel);
		  panel.add(new JLabel("Enter a Url:"));
		  String urlString = JOptionPane.showInputDialog(this, panel);
		  if (urlString != null) {
			  // must parse out name, parent + sep...
			  int postfix = urlString.lastIndexOf("/") + 1;
			  String name = urlString.substring(postfix);
			  String parent = urlString.substring(0,postfix);
			  fileSet1 = new FileSet(name, parent);
		  } else {
			  throw new LoadException("Input Dialog closed without selection...", LoadException.NOFILE);
		  }
		  
		  fileSet1.setStyle(boxPanel.getSelectedStyleIndex());
		  fileSet1.setParseQuotedStrings(boxPanel.isQuoteSelected());
		  return fileSet1;
	  }
}


