/*
Tiamat - a role-playing game framework
ScriptTableKey.java - used to store & retrieve entries from a GameScript
 
 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;

import java.util.ArrayList;

/**
 * ScriptTableKey - used to store & retrieve entries from a GameScript
 * @author Hugues Johnson
 */
public class ScriptTableKey{
    /**
     * The Event stored in this key.
     */
    public Event event;
    /**
     * The conditions for this key.
     */
    public ArrayList<String> conditions;
    /**
     * Create a new instance of ScriptTableKey.
     * @param event The stored in this key.
     * @param conditions The conditions for this key.
     */
    public ScriptTableKey(Event event,String[] conditions){
        this.event=event;
        this.conditions=new ArrayList<String>();
        if(conditions!=null){
            int length=conditions.length;
            for(int index=0;index<length;index++){
                this.conditions.add(new String(conditions[index]));
            }
        }
    } 
    /**
     * Create a new instance of ScriptTableKey.
     * @param event The stored in this key.
     * @param conditions The conditions for this key.
     */
    public ScriptTableKey(Event event,ArrayList<String> conditions){
        this.event=event;
        this.conditions=new ArrayList<String>();
        this.conditions.addAll(conditions);
    } 
    /* (non-Javadoc)
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object object){
        if(!(object instanceof ScriptTableKey)){
            return(false);
        }
		boolean isEqual=true;
		ScriptTableKey key=(ScriptTableKey)object;
		//fastest test first, are the actions the same?
		isEqual=this.event.getAction().equals(key.event.getAction());
		//are the conditions the same?
		if(isEqual){
		    int length=this.conditions.size();
		    if(length!=key.conditions.size()){
		        isEqual=false;
		    } else{
		        int index=0;
		        while((index<length)&&(isEqual)){
		            if(!key.conditions.contains(this.conditions.get(index))){
		                isEqual=false;
		            } else{
		                index++;
		            }
		        }
		    }
		}
		//finally, test the parameters
		if(isEqual){
		    String[][] thisParams=this.event.getParameters().getAll();
		    String[][] keyParams=key.event.getParameters().getAll();
		    //[0][n]=key for item n, [1][n]=value for item n
		    if(thisParams==null){
		        if(keyParams!=null){
		            isEqual=false;
		        }
		    } else if(keyParams==null){
		        isEqual=false;
		    } else{
		        int length=thisParams[0].length;
		        if(length!=keyParams[0].length){
		            isEqual=false;
		        } else{
		            int index=0;
		            String defaultValue=new String("\r_DeF@uLt__Va1Ue!!__\t^");
		            //potential issue.. this assumes that parameters are always in the same order
		            while((index<length)&&(isEqual)){
		                String value=key.event.getParameters().get(thisParams[0][index],defaultValue);
		                if(!value.equalsIgnoreCase(thisParams[1][index])){
		                    isEqual=false;
		                } else{
		                    index++;
		                }
		            }
		        }
		    }
		}
		key=null;
		return(isEqual);
    }
    /* (non-Javadoc)
     * @see java.lang.Object#hashCode()
     */
    public int hashCode(){
        int hashcode=0;
        //this is moderatly tricky.. 
        //we have to make sure the object will always return the same hashCode
        //this works fine and is fairly fast but could be better I suppose
        byte b[]=this.event.getAction().getBytes();
        int length=b.length;
        for(int index=0;index<length;index++){
            hashcode|=b[index];
        }
        length=this.conditions.size();
        if(length>0){
            hashcode+=(1000*length);
        }
        return(hashcode);
    }
}