import java.awt.Dimension;
import java.awt.GridLayout;

import javax.swing.ImageIcon;
import javax.swing.JPanel;


/**
 * This adds the options under the tools (like the line thickness)
 *
 * @author Jared Mathis.
 *         Created Apr 14, 2008.
 */
public class ToolOptions extends JPanel{
	
	/**
	 * The paint this belongs to.  Instead of having each tool button know its own paint, we just
	 * had them know the tool options that created it and have them access paint through that, which
	 * is why this is protected.
	 */
	protected Paint paint;

	/**
	 * The status of the OptionButtons contained in this ToolOptions.  For possible values, see
	 * possible statuses below.
	 */
	protected int status;
	
	private static int MAX_NUMBER_OF_OPTIONS = 4;
	
	
	
	// Tool Sizes
	/**
	 * Has an area of one pixel.  Used by drawSpace, which is why it is protected.
	 */
	protected static int SIZE_1 = 0;
	
	/**
	 * Has an area of four pixels.  Used by drawSpace, which is why it is protected.
	 */
	protected static int SIZE_2 = 1;
	
	/**
	 * Has an area of nine pixels.  Used by drawSpace, which is why it is protected.
	 */
	protected static int SIZE_3 = 2;

	/**
	 * Has an area of 21 pixels.  Used by drawSpace, which is why it is protected.
	 */
	protected static int SIZE_4 = 3;
	
	
	
	// Tool Styles
	/**
	 * Used by drawSpace when you want to just draw the outline of a shape.
	 */
	protected static int STYLE_EDGE = 0;
	
	/**
	 * Used by drawSpace when you want to fill in  a shape.
	 */
	protected static int STYLE_SOLID = 1;
	
	
	
	// Possible Statuses
	/**
	 * Used by the ToolButton's to figure out if they should be enabled or disabled.
	 */
	protected static int DISABLED = 0;
	private static int ENABLED = 1;
	/**
	 * Used by the OptionButton to figure out which id to set to either currentToolSize or currentToolStyle,
	 * which is why it's protected.
	 */
	protected static int SIZES = 2;
	/**
	 * Protected for same reason as above.  There are two possible styles, see above.  Not used by all tools.
	 */
	protected static int STYLES = 3;
	
	private static String[] SIZE_DEFAULT_ICONS = {
		"size1", 
		"size2",
		"size3",
		"size4",
	};
	
	private static String[] STYLES_DEFAULT_ICONS = {
		"edge", 
		"solid",
	};
	
	private static Dimension PREFERRED_SIZE = new Dimension(
			OptionButton.BUTTON_WIDTH,
			OptionButton.BUTTON_HEIGHT * MAX_NUMBER_OF_OPTIONS);


	/**
	 * Constructs a ToolOptions for a ToolPanel.
	 *
	 * @param paint  The paint to which this ToolOptions belongs to.
	 */
	ToolOptions(Paint paint) {
		super(new GridLayout(MAX_NUMBER_OF_OPTIONS, 1));
		
		this.paint = paint;
		
		for (int i = 0; i < MAX_NUMBER_OF_OPTIONS; i++) this.add(new OptionButton(i, this));
		
		this.setPreferredSize(PREFERRED_SIZE);
		this.setOptionsTo(DISABLED);
		
	}

	/**
	 * This method changes the state of all of the tool options.  It is protected so that when a tool button is clicked, 
	 * said tool button may turn them on/off or change them to suit the tool, etc.
	 *
	 * @param status New Status (int constant)
	 */
	protected void setOptionsTo(int status) {
		this.status = status;
		if (this.status == DISABLED) this.disableOptions();
		else if (this.status == ENABLED) this.enableOptions();
		else if (this.status == SIZES) this.setOptionsToSizes();
		else if (this.status == STYLES) this.setOptionsToStyles();
	}

	private void setOptionsToStyles() {
		this.enableOptions();
		
		for (int i = 0; i < STYLES_DEFAULT_ICONS.length; i++) {			
			if (!(this.getComponent(i) instanceof OptionButton)) break;
			OptionButton button = (OptionButton)(this.getComponent(i));
			
			button.defaultIcon = new ImageIcon("images/" + STYLES_DEFAULT_ICONS[i] + ".gif");
			button.selectedIcon = new ImageIcon("images/" + STYLES_DEFAULT_ICONS[i] + "2.gif");
			if (button.id == this.paint.currentToolStyle) button.select();
			else button.deselect();
		}
		
		for (int i = STYLES_DEFAULT_ICONS.length; i < MAX_NUMBER_OF_OPTIONS; i++ ) {
			OptionButton button = (OptionButton)(this.getComponent(i));
			button.setVisible(false);
			button.setEnabled(false);
		}
		
	}

	private void setOptionsToSizes() {
		this.enableOptions();
		
		for (int i = 0; i < SIZE_DEFAULT_ICONS.length; i++) {			
			if (!(this.getComponent(i) instanceof OptionButton)) break;
			
			OptionButton button = (OptionButton)(this.getComponent(i));
			button.defaultIcon = new ImageIcon("images/" + SIZE_DEFAULT_ICONS[i] + ".gif");
			button.selectedIcon = new ImageIcon("images/" + SIZE_DEFAULT_ICONS[i] + "2.gif");
			if (button.id == this.paint.currentToolSize) button.select();
			else button.deselect();
		}
	}

	private void enableOptions() {
		for (int i = 0; i < MAX_NUMBER_OF_OPTIONS; i++) {
			if (!(this.getComponent(i) instanceof OptionButton)) break;
			
			OptionButton button = (OptionButton)(this.getComponent(i));
			button.setVisible(true);
			button.setEnabled(true);
		}
	}

	private void disableOptions() {
		for (int i = 0; i < MAX_NUMBER_OF_OPTIONS; i++) {
			if (!(this.getComponent(i) instanceof OptionButton)) break;
			
			OptionButton button = (OptionButton)(this.getComponent(i));
			button.setVisible(false);
			button.setEnabled(false);
		}
	}

	/**
	 * Deselects all OptionButtons.  Used by OptionButton so that it can turn off all selected OptionButtons,
	 * and then select itself, instead of trying to figure out which one is selected and turning off that one.
	 */
	protected void deselectAllOptions() {
		for (int i = 0; i < MAX_NUMBER_OF_OPTIONS; i++) {
			if (!(this.getComponent(i) instanceof OptionButton)) break;
			
			OptionButton button = (OptionButton)(this.getComponent(i));
			button.deselect();
		}	
	}
	
}
