/* BEGIN_HEADER                                              Java TreeView
 *
 * $Author: alokito $
 * $RCSfile: FUOptionsPanel.java,v $
 * $Revision: 1.2 $B
 * $Date: 2008-03-09 21:06:34 $
 * $Name:  $
 *
 * 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.plugin.dendroview;

import edu.stanford.genetics.treeview.*;

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

/**
 * This class allows selection of Font and Url options.
 *
 * It requires a FontSelectable, a UrlExtractor, and optionally a UrlPresets
 */
public class FUOptionsPanel extends JPanel implements SettingsPanel {
	private FontSelectable fontSelectable;
	private UrlExtractor urlExtractor;
	private UrlPresets urlPresets = null;
	private UrlPanel urlPanel = null;
	private HeaderInfo headerInfo;
	private JFrame top;
	private JDialog d;
	private Window window;
	private JPanel innerPanel; // seems to help with the tabbedpane, go figure...
	public FUOptionsPanel(FontSelectable fs, UrlExtractor ue, UrlPresets up, HeaderInfo hi) {
		fontSelectable = fs;
		urlExtractor = ue;
		urlPresets = up;
		headerInfo = hi;
		innerPanel = new JPanel();
		add(innerPanel);
		setupWidgets();
	}
	public String getTitle() {return "Font and Url Options";}
	public static void main(String [] argv) {
		UrlPresets p = new UrlPresets(new DummyConfigNode("UrlPresets"));
		HeaderInfo hi = new DummyHeaderInfo();
		UrlExtractor ue = new UrlExtractor(hi);
		FontSelectable fs = new TextView(hi, ue);
		fs.setPoints(10);
		FUOptionsPanel e  = new FUOptionsPanel(fs, ue, p, hi);
		Frame f = new Frame(e.getTitle());
		f.add(e);
		f.addWindowListener(new WindowAdapter (){
			public void windowClosing(WindowEvent we)
			{System.exit(0);}
		});
		f.pack();
		f.setVisible(true);
	}

	public void synchronizeFrom() {
		setupWidgets();
	}

	public void synchronizeTo() {
		//nothing to do...
	}
	private void setupWidgets() {
		innerPanel.removeAll();
		GridBagLayout gbl  = new GridBagLayout();
//		  setBackground(Color.red);
		innerPanel.setLayout(gbl);
		GridBagConstraints gbc  = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		innerPanel.add(Box.createVerticalStrut(10), gbc);
		gbc.gridy = 1;
		gbc.gridwidth = 1;
		gbc.insets = new Insets(5,5,5,5);
		gbc.fill = GridBagConstraints.BOTH;
		gbc.anchor = GridBagConstraints.NORTHEAST;
		innerPanel.add(new JLabel ("Font:", JLabel.LEFT), gbc);

		gbc.gridy = 2;
		gbc.gridx = 0;
		innerPanel.add(Box.createVerticalStrut(20), gbc);

		gbc.gridy = 3;
		EnablePanel enablePanel = new EnablePanel();
		// should make panel which includes enable checkbox...
		innerPanel.add(enablePanel, gbc);

		gbc.gridy = 1;
		gbc.gridx = 1;
		innerPanel.add(new FontSettingsPanel(fontSelectable), gbc);

		gbc.gridy = 3;
		gbc.weightx= 100;
		gbc.weighty= 100;
		urlPanel =new UrlPanel(urlExtractor, urlPresets, headerInfo);
		urlPanel.setEnabled(urlExtractor.isEnabled());
		innerPanel.add(urlPanel, gbc);
	}
	class EnablePanel extends JPanel {
		ModeChoice modeChoice;
		EnablePanel() {
			setLayout(new BorderLayout());
			add(new JLabel ("Web Link:", JLabel.LEFT), BorderLayout.NORTH);
			modeChoice = new ModeChoice();
			add(modeChoice, BorderLayout.CENTER);

		}
	}

	private class ModeChoice extends JComboBox implements ItemListener {
		final private UrlExtractor.UrlExtractorMode[] modes;
		ModeChoice() {
			super();
			modes = UrlExtractor.UrlExtractorMode.values();
			for (int i = 0; i < modes.length; i++) {
				addItem(modes[i].toString());
			}
			setSelectedItem(urlExtractor.getUrlExtractorMode().toString());
			addItemListener(this);
		}
		public void itemStateChanged(ItemEvent e) {
			UrlExtractor.UrlExtractorMode mode = modes[this.getSelectedIndex()];
			urlExtractor.setUrlExtractorMode(mode);
			urlPanel.setEnabled(urlExtractor.isEnabled());
			urlPanel.updatePreview();
		}
	}


