/***********************************************************************

GECCO, a platform for command and control gaming

Copyright (C) 2001 Henrik Bäärnhielm, Andreas Enblom, Niklas
Hallenfur, Karl Hasselström, Henrik Hägerström, Oskar Linde, Jing Fu
Zi and Jon Åslund

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 gecco.client;

/**
 *  An Action is a thing that a Piece can do. The Action has a name that is
 *  presented to the user and a type. The type is a String. <p>
 *
 *  Note that Actions are assumed to be used only with one Piece, that is if two
 *  pieces have the same action, they should have two different instances with
 *  the same properties, use method clone(). The type indentifies uniquely the
 *  type of action and not the instance. <p>
 *
 *  An Action is performed by a Piece and it can be done toward an object. An
 *  action therefore has a property called parameter type that represents the
 *  type of the thing the actions is perfomed to. The parameter types are void
 *  (nothing), position and piece. For information purposes every action can be
 *  given a parameter, but no checking that it is of the correct type is done.
 *  The parameter is initilized to null. <p>
 *
 *  Every action has instantaneous flag that indicates whether the action is an
 *  action that is performed immediately and that has no time span. Other
 *  actions are normally put in a queue and executed in order. <p>
 *
 *  Two actions are considered equals if their types are equal.
 *
 * @author     Andreas Enblom
 * @created    June 27, 2001
 */

public class Action implements Cloneable {

    /**
     *  Description of the Field
     */
    final String type;
    /**
     *  Description of the Field
     */
    final String name;
    /**
     *  Description of the Field
     */
    final int parameterType;
    /**
     *  Description of the Field
     */
    final boolean instantaneous;
    /**
     *  Description of the Field
     */
    Object parameter = null;
    /**
     *  The parameter type void.
     */
    public final static int VOID = 0;
    /**
     *  The parameter type position.
     */
    public final static int POSITION = 1;
    /**
     *  The parameter type piece.
     */
    public final static int PIECE = 2;


    /**
     *  Constructor for the Action object
     *
     * @param  type           Description of Parameter
     * @param  name           Description of Parameter
     * @param  parameterType  Description of Parameter
     * @param  instantaneous  Description of Parameter
     */
    public Action(String type, String name, int parameterType,
            boolean instantaneous) {
        this.type = new String(type);
        this.name = new String(name);
        if ((parameterType != VOID) &&
                (parameterType != POSITION) &&
                (parameterType != PIECE)) {
            this.parameterType = VOID;
        } else {
            this.parameterType = parameterType;
        }
        this.instantaneous = instantaneous;
    }


    /**
     *  Constructor for the Action object
     *
     * @param  type           Description of Parameter
     * @param  name           Description of Parameter
     * @param  parameterType  Description of Parameter
     * @param  instantaneous  Description of Parameter
     * @param  parameter      Description of Parameter
     */
    public Action(String type, String name, int parameterType,
            boolean instantaneous, Object parameter) {
        this(type, name, parameterType, instantaneous);
        setParameter(parameter);
    }


    /**
     *  Constructor for the Action object
     *
     * @param  a  Description of Parameter
     */
    public Action(Action a) {
        this(new String(a.getType()),
                new String(a.getName()),
                a.getParameterType(),
                a.isInstantaneous());
    }


    /**
     *  Constructor for the Action object
     *
     * @param  a          Description of Parameter
     * @param  parameter  Description of Parameter
     */
    public Action(Action a, Object parameter) {
        this(a);
        setParameter(parameter);
    }


    /**
     *  Sets the Parameter attribute of the Action object
     *
     * @param  o  The new Parameter value
     */
    public void setParameter(Object o) {
        parameter = o;
    }


    /**
     *  Gets the Type attribute of the Action object
     *
     * @return    The Type value
     */
    public String getType() {
        return type;
    }


    /**
     *  Gets the Name attribute of the Action object
     *
     * @return    The Name value
     */
    public String getName() {
        return name;
    }


    /**
     *  Gets the ParameterType attribute of the Action object
     *
     * @return    The ParameterType value
     */
    public int getParameterType() {
        return parameterType;
    }


    /**
     *  Gets the Instantaneous attribute of the Action object
     *
     * @return    The Instantaneous value
     */
    public boolean isInstantaneous() {
        return instantaneous;
    }


    /**
     *  Gets the Parameter attribute of the Action object
     *
     * @return    The Parameter value
     */
    public Object getParameter() {
        return parameter;
    }


    /**
     *  Description of the Method
     *
     * @return    Description of the Returned Value
     */
    public Object clone() {
        Action a = new Action(this);
        return a;
    }


    /**
     *  Description of the Method
     *
     * @param  o  Description of Parameter
     * @return    Description of the Returned Value
     */
    public boolean equals(Object o) {
        if (!(o instanceof Action)) {
            return false;
        }
        return ((Action) o).getType().equals(getType());
    }


    /**
     *  Description of the Method
     *
     * @return    Description of the Returned Value
     */
    public int hashCode() {
        return getType().hashCode();
    }


    /**
     *  Description of the Method
     *
     * @return    Description of the Returned Value
     */
    public String toString() {
        String arg = "";
        if ((parameterType == POSITION) && (parameter instanceof Position)) {
            Position pos = (Position) parameter;
            arg = " (" + (int) pos.x + "," + (int) pos.y + ")";
        }
        if ((parameterType == PIECE) && (parameter instanceof Piece)) {
            Piece piece = (Piece) parameter;
            arg = " " + piece.getName();
        }
        return (getName() + arg);
    }
}
