/*
 *  JFLAP - Formal Languages and Automata Package
 * 
 * 
 *  Susan H. Rodger
 *  Computer Science Department
 *  Duke University
 *  August 27, 2009

 *  Copyright (c) 2002-2009
 *  All rights reserved.

 *  JFLAP is open source software. Please see the LICENSE for terms.
 *
 */





package automata;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.StringTokenizer;

import automata.event.AutomataStateEvent;

/**
 * This class represents a single state in an automaton. This class is intended
 * to act as nothing more than a simple placeholder.
 * 
 * @author Thomas Finley
 * @version 1.0
 */

public class State implements Serializable {
	/**
	 * Instantiates a new state.
	 * 
	 * @param id
	 *            the state id, used for generating
	 * @param automaton
	 *            the automaton this belongs to
	 */
	public State(int id, Automaton automaton) {
		this.id = id;
		this.automaton = automaton;
	}

	public void setAutomaton(Automaton auto) {
		this.automaton = auto;
	}

	/**
	 * Returns the automaton that this state belongs to.
	 * 
	 * @return the automaton that this state belongs to
	 */
	public Automaton getAutomaton() {
		return automaton;
	}	


	/**
	 * Returns the state ID for this state.
	 * 
	 * @return the ID of the state
	 */
	public int getID() {
		return id;
	}

	/**
	 * Sets the ID for this state.
	 * 
	 * @param id
	 *            the new ID for this state.
	 */
	protected void setID(int id) {
		if (("q" + this.id).equals(name))
			name = null;
		this.id = id;
		getAutomaton()
				.distributeStateEvent(
						new AutomataStateEvent(getAutomaton(), this, false,
								false, true));
	}


	/**
	 * Sets the name for this state. A parameter of <CODE>null</CODE> will
	 * reset this to the default.
	 * 
	 * @param name
	 *            the new name for the state
	 */
	public void setName(String name) {
		this.name = name;
		getAutomaton()
				.distributeStateEvent(
						new AutomataStateEvent(getAutomaton(), this, false,
								false, true));
	}

	/**
	 * Returns the simple "name" for this state. By default this will simply be
	 * "qd", where d is the ID number.
	 * 
	 * @return the name for this state
	 */
	public String getName() {
		if (name == null) {
			name = "q" + Integer.toString(getID());
		}
		return name;
	}

	private String digitizer(int number) {
		if (number == 0)
			return "\u2080";
		String s = digitizer(number / 10, 1);
		return s + (SS + (char) (number % 10));
	}

	private String digitizer(int number, int supp) {
		if (number == 0)
			return "";
		String s = digitizer(number / 10, 1);
		return s + (SS + (char) (number % 10));
	}

	/**
	 * Sets the "label" for a state, an optional description for the state.
	 * 
	 * @param label
	 *            the new descriptive label, or <CODE>null</CODE> if the user
	 *            wishes to specify that there is no label
	 */
	public void setLabel(String label) {
		this.label = label;
		if (label == null) {
			labels = new String[0];
		} else {
			StringTokenizer st = new StringTokenizer(label, "\n");
			ArrayList lines = new ArrayList();
			while (st.hasMoreTokens())
				lines.add(st.nextToken());
			labels = (String[]) lines.toArray(new String[0]);
		}
		getAutomaton()
				.distributeStateEvent(
						new AutomataStateEvent(getAutomaton(), this, false,
								false, true));
	}

	/**
	 * Returns the label for the state.
	 * 
	 * @return the descriptive label of the state, or <CODE>null</CODE> if
	 *         this state has no label
	 */
	public String getLabel() {
		return label;
	}

	/**
	 * Returns the label for the state, broken across newlines if there are
	 * newlines in it.
	 * 
	 * @return an array of all label elements, or an empty array if this state
	 *         has no labels
	 */
	public String[] getLabels() {
		return labels;
	}

	String internalName = null;

	/** The state ID. */
	int id;

	/** The name of the state. */
	String name = null;

	/** The subscript unicode start point. */
	private static final char SS = '\u2080';

	/** The automaton this state belongs to. */
	private Automaton automaton = null;

	/** The label for the state. */
	private String label;

	/** If there are multiple labels, return those. */
	private String[] labels = new String[0];
	
//	/** If the state has a parent block, this is it.  It is null if there is no parent block. */
//	private State parentBlock = null;
	
//	/** If it is the final state in the block, this is <CODE>true</CODE>*/
//	private boolean finalStateInBlock = false;
	
	private boolean selected = false;

	public void setSelect(boolean select) {
		selected = select;
	}
	
	public boolean isSelected(){
		return selected;
	}

}