	/**
	 *  Create a toplevel frame with this component in it
	 */
	public void makeTop() {
		top = new JFrame(getTitle());
		top.add(this);
		top.addWindowListener(
				new WindowAdapter() {
					public void windowClosing(WindowEvent we) {
						we.getWindow().dispose();
					}
				});
		top.pack();
		top.setVisible(true);
	}


	//
// the allowed font styles
//
	/**
	 *  Description of the Field
	 */
	public final static String[] styles  = {
			"Plain",
			"Italic",
			"Bold",
			"Bold Italic"
	};

	/**
	 * turn a style number from class java.awt.Font into a string
	 *
	 * @param  style  style index
	 * @return        string description
	 */
	public final static String decode_style(int style) {
		switch (style) {
			case Font.PLAIN:
				return styles[0];
			case Font.ITALIC:
				return styles[1];
			case Font.BOLD:
				return styles[2];
			default:
				return styles[3];
		}
	}

	/**
	 * turn a string into a style number
	 *
	 * @param  style  string description
	 * @return        integer encoded representation
	 */
	public final static int encode_style(String style) {
		return
				style == styles[0] ? Font.PLAIN :
						style == styles[1] ? Font.ITALIC :
								style == styles[2] ? Font.BOLD :
										Font.BOLD + Font.ITALIC;
	}

	/**
	 *  Create a blocking dialog containing this component
	 *
	 * @param  f  frame to block
	 */
	public void showDialog(Frame f, String title) {
		d = new JDialog(f, title);
		window = d;
		d.setLayout(new BorderLayout());
		d.add(this, BorderLayout.CENTER);
		d.add(new ButtonPanel(), BorderLayout.SOUTH);
		d.addWindowListener(
				new WindowAdapter() {
					public void windowClosing(WindowEvent we) {
						we.getWindow().dispose();
					}
				});
		d.pack();
		d.setVisible(true);
	}
	public void showDialog(Frame f) {
		showDialog(f, getTitle());
	}

	class UrlPanel extends JPanel {

		/**
		 * I don't use serialization, this is to keep eclipse happy.
		 */
		private static final long serialVersionUID = 1L;
		private UrlExtractor extractor;
		private UrlPresets presets;
		private HeaderInfo headerInfo;
		private String tester = "YAL039W";
		private JButton[] buttons;
		private JTextField previewField;
		private TemplateField templateField;
		private HeaderChoice headerChoice;


		public void setEnabled(boolean b) {
			templateField.setEnabled(b);
			headerChoice.setEnabled(b);
			previewField.setEnabled(b);
			for (int i = 0; i < buttons.length; i++) {
				if (buttons[i] != null)
					buttons[i].setEnabled(b);

			}
		}
		/**
		 * This class must be constructed around a HeaderInfo
		 */
		public UrlPanel(UrlExtractor ue, UrlPresets up, HeaderInfo hI) {
			super();
			extractor = ue;
			presets = up;
			headerInfo = hI;
			redoLayout();
			templateField.setText(extractor.getUrlTemplate());
			try {
				headerChoice.setSelectedIndex(extractor.getIndex());
			} catch(  java.lang.IllegalArgumentException e) {
			}
			updatePreview();
		}

		private GridBagConstraints gbc;
		public void redoLayout() {
			String [] preset;
			preset = presets.getPresetNames();
			int nPresets = preset.length;
			removeAll();
			setLayout(new GridBagLayout());
			gbc = new GridBagConstraints();
			gbc.gridwidth = 1;
			gbc.fill = GridBagConstraints.HORIZONTAL;
			gbc.anchor = GridBagConstraints.NORTH;
			gbc.gridy = 0;
			gbc.weightx = 100;
			templateField = new TemplateField();
			add(templateField, gbc);
			gbc.gridx  = 1;
			headerChoice  = new HeaderChoice();
			gbc.fill = GridBagConstraints.NONE;
			gbc.weightx = 0;
			add(headerChoice, gbc);
			gbc.gridx  = 0;
			gbc.gridy = 1;
			gbc.gridwidth = 2;
			gbc.fill = GridBagConstraints.HORIZONTAL;
			previewField = new JTextField(extractor.substitute(tester));
			previewField.setEditable(false);
			add(previewField, gbc);
			JPanel presetPanel = new JPanel();
			buttons = new JButton[nPresets];
			for (int i = 0; i < nPresets; i++) {
				JButton presetButton = new JButton((presets.getPresetNames()) [i]);
				final int index = i;
				presetButton.addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						templateField.setText(presets.getTemplate(index));
						updatePreview();
					}
				});
				presetPanel.add(presetButton);
				buttons[index] = presetButton;
			}
			gbc.gridy = 2;
			gbc.fill = GridBagConstraints.BOTH;
			gbc.weighty = 100;
			gbc.weightx = 100;
