/*
 Tiamat - a role-playing game framework
 ThemeEditorFrame.java - main window for editing a Theme
 
 Copyright  (C) 2005 Hugues Johnson
 
 This program is free software; you can redistribute it and/or
 modify it under the terms of the GNU General Public License
 as published by the Free Software Foundation; either version 2
 of the License, or (at your option) any later version.
 
 This program is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
 the GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
 along with this program; if not, write to the Free Software
 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

package com.huguesjohnson.tiamat.tools;

import com.huguesjohnson.PathResolver;
import com.huguesjohnson.fileFilter.XmlFileFilter;
import com.huguesjohnson.serialization.XmlFormatter;
import com.huguesjohnson.tiamat.graphics.ColorScheme;
import com.huguesjohnson.tiamat.graphics.Theme;
import com.huguesjohnson.ui.FileBrowsePanel;
import com.huguesjohnson.ui.ImageBrowsePanel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingConstants;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;

/**
 * Main window for editing a Theme. Protected code segments were generated by the NetBeans 3.6 form editor.
 * @author Hugues Johnson
 */
public class ThemeEditorFrame extends BaseEditorFrame{
	/** Determines if a de-serialized file is compatible with this class. See <a href="http://java.sun.com/j2se/1.5.0/docs/guide/serialization/spec/class.html">Java Object Serialization Specifications</a>. */
	private static final long serialVersionUID=5216424199269326205L;

	// ui components
	private JButton buttonBackColor;
	private JButton buttonBorderColor;
	private JButton buttonBorderInsetColor;
	private JButton buttonForeColor;
	private ButtonGroup buttonGroupPreview;
	private JLabel labelBackColor;
	private JLabel labelBorderColor;
	private JLabel labelBorderInsetColor;
	private JLabel labelForeColor;
	private JLabel labelPreview1;
	private JPanel panelBorderColorBorderInsetColor;
	private JPanel panelColors;
	private JPanel panelColorsInner;
	private JPanel panelForeColorBackColor;
	private JPanel panelLeft;
	private JPanel panelMainContent;
	private JPanel panelPreview;
	private JPanel panelRadioButtonImage;
	private JPanel panelRadioButtonSelectedImage;
	private JPanel panelRight;
	private JPanel panelThemeFile;
	private JRadioButton radioButtonPreview1;
	private JRadioButton radioButtonPreview2;
	private JRadioButton radioButtonPreview3;

	// panel that holds the path to the Theme file
	FileBrowsePanel browsePanelTheme;
	// panel that holds the radio button image
	ImageBrowsePanel imagePanelRadioButton;
	// panel that holds the radio button selected image
	ImageBrowsePanel imagePanelRadioButtonSelected;

	/**
	 * Creates a new ThemeEditorFrame.
	 */
	public ThemeEditorFrame(){
		super("Theme");
		// draw the preview
		this.updatePreview();
	}

	/**
	 * Creates a new ThemeEditorFrame with the specified Theme.
	 * @param filePath The Theme file to open.
	 */
	public ThemeEditorFrame(String filePath){
		super("Theme");
		// load the Theme
		this.loadTheme(filePath);
	}

