/*
ScriptTable_Prototype.java - Trying out ideas for storing a game script
  
 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.test;

import com.huguesjohnson.tiamat.Event;

import java.util.ArrayList;
import java.util.Hashtable;

/** ScriptTable_Prototype.java - Trying out ideas for storing a game script
 * @author Hugues Johnson
 */
public class ScriptTable_Prototype{
    
    /** 
     * TestKey is used to test a script table key.
     * @author Hugues Johnson
     */
    public class TestKey{
        public Event event;
        public ArrayList<String> conditions;
        TestKey(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]));
                }
            }
        }
        public boolean equals(Object object){
            if(!(object instanceof TestKey)){
                return(false);
            }
			boolean isEqual=true;
			TestKey key=(TestKey)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^");
			            while((index<length)&&(isEqual)){
			                String value=key.event.getParameters().get(thisParams[0][index],defaultValue);
			                if(!value.equals(thisParams[1][index])){
			                    isEqual=false;
			                } else{
			                    index++;
			                }
			            }
			        }
			    }
			}
			return(isEqual);
        }
    }
    
    /** 
     * TestValue is used to test a script table value.
     * @author Hugues Johnson
     */
    public class TestValue{
        ArrayList<Event> events;
        public TestValue(){
            this.events=new ArrayList<Event>();
        }
    }
        
    /**
     * Runs the tests.
     */
    public ScriptTable_Prototype(){
        boolean allPassed=true;
        //first test, compare two keys for equality
        Event event1=new Event("event1");
        event1.getParameters().set("param1","value1");
        event1.getParameters().set("param2","value2");
        String[] conditions1=new String[2];
        conditions1[0]="c1";
        conditions1[1]="c2";
        TestKey key1=new TestKey(event1,conditions1);
        Event event2=new Event("event1");
        event2.getParameters().set("param1","value1");
        event2.getParameters().set("param2","value2");
        String[] conditions2=new String[2];
        conditions2[0]="c1";
        conditions2[1]="c2";
        TestKey key2=new TestKey(event2,conditions2);
        boolean isEqual=key1.equals(key2);
        if(!isEqual){
            allPassed=false;
            System.out.println("first test failed");
        }
        //second test, compare two keys with different action but same parameters
        Event event3=new Event("event3");
        event3.getParameters().set("param1","value1");
        event3.getParameters().set("param2","value2");
        String[] conditions3=new String[2];
        conditions3[0]="c1";
        conditions3[1]="c2";
        TestKey key3=new TestKey(event3,conditions3);
        isEqual=key1.equals(key3);
        if(isEqual){
            allPassed=false;
            System.out.println("second test failed");
        }
        //third test, compare two keys with same action but different parameters
        Event event4=new Event("event1");
        event4.getParameters().set("param1","value1");
        event4.getParameters().set("param2","xxxxxx");
        String[] conditions4=new String[2];
        conditions4[0]="c1";
        conditions4[1]="c2";
        TestKey key4=new TestKey(event4,conditions4);
        isEqual=key1.equals(key4);
        if(isEqual){
            allPassed=false;
            System.out.println("third test failed");
        }
        //fourth test, compare two keys with same action but null parameters
        Event event5=new Event("event1");
        String[] conditions5=new String[2];
        conditions5[0]="c1";
        conditions5[1]="c2";
        TestKey key5=new TestKey(event5,conditions5);
        isEqual=key1.equals(key5);
        if(isEqual){
            allPassed=false;
            System.out.println("fourth test failed");
        }
        //fifth test, compare two keys with same action and parameters but different conditions
        Event event6=new Event("event1");
        event6.getParameters().set("param1","value1");
        event6.getParameters().set("param2","value2");
        String[] conditions6=new String[2];
        conditions6[0]="xxxxx";
        conditions6[1]="yyyyy";
        TestKey key6=new TestKey(event6,conditions6);
        isEqual=key1.equals(key6);
        if(isEqual){
            allPassed=false;
            System.out.println("fifth test failed");
        }
        //sixth test, compare two keys with same action and parameters but null conditions
        Event event7=new Event("event1");
        event6.getParameters().set("param1","value1");
        event6.getParameters().set("param2","value2");
        TestKey key7=new TestKey(event7,null);
        isEqual=key1.equals(key7);
        if(isEqual){
            allPassed=false;
            System.out.println("sixth test failed");
        }        
        
        //now.. let's see if this all works with a hashtable
        Hashtable<TestKey,TestValue> table=new Hashtable<TestKey,TestValue>();
        TestValue value=new TestValue();
        value.events.add(event2);
        value.events.add(event3);
        table.put(key1,value);
        value=new TestValue();
        value.events.add(event4);
        value.events.add(event5);
        table.put(key3,value);
        value=new TestValue();
        value.events.add(event6);
        value.events.add(event7);
        table.put(key5,value);
        Object returnValue=table.get(key1);
        if(returnValue==null){
            allPassed=false;
            System.out.println("getting key1 failed");
        }
        returnValue=table.get(key2);
        if(returnValue!=null){
            allPassed=false;
            System.out.println("getting key2 succeeded");
        }
        returnValue=table.get(key3);
        if(returnValue==null){
            allPassed=false;
            System.out.println("getting key3 failed");
        }
        returnValue=table.get(key4);
        if(returnValue!=null){
            allPassed=false;
            System.out.println("getting key4 succeeded");
        }
        returnValue=table.get(key5);
        if(returnValue==null){
            allPassed=false;
            System.out.println("getting key5 failed");
        }
        
        if(allPassed){
            System.out.println("Good times");
        } else{
            System.out.println("Bad times");
        }
    }
    
	/**
	 * Entry point for the test.
	 * @param arguments Not Used.
	 */
   public static void main(String[] arguments){
        new ScriptTable_Prototype();
    }
}