//		  add(new JScrollPane(presetPanel, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS), gbc);
			add(presetPanel, gbc);
		}

		private void updatePreview() {
			extractor.setUrlTemplate(templateField.getText());
			extractor.setIndex(headerChoice.getSelectedIndex());
			previewField.setText("Ex: " + extractor.getUrl(0));
		}



		private class HeaderChoice extends JComboBox implements ItemListener {
			HeaderChoice() {
				super();
				String [] headers;
				int lastI;
				if (headerInfo != null) {
					headers = headerInfo.getNames();
					lastI = headers.length;
					if (headerInfo.getIndex("GWEIGHT") != -1) {
						lastI--;
					}
				} else {
					headers = new String [] {"Dummy1", "Dummy2", "Dummy3"};
					lastI = headers.length;
				}

				for (int i = 0; i < lastI; i++) {
					if (headers[i] == null) {
						addItem("-- NULL --");
					} else {
						addItem(headers[i]);
					}
				}
				addItemListener(this);
			}
			public void itemStateChanged(ItemEvent e) {
				updatePreview();
			}
		}



		private class TemplateField extends JTextField {
			TemplateField () {
				super("enter url template");
				addActionListener(new ActionListener() {
					public void actionPerformed(ActionEvent e) {
						updatePreview();
					}
				});
			}
		}
		/*
		private void addPreset(int i) {
		  final int index = i;
		  gbc.gridx = 0;
		  add(new JLabel((presets.getPresetNames()) [index]), gbc);
		  gbc.gridx = 1;
		  gbc.weightx = 100;
		  add(new JTextField(presets.getTemplate(index)), gbc);
		  gbc.gridx = 2;
		  gbc.weightx = 0;
		  JButton set = new JButton("Set");
		  set.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
			  templateField.setText(presets.getTemplate(index));
			  updatePreview();
			}
		  });
		  add(set, gbc);
		}
		*/
	}


	class FontPanel extends JPanel {

		private String[] fonts               = FontSelector.fonts;
	/*
	 *  {
	 *  "Courier",
	 *  "Default",
	 *  "Dialog",
	 *  "DialogInput",
	 *  "Helvetica",
	 *  "TimesRoman",
	 *  "ZapfDingbats"
	 *  };
	 */

		private JComboBox font_choice;
		private JComboBox style_choice;
		private NatField size_field;
		private JButton display_button;
		private FontSelectable client;
		private JLabel exampleField;

		String size_prop, face_prop, style_prop;



		FontPanel(FontSelectable client) {
			this.client = client;
			setupWidgets();
			updateExample();

		}

		private void setupFontChoice() {
			font_choice = new JComboBox(fonts);
			font_choice.setSelectedItem(client.getFace());
		}
		private void setupStyleChoice() {
			style_choice = new JComboBox(styles);
			style_choice.setSelectedItem(decode_style(client.getStyle()));
		}

		private void synchronizeClient() {
			String string  = (String) font_choice.getSelectedItem();
			int i          = encode_style((String) style_choice.getSelectedItem());
			int size       = size_field.getNat();
			client.setFace(string);
			client.setStyle(i);
			client.setPoints(size);
		}
		/**
		 *  Sets up widgets
		 */
		private void setupWidgets() {
			GridBagLayout gbl  = new GridBagLayout();
			setLayout(gbl);
			GridBagConstraints gbc  = new GridBagConstraints();
			gbc.gridx = 0;
			gbc.gridy = 0;
			gbc.gridwidth = 1;
			gbc.fill = GridBagConstraints.HORIZONTAL;

			setupFontChoice();
			add(font_choice, gbc);

			setupStyleChoice();
			gbc.gridx = 1;
			add(style_choice, gbc);

			size_field = new NatField(client.getPoints(), 3);
			gbc.gridx = 2;
			add(size_field, gbc);

			display_button = new JButton("Display");
			display_button.addActionListener(
					new ActionListener() {

						public void actionPerformed(ActionEvent actionEvent) {
							updateExample();
							synchronizeClient();
						}
					});
			gbc.gridx = 3;
			add(display_button, gbc);
			gbc.gridx = 0;
			gbc.gridy = 1;
			gbc.gridwidth = 3;
			gbc.fill = GridBagConstraints.BOTH;
			exampleField = new JLabel("Example Text", JLabel.CENTER);
			add(exampleField, gbc);
		}

		private void updateExample() {
			String string  = (String)font_choice.getSelectedItem();
			int i          = encode_style((String)style_choice.getSelectedItem());
			int size       = size_field.getNat();
//				System.out.println("Setting size to " + size);
			exampleField.setFont(new Font(string, i, size) );
			exampleField.revalidate();
			exampleField.repaint();
		}
	}


	private class ButtonPanel extends JPanel {
		ButtonPanel() {
			JButton save_button = new JButton("Close");
			save_button.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					window.setVisible(false);
				}
			});
			add(save_button);

		}
	}
}