	@SuppressWarnings("serial")
	protected void initComponents(){
		this.buttonGroupPreview=new ButtonGroup();
		this.buttonForeColor=new JButton();
		this.labelBackColor=new JLabel();
		this.buttonBackColor=new JButton();
		this.panelBorderColorBorderInsetColor=new JPanel();
		this.labelBorderColor=new JLabel();
		this.buttonBorderColor=new JButton();
		this.labelBorderInsetColor=new JLabel();
		this.buttonBorderInsetColor=new JButton();
		this.panelRadioButtonImage=new JPanel();
		this.panelRadioButtonSelectedImage=new JPanel();
		this.panelRight=new JPanel();
		this.panelPreview=new JPanel();
		this.labelPreview1=new JLabel();
		this.radioButtonPreview1=new JRadioButton();
		this.radioButtonPreview2=new JRadioButton();
		this.radioButtonPreview3=new JRadioButton();

		this.panelMainContent=new JPanel();
		this.panelMainContent.setLayout(new BoxLayout(this.panelMainContent,BoxLayout.X_AXIS));

		this.panelLeft=new JPanel();
		this.panelLeft.setLayout(new BoxLayout(this.panelLeft,BoxLayout.Y_AXIS));

		this.panelThemeFile=new JPanel();
		this.panelThemeFile.setLayout(new GridLayout(1,0));
		this.panelLeft.add(this.panelThemeFile);

		this.panelColors=new javax.swing.JPanel();
		this.panelColors.setLayout(new BorderLayout());
		this.panelColors.setBorder(new TitledBorder("Colors"));
		this.panelColorsInner=new JPanel();
		this.panelColorsInner.setLayout(new BoxLayout(this.panelColorsInner,BoxLayout.Y_AXIS));

		this.panelForeColorBackColor=new JPanel();
		this.panelForeColorBackColor.setLayout(new FlowLayout(FlowLayout.LEFT));

		this.labelForeColor=new JLabel();
		this.labelForeColor.setHorizontalAlignment(SwingConstants.RIGHT);
		this.labelForeColor.setText("Foreground Color:");
		this.labelForeColor.setMaximumSize(new Dimension(120,15));
		this.labelForeColor.setMinimumSize(new Dimension(120,15));
		this.labelForeColor.setPreferredSize(new Dimension(120,15));
		this.panelForeColorBackColor.add(this.labelForeColor);

		this.buttonForeColor.setBackground(new Color(0,0,0));
		this.buttonForeColor.setMaximumSize(new Dimension(24,24));
		this.buttonForeColor.setMinimumSize(new Dimension(24,24));
		this.buttonForeColor.setPreferredSize(new Dimension(24,24));
		this.buttonForeColor.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent evt){
				buttonForeColorActionPerformed();
			}
		});

		this.panelForeColorBackColor.add(this.buttonForeColor);

		this.labelBackColor.setHorizontalAlignment(SwingConstants.RIGHT);
		this.labelBackColor.setText("Background Color:");
		this.labelBackColor.setMaximumSize(new Dimension(120,15));
		this.labelBackColor.setMinimumSize(new Dimension(120,15));
		this.labelBackColor.setPreferredSize(new Dimension(120,15));
		this.panelForeColorBackColor.add(this.labelBackColor);

		this.buttonBackColor.setBackground(new Color(255,255,255));
		this.buttonBackColor.setMaximumSize(new Dimension(24,24));
		this.buttonBackColor.setMinimumSize(new Dimension(24,24));
		this.buttonBackColor.setPreferredSize(new Dimension(24,24));
		this.buttonBackColor.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent evt){
				buttonBackColorActionPerformed();
			}
		});

		this.panelForeColorBackColor.add(this.buttonBackColor);

		this.panelColorsInner.add(this.panelForeColorBackColor);

		this.panelBorderColorBorderInsetColor.setLayout(new FlowLayout(java.awt.FlowLayout.LEFT));

		this.labelBorderColor.setHorizontalAlignment(SwingConstants.RIGHT);
		this.labelBorderColor.setText("Border Color:");
		this.labelBorderColor.setMaximumSize(new Dimension(120,15));
		this.labelBorderColor.setMinimumSize(new Dimension(120,15));
		this.labelBorderColor.setPreferredSize(new Dimension(120,15));
		this.panelBorderColorBorderInsetColor.add(this.labelBorderColor);

		this.buttonBorderColor.setBackground(new Color(255,255,255));
		this.buttonBorderColor.setMaximumSize(new Dimension(24,24));
		this.buttonBorderColor.setMinimumSize(new Dimension(24,24));
		this.buttonBorderColor.setPreferredSize(new Dimension(24,24));
		this.buttonBorderColor.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent evt){
				buttonBorderColorActionPerformed();
			}
		});

		this.panelBorderColorBorderInsetColor.add(this.buttonBorderColor);

		this.labelBorderInsetColor.setHorizontalAlignment(SwingConstants.RIGHT);
		this.labelBorderInsetColor.setText("Border Inset Color:");
		this.labelBorderInsetColor.setMaximumSize(new Dimension(120,15));
		this.labelBorderInsetColor.setMinimumSize(new Dimension(120,15));
		this.labelBorderInsetColor.setPreferredSize(new Dimension(120,15));
		this.panelBorderColorBorderInsetColor.add(this.labelBorderInsetColor);

		this.buttonBorderInsetColor.setBackground(new Color(0,0,0));
		this.buttonBorderInsetColor.setMaximumSize(new Dimension(24,24));
		this.buttonBorderInsetColor.setMinimumSize(new Dimension(24,24));
		this.buttonBorderInsetColor.setPreferredSize(new Dimension(24,24));
		this.buttonBorderInsetColor.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent evt){
				buttonBorderInsetColorActionPerformed();
			}
		});

		this.panelBorderColorBorderInsetColor.add(this.buttonBorderInsetColor);

		this.panelColorsInner.add(this.panelBorderColorBorderInsetColor);

		this.panelColors.add(this.panelColorsInner,BorderLayout.CENTER);

		this.panelLeft.add(this.panelColors);

		this.panelRadioButtonImage.setLayout(new GridLayout(1,0));

		this.panelLeft.add(this.panelRadioButtonImage);

		this.panelRadioButtonSelectedImage.setLayout(new GridLayout(1,0));

		this.panelLeft.add(this.panelRadioButtonSelectedImage);

		this.panelMainContent.add(this.panelLeft);

		this.panelRight.setLayout(new java.awt.GridLayout(1,0));

		this.panelPreview.setBorder(new TitledBorder("Preview"));
		this.panelContent.setLayout(new BoxLayout(this.panelContent,javax.swing.BoxLayout.Y_AXIS));

		this.labelPreview1.setText("Here is some text.");
		this.panelContent.add(this.labelPreview1);

		this.radioButtonPreview1.setSelected(true);
		this.radioButtonPreview1.setText("Preview radio button");
		this.buttonGroupPreview.add(this.radioButtonPreview1);
		this.panelContent.add(this.radioButtonPreview1);

		this.radioButtonPreview2.setText("Preview radio button");
		this.buttonGroupPreview.add(this.radioButtonPreview2);
		this.panelContent.add(this.radioButtonPreview2);

		this.radioButtonPreview3.setText("Preview radio button");
		this.buttonGroupPreview.add(this.radioButtonPreview3);
		this.panelContent.add(this.radioButtonPreview3);

		this.panelPreview.add(this.panelContent);

		this.panelRight.add(this.panelPreview);

		this.panelMainContent.add(this.panelRight);

		this.getContentPane().add(this.panelMainContent,BorderLayout.CENTER);

		this.browsePanelTheme=new FileBrowsePanel("Theme File",(new XmlFileFilter()),false);
		this.panelThemeFile.add(this.browsePanelTheme);
		this.imagePanelRadioButton=new ImageBrowsePanel("Radio Button Image"){
			public void onBrowseComplete(){
				updatePreview();
			}
		};
		this.panelRadioButtonImage.add(this.imagePanelRadioButton);
		this.imagePanelRadioButtonSelected=new ImageBrowsePanel("Radio Button Selected Image"){
			public void onBrowseComplete(){
				updatePreview();
			}
		};
		this.panelRadioButtonSelectedImage.add(this.imagePanelRadioButtonSelected);

		this.pack();

		// disable save by default
		this.disableSave();
	}

	protected void onViewXml(){
		String filePath="file:///"+this.browsePanelTheme.getFilePath();
		this.viewXml(filePath);
	}

	public void buttonBorderInsetColorActionPerformed(){
		this.browseColor(this.buttonBorderInsetColor);
	}

	public void buttonBorderColorActionPerformed(){
		this.browseColor(this.buttonBorderColor);
	}

	public void buttonBackColorActionPerformed(){
		this.browseColor(this.buttonBackColor);
	}

	public void buttonForeColorActionPerformed(){
		this.browseColor(this.buttonForeColor);
	}

	/**
	 * Browses for a color and paints the target component.
	 * @param targetComponent The component to paint with the selected color.
	 */
	private void browseColor(JComponent targetComponent){
		JColorChooser colorChooser=new JColorChooser();
		Color color=JColorChooser.showDialog(this,"Select a color",targetComponent.getBackground());
		if(color!=null){
			targetComponent.setBackground(color);
			this.updatePreview();
		}
	}

	/**
	 * Updates the preview section.
	 */
	public void updatePreview(){
		// draw the border
		LineBorder outerLineBorder=(LineBorder)BorderFactory.createLineBorder(this.buttonBorderColor.getBackground());
		LineBorder insetLineBorder=(LineBorder)BorderFactory.createLineBorder(this.buttonBorderInsetColor.getBackground());
		Border border=BorderFactory.createCompoundBorder(insetLineBorder,outerLineBorder);
		this.panelContent.setBorder(border);
		// paint components in the preview panel
		Color foreColor=this.buttonForeColor.getBackground();
		this.panelContent.setForeground(foreColor);
		Color backColor=this.buttonBackColor.getBackground();
		this.panelContent.setBackground(backColor);
		int componentCount=this.panelContent.getComponentCount();
		for(int index=0;index<componentCount;index++){
			Component component=this.panelContent.getComponent(index);
			component.setBackground(backColor);
			component.setForeground(foreColor);
		}
		// update the radio buttons
		BufferedImage radioButtonImage=this.imagePanelRadioButton.getImage();
		if(radioButtonImage!=null){
			ImageIcon imageIcon=new ImageIcon(radioButtonImage);
			this.radioButtonPreview1.setIcon(imageIcon);
			this.radioButtonPreview2.setIcon(imageIcon);
			this.radioButtonPreview3.setIcon(imageIcon);
		}
		BufferedImage radioButtonSelectedImage=this.imagePanelRadioButtonSelected.getImage();
		if(radioButtonSelectedImage!=null){
			ImageIcon imageIcon=new ImageIcon(radioButtonSelectedImage);
			this.radioButtonPreview1.setSelectedIcon(imageIcon);
			this.radioButtonPreview2.setSelectedIcon(imageIcon);
			this.radioButtonPreview3.setSelectedIcon(imageIcon);
		}
	}

	/**
	 * Resets everything to default values.
	 */
	protected void onNew(){
		// reset the radio button images
		this.imagePanelRadioButton.clear();
		this.imagePanelRadioButtonSelected.clear();
		this.radioButtonPreview1.setIcon(null);
		this.radioButtonPreview1.setSelectedIcon(null);
		this.radioButtonPreview2.setIcon(null);
		this.radioButtonPreview2.setSelectedIcon(null);
		this.radioButtonPreview3.setIcon(null);
		this.radioButtonPreview3.setSelectedIcon(null);
		// reset the colors
		this.buttonBackColor.setBackground(Color.WHITE);
		this.buttonBorderColor.setBackground(Color.BLACK);
		this.buttonBorderInsetColor.setBackground(Color.WHITE);
		this.buttonForeColor.setBackground(Color.BLACK);
		// reset the browse panel
		this.browsePanelTheme.clear();
		// disable buttons
		this.disableSave();
		// update the preview
		this.updatePreview();
	}

	protected void onSave(){
		String filePath=this.browsePanelTheme.getFilePath();
		// get the directory the file is being saved in
		String absoluteDir=this.browsePanelTheme.getDirectory();
		// get the colors
		ColorScheme colorScheme=new ColorScheme(this.buttonForeColor.getBackground(),this.buttonBackColor.getBackground(),this.buttonBorderColor.getBackground(),this.buttonBorderInsetColor.getBackground());
		// create the Theme
		Theme theme=new Theme();
		theme.setAbsoluteDir(absoluteDir);
		theme.setColorScheme(colorScheme);
		// get the images
		String imagePath=this.imagePanelRadioButton.getImagePath();
		if(imagePath!=null){
			String imagePathRelative=PathResolver.getRelativePath(absoluteDir,imagePath);
			theme.setRadioButtonImagePath(imagePathRelative);
		}
		imagePath=this.imagePanelRadioButtonSelected.getImagePath();
		if(imagePath!=null){
			String imagePathRelative=PathResolver.getRelativePath(absoluteDir,imagePath);
			theme.setRadioButtonSelectedImagePath(imagePathRelative);
		}
		// save the Theme
		XmlFormatter formatter=new XmlFormatter();
		try{
			formatter.saveTo(theme,filePath);
		} catch(Exception x){
			x.printStackTrace();
			JOptionPane.showMessageDialog(this,"Error saving theme:"+x.getMessage(),"Error",JOptionPane.ERROR_MESSAGE);
		}
	}

	protected void onOpen(){
		String filePath=new String(this.browsePanelTheme.getFilePath());
		if(this.browsePanelTheme.browse()){
			String newPath=new String(this.browsePanelTheme.getFilePath());
			if(filePath!=newPath){
				this.loadTheme(newPath);
				this.addRecentFile(newPath);
			}
		}
	}

	protected void onSaveAs(){
		if(this.browsePanelTheme.browse()){
			String filePath=new String(this.browsePanelTheme.getFilePath().toLowerCase());
			if(!filePath.endsWith(".theme.xml")){
				this.browsePanelTheme.setFilePath(filePath+".theme.xml");
			}
			this.onSave();
			this.enableSave();
			this.addRecentFile(filePath);
		}
	}

	public void loadTheme(String filePath){
		// clear out everything
		this.onNew();
		XmlFormatter formatter=new XmlFormatter();
		try{
			Theme theme=(Theme)formatter.loadFrom(filePath);
			// set the colors
			ColorScheme colorScheme=theme.getColorScheme();
			this.buttonBackColor.setBackground(colorScheme.getBackColor());
			this.buttonBorderColor.setBackground(colorScheme.getBorderColor());
			this.buttonBorderInsetColor.setBackground(colorScheme.getBorderInsetColor());
			this.buttonForeColor.setBackground(colorScheme.getForeColor());
			// set the radio button images
			String imagePath=theme.getRadioButtonImagePathAbsolute();
			if(imagePath!=null){
				this.imagePanelRadioButton.setImage(imagePath);
			}
			imagePath=theme.getRadioButtonSelectedImagePathAbsolute();
			if(imagePath!=null){
				this.imagePanelRadioButtonSelected.setImage(imagePath);
			}
			// enable save
			this.enableSave();
			// set the browse panel
			this.browsePanelTheme.setFilePath(filePath);
			// update the preview
			this.updatePreview();
		} catch(Exception x){
			x.printStackTrace();
			JOptionPane.showMessageDialog(this,"Error loading theme:"+x.getMessage(),"Error",JOptionPane.ERROR_MESSAGE);
		}
	}
	
	protected void onRecentFile(String filePath){
		this.loadTheme(filePath);
	}

	public static void main(String args[]){
		try{
			(new ThemeEditorFrame()).setVisible(true);
		} catch(Exception x){
			x.printStackTrace();			
		}
	}
}