/*
 * @(#)KeySettings.java
 *
 * Last Modified: 9/01/02
 */

 import java.util.*;
 import java.lang.*;
 import java.awt.*;
 import java.awt.font.*;


/** * The class provides an object that refers to the settings of a <code>DrawableKey</code>.
 	* Many static variables are available for use as defaults and different settings. Additionally,
 	* a static method <code>getScheme</code> becomes very useful in acquiring the object with a
 	* given color scheme.
 	*
 	* <p> The class implements cloneable, making copies of the object possible. The copies are shallow copies
 	* which means changes to the specific elements could be dangerous when numerous instances refer
 	* to the same elements. For example, modifying the rule of the given AlphaComposite, modifies the rule
 	* for all <code>KeySettings</code> that refer to that AlphaComposite. Therefore, it is suggested
 	* that no modifications to the specific elements be made. Instead, simply use a different element.
 	*
 	* @see DrawableKey
 	* @see NodeSettings
 	*
 	* @author  Corey Sanders
	* @version 3.0 9/01/02
 	*/
 public class KeySettings extends Object implements Cloneable {

	/********************/
	/* Static variables */
	/********************/


	/**
	* Default <code>Stroke</code> for Key Drawing (BasicStroke(.05)).
	*/
 	final public static BasicStroke keyDefaultStroke = new BasicStroke(.05f);

	/**
	* Default <code>Paint</code> for Key Stroke (Color.black).
	*/
	final public static Color keyOutlineDefaultColor = Color.black;

	/**
	* Default <code>Paint</code> for Key Fill (PaintSettings.lightWhite).
	*/
	final public static Color keyDefaultColor = PaintSettings.lightWhite;

	/**
	* Default <code>AlphaComposite</code> rule for Key Drawing (SRC_OVER).
	*/
	final public static int keyRuleDefault = AlphaComposite.SRC_OVER;

	/**
	* Default alpha for Key Drawing (1.0).
	*/
	final public static float keyAlphaDefault = 1.0F;

	/**
	* Default alpha for Key Animating (.8).
	*/
	final public static float keyAlphaAnimateDefault = .8F;

	/**
	* Default <code>Font</code> for Key Drawing (Serif, Font.PLAIN).
	*/
	final public static Font fontDefault = new Font("Serif", Font.PLAIN, 10);

	/**
	 * Default <code>Composite</code> for key drawing (AlphaComposite(keyRuleDefault, keyAlphaDefault)).
	 */
	final public static AlphaComposite keyCompositeDefault = AlphaComposite.getInstance(keyRuleDefault, keyAlphaDefault);

	/**
	 * Default <code>Composite</code> for key animating (AlphaComposite(keyRuleDefault, keyAlphaAnimateDefault)).
	 */
	final public static AlphaComposite keyCompositeAnimateDefault = AlphaComposite.getInstance(keyRuleDefault, keyAlphaAnimateDefault);

	/**
	 * Default color scheme. (Uses the defaults of above).
	 */
	final public static String DEFAULT_SCHEME = "Default";

	/**
	 * Old Default color scheme.
	 */
	final public static String DEFAULT_SCHEME_2 = "Default 2";

	/**
	 * Erasing color scheme. (Background color and larger stroke widths).
	 */
	final public static String ERASE = "Erase";


	/**
	 * Black color scheme.
	 */
	final public static String BLACK_SCHEME = "Black";

	/**
	 * Ghost color scheme.
	 */
	final public static String GHOST_SCHEME = "Ghost";

	/**
	 * White color scheme.
	 */
	final public static String WHITE_SCHEME = "White";

	/**
	 * Princeton color scheme.
	 */
	final public static String CHRISTMAS_SCHEME = "Christmas";


	/**
	 * Default animating color scheme. (Uses the defaults of above).
	 */
	final public static String ANIMATOR_SCHEME_1 = "Animator 1";

	/**
	 * Animator Scheme 2.
	 */
	final public static String ANIMATOR_SCHEME_2 = "Animator 2";
	/**
	 * Animator Scheme 3.
	 */
	final public static String ANIMATOR_SCHEME_3 = "Animator 3";
	/**
	 * Animator Scheme 4.
	 */
	final public static String ANIMATOR_SCHEME_4 = "Animator 4";


	/**
	 * String used in <code>getSettingName</code> to define an undefined settings.
	 */
	final public static String original = "Original";

	/**************/
	/* Variables  */
	/**************/

	/**
	 * String defining the type of NodeSettings the current node is.
	 */
	private String settingName = original;

	/**
	 * Font for key drawing
	 */
 	private Font font = fontDefault;

	/**
	 * Fill paint of the key.
	 */
	private Paint keyFillPaint = keyDefaultColor;

	/**
	 * Outline Stroke of the key.
	 */
	private Stroke keyOutlineStroke = keyDefaultStroke;

	/**
	 * Outline Stroke width of the key.
	 */
	private float keyOutlineStrokeWidth = keyDefaultStroke.getLineWidth();

	/**
	 * Outline Paint of the key.
	 */
	private Paint keyOutlinePaint = keyOutlineDefaultColor;

	/**
	 * Composite for key drawing.
     */
	private Composite keyComposite = keyCompositeDefault;


	/***************/
	/* Constructor */
	/***************/

	/**
	 * Constructor, contructs a default defined <code>KeySettings</code>.
	 */
	public KeySettings() {
		this.setScheme(DEFAULT_SCHEME);

	}

	/**
	 * Constructor, contructs a defined <code>KeySettings</code> with the given scheme.
	 *
	 * @param int scheme, defining the scheme of this KeySettings.
	 */
	public KeySettings(String scheme) {
		this.setScheme(scheme);

	}

	/*******************/
	/* Static Methods  */
	/*******************/

	/**
	 * Gets a <code>KeySettings</code> that defines the given int scheme. The scheme must be one
	 * defined within the class, otherwise the default scheme is returned.
	 *
	 * @param s defined color scheme within the class.
	 *
	 * @return <code>KeySettings</code> that defines the given color scheme or default if no
	 * color scheme exists.
	 */
	public static KeySettings getScheme(String s) {
		KeySettings settings = new KeySettings();
		settings.setScheme(s);
		return settings;
	}

	/**
	 * Gets an array of String elements representing every NodeSettings choice available.
	 */
	 public static String[] getList() {
		String[] list = {DEFAULT_SCHEME, DEFAULT_SCHEME_2, BLACK_SCHEME, WHITE_SCHEME, GHOST_SCHEME, CHRISTMAS_SCHEME, ERASE, ANIMATOR_SCHEME_1,ANIMATOR_SCHEME_2,ANIMATOR_SCHEME_3, ANIMATOR_SCHEME_4};

		return list;

	}


	/************/
	/* Methods  */
	/************/



	/**
	 * Gets the string name for the current settings.
	 *
	 * @return String defining the settings name.
	 */
	 public String getSettingName() {
		 return settingName;
	 }

	/**
	 * Sets the string name for the current settings.
	 *
	 * @param settingName String defining the settings name.
	 */
	 public void setSettingName(String settingName) {
		 this.settingName = settingName;
	 }

	/**
	 * Sets the scheme of the settings, using Color.white as the default background color, if
	 * the background color is indeed needed.
	 *
	 * @param s defined color scheme within the class.
	 */
	public void setScheme(String s) {
		// Call to method.
		setScheme(s, Color.white);
	}

	/**
	 * Sets the scheme of the settings, using the background color if needed.
	 *
	 * @param s defined color scheme within the class.
	 * @param background background color if needed.
	 */
	public void setScheme(String s, Color background) {
		setSettingName(s);

		// Drawing Schemes
		if (s.equals(DEFAULT_SCHEME)) {
			setFont(new Font("Times", Font.PLAIN, 10));
			setKeyFillPaint(PaintSettings.lightWhite);
			setKeyOutlineStroke(new BasicStroke(.05f));
			setKeyOutlinePaint(PaintSettings.lighterGray);
			setKeyComposite(keyCompositeDefault);
		}
		if (s.equals(DEFAULT_SCHEME_2)) {
			setFont(new Font("Serif", Font.PLAIN, 10));
			setKeyFillPaint(PaintSettings.lightWhite);
			setKeyOutlineStroke(new BasicStroke(.05f));
			setKeyOutlinePaint(keyOutlineDefaultColor);
			setKeyComposite(keyCompositeDefault);
		}
		if (s.equals(WHITE_SCHEME)) {
			setFont(new Font("Serif", Font.PLAIN, 10));
			setKeyFillPaint(PaintSettings.lightWhite);
			setKeyOutlineStroke(new BasicStroke(.05f));
			setKeyOutlinePaint(PaintSettings.lighterGray);
			setKeyComposite(keyCompositeDefault);
		}

		if (s.equals(BLACK_SCHEME)) {
			setFont(new Font("Serif", Font.PLAIN, 10));
			setKeyFillPaint(Color.black);
			setKeyOutlineStroke(new BasicStroke(.05f));
			setKeyOutlinePaint(Color.darkGray);
			setKeyComposite(keyCompositeDefault);
		}
		if (s.equals(CHRISTMAS_SCHEME)) {
			setFont(new Font("Serif", Font.PLAIN, 10));
			setKeyFillPaint(Color.green);
			setKeyOutlineStroke(new BasicStroke(1f));
			setKeyOutlinePaint(Color.red);
			setKeyComposite(keyCompositeDefault);
		}
		if (s.equals(GHOST_SCHEME)) {
			setFont(new Font("Serif", Font.PLAIN, 10));
			setKeyFillPaint(PaintSettings.ghostlyGray);
			setKeyOutlineStroke(new BasicStroke(.05f));
			setKeyOutlinePaint(PaintSettings.lightWhite);
			setKeyComposite(keyCompositeAnimateDefault);
		}

		if (s.equals(ERASE)) {
			setKeyOutlineStroke(new BasicStroke(3f));
			setKeyFillPaint(background);
			setKeyOutlinePaint(background);
			setKeyComposite(keyCompositeDefault);
		}


		// Animating Schemes
		if (s.equals(ANIMATOR_SCHEME_1)) {
			setFont(new Font("Times", Font.PLAIN, 10));
			setKeyFillPaint(Color.white);
			setKeyOutlineStroke(new BasicStroke(.05f));
			setKeyOutlinePaint(Color.white);
			setKeyComposite(keyCompositeAnimateDefault);
		}
		if (s.equals(ANIMATOR_SCHEME_2)) {
			setFont(new Font("Times", Font.PLAIN, 10));
			setKeyFillPaint(PaintSettings.aqua);
			setKeyOutlineStroke(new BasicStroke(.05f));
			setKeyOutlinePaint(Color.blue);
			setKeyComposite(keyCompositeAnimateDefault);
		}
		if (s.equals(ANIMATOR_SCHEME_3)) {
			setFont(new Font("Times", Font.PLAIN, 10));
			setKeyFillPaint(Color.green);
			setKeyOutlineStroke(new BasicStroke(.5f));
			setKeyOutlinePaint(PaintSettings.grayGreen);
			setKeyComposite(keyCompositeAnimateDefault);
		}
		if (s.equals(ANIMATOR_SCHEME_4)) {
			setFont(new Font("Times", Font.PLAIN, 10));
			setKeyFillPaint(Color.orange);
			setKeyOutlineStroke(new BasicStroke(.05f));
			setKeyOutlinePaint(Color.white);
			setKeyComposite(keyCompositeAnimateDefault);
		}

	}


 	/**
     * Returns a copy of this <code>AffineTransform</code> object.
     * @return an <code>Object</code> that is a copy of this
     * <code>AffineTransform</code> object.
     */
    public Object clone() {

		try {
		    return super.clone();
		}
		catch (CloneNotSupportedException e) {
		    // this shouldn't happen, since we are Cloneable
		    throw new InternalError();
		}
    }

	/**
	 * Sets the settings of just the key of the KeySettings, using the KeySettings passed.
	 *
	 * @param s KeySettings to which the node settings are set.
	 */
	public void setAllSettings(KeySettings s) {
		setFont(s.getFont());
		setKeyFillPaint(s.getKeyFillPaint());
		setKeyOutlineStroke(s.getKeyOutlineStroke(), s.getKeyOutlineStrokeWidth());
		setKeyOutlinePaint(s.getKeyOutlinePaint());
		setKeyComposite(s.getKeyComposite());
	}

	/**********************/
	/* Mutator Methods    */
	/**********************/


	/**
	 * Sets the <code>Font</code> used for drawing the key.
	 * @param f <code>Font</code> used for drawing.
	 */
	public void setFont(Font f) {
		font = f;
	}

	/**
	 * Sets the paint for filling the key.
	 *
	 * @param p <code>Paint</code> for filling the key.
	 */
	public void setKeyFillPaint(Paint p) {
		keyFillPaint = p;
	}

	/**
	 * Sets the stroke for the key.
	 *
	 * @param s <code>Stroke</code> that sets the key stroke.
	 * @param w Width of the <code>Stroke</code> for drawing corrections.
	 */
	public void setKeyOutlineStroke(Stroke s, float w) {
		keyOutlineStroke = s;
		keyOutlineStrokeWidth = w;
	}

	/**
	 * Sets the key stroke. No width is necessary, becuase
	 * BasicStroke defines a <code>getLineWidth</code> method.
	 *
	 * @param s <code>BasicStroke</code> for drawing the key.
	 */
	public void setKeyOutlineStroke(BasicStroke s) {
		keyOutlineStroke = s;
		keyOutlineStrokeWidth = s.getLineWidth();
	}

	/**
	 * Sets the paint for the outline of the key.
	 *
	 * @param p <code>Paint</code> for drawing the outline of the key.
	 */
	public void setKeyOutlinePaint(Paint p) {
		keyOutlinePaint = p;
	}

	/**
	 * Sets the key composite. Generally an AlphaComposite is used.
	 *
	 * @param c <code>Composite</code> for drawing the key.
	 */
	public void setKeyComposite(Composite c) {
		keyComposite = c;
	}



	/**********************/
	/* Accessor Methods   */
	/**********************/

	/**
	 * Gets the <code>Font</code> used for drawing the key.
	 * @return <code>Font</code> used for drawing.
	 */
	public Font getFont() {
		return font;
	}

	/**
	 * Gets the key fill paint.
	 *
	 * @return fill <code>Paint</code> of the key.
	 */
	public Paint getKeyFillPaint() {
		return keyFillPaint;
	}

	/**
	 * Gets the outline stroke of the key.
	 *
	 * @return <code>Stroke</code> outline of the key.
	 */
	public Stroke getKeyOutlineStroke() {
		return keyOutlineStroke;
	}

	/**
	 * Gets the outline stroke width of the key.
	 *
	 * @return width of the outline of the key.
	 */
	public float getKeyOutlineStrokeWidth() {
		return keyOutlineStrokeWidth;
	}

	/**
	 * Gets the key outline paint.
	 *
	 * @return outline <code>Paint</code> of the key.
	 */
	public Paint getKeyOutlinePaint() {
		return keyOutlinePaint;
	}

	/**
	 * Gets the key composite.
	 *
	 * @return <code>Composite</code> of the key.
	 */
	public Composite getKeyComposite() {
		return keyComposite;
	}




}
