/*
 Tiamat - a role-playing game framework
 CodeUtilities.java - contains functions to generate code
 
 Copyright  (C) 2006 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.tools.adventureStudio;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;

import com.huguesjohnson.tiamat.BaseAdventureGame;
import com.huguesjohnson.tiamat.Event;
import com.huguesjohnson.tiamat.IAdventureCommands;
import com.huguesjohnson.tiamat.graphics.Sequence;
import com.huguesjohnson.tiamat.graphics.SequenceFrame;
import com.huguesjohnson.tiamat.tools.adventureStudio.event.EventUtilities;

/**
 * CodeUtilities - contains functions to generate code
 * @author Hugues Johnson
 */
public class CodeUtilities{
	private final static String CLASSNAME_TOKEN="CLASSNAME";
	private final static String PACKAGENAME_TOKEN="PACKAGENAME";

	//would be static except this.getClass() can't be called from a static method
	public void buildFromTemplate(String templateName,String classPrefix,String destinationDir){
		//paranoid programming
		if(!destinationDir.endsWith(File.separator)){
			destinationDir+=File.separator;
		}
		//set class & package name
		String className=classPrefix.substring(0,1).toUpperCase()+classPrefix.substring(1);
		String packageName=className.toLowerCase();
		//copy the template file to the destination
		try{
			//create reader for source file
			InputStream in=this.getClass().getResourceAsStream("/com/huguesjohnson/tiamat/tools/adventureStudio/"+templateName+".template");
			BufferedReader reader=new BufferedReader(new InputStreamReader(in));
			//create writer for output file
			PrintWriter out=new PrintWriter(new BufferedWriter(new FileWriter(destinationDir+className+templateName+".java")));
			//do the copy & character replacement
			String currentLine;
			while((currentLine=reader.readLine())!=null){
				currentLine=currentLine.replaceAll(CLASSNAME_TOKEN,className);
				currentLine=currentLine.replaceAll(PACKAGENAME_TOKEN,packageName);
				out.write(currentLine);
			}
			out.flush();
			out.close();
			in.close();
		} catch(Exception x){
			EventUtilities.showErrorDialog(x);
		}
	}
	
	public static ArrayList<String> getClassPaths(){
       ArrayList<String> classPaths=new ArrayList<String>();
       
       String classPath=System.getProperty("java.class.path");
       if(classPath!=null){
	       String pathSeparator=System.getProperty("path.separator");
	       if((pathSeparator==null)||(pathSeparator.length()<1)){
	    	   pathSeparator=";";
	       }
	       String[] allClassPaths=classPath.split(pathSeparator);
	       if(allClassPaths!=null){
	    	   int length=allClassPaths.length;
	    	   for(int index=0;index<length;index++){
	    		   String lower=allClassPaths[index].toLowerCase();
	    		   //check for jars that we care about
	    		   if(lower.endsWith(".jar")){
	    			   if((lower.indexOf("xpp3_min")>=0)||(lower.indexOf("xstream")>=0)||(lower.indexOf("tiamat")>=0)){
	    				   classPaths.add(allClassPaths[index]);
	    			   }
	    		   }
	    	   }
	       }
       }
       
       return(classPaths);
    }

	//this method will probably come back to bite me someday, it's a potential maintenance problem
	public static Sequence buildDefaultSequence(String sequenceName,String absoluteDir){
		SequenceFrame[] frames=new SequenceFrame[2];
		Event[] exitEvents=new Event[1];
		//initialize frames
		frames[0]=new SequenceFrame();
		frames[0].setAbsoluteDir(absoluteDir);
		frames[1]=new SequenceFrame();
		frames[1].setAbsoluteDir(absoluteDir);
		StringBuffer text0=new StringBuffer();
		StringBuffer text1=new StringBuffer();
		//start the frame text
		text0.append("This is the first frame for the ");
		text0.append(sequenceName);
		text0.append(" sequence. ");
		text1.append("This is the last frame for the ");
		text1.append(sequenceName);
		text1.append(" sequence. ");
		//add sequence specific messages & events
		if(sequenceName.equals(BaseAdventureGame.ConfigKeys.SEQUENCE_GAMEOVER.defaultValue())){
			text0.append("This sequence should be called to end the game.");
			text0.append("\n\nDo NOT remove the ");
			text0.append(IAdventureCommands.Actions.GAMEOVER.value());
			text0.append(" exitEvent from this sequence.");
			text1.append("This sequence should be called to end the game.");
			text1.append("\n\nDo NOT remove the ");
			text1.append(IAdventureCommands.Actions.GAMEOVER.value());
			text1.append(" exitEvent from this sequence.");
			exitEvents[0]=new Event(IAdventureCommands.Actions.GAMEOVER.value());
		} else if(sequenceName.equals(BaseAdventureGame.ConfigKeys.SEQUENCE_INTRODUCTION.defaultValue())){
			text0.append("This sequence is called when a new game is started.");
			text0.append("\n\nTODO: Update the location on the ");
			text0.append(IAdventureCommands.Actions.MOVEPLAYER.value());
			text0.append(" exitEvent.");
			text1.append("This sequence is called when a new game is started.");
			text1.append("\n\nTODO: Update the location on the ");
			text1.append(IAdventureCommands.Actions.MOVEPLAYER.value());
			text1.append(" exitEvent.");
			exitEvents[0]=new Event(IAdventureCommands.Actions.MOVEPLAYER.value());
			exitEvents[0].getParameters().set(IAdventureCommands.Parameters.LOCATION.value(),"TODO: Set this to the starting location.");
		} else if(sequenceName.equals(BaseAdventureGame.ConfigKeys.SEQUENCE_TITLE.defaultValue())){
			text0.append("This is the title sequence to the game and is automatically loaded when the program starts.");
			text0.append("\n\nDo NOT remove the ");
			text0.append(IAdventureCommands.Actions.TITLEMENU.value());
			text0.append(" exitEvent from this sequence.");
			text1.append("This is the title sequence to the game and is automatically loaded when the program starts.");
			text1.append("\n\nDo NOT remove the ");
			text1.append(IAdventureCommands.Actions.TITLEMENU.value());
			text1.append(" exitEvent from this sequence.");
			exitEvents[0]=new Event(IAdventureCommands.Actions.TITLEMENU.value());
		}
		//finish off the text
		text0.append("\n\nTODO: Set the background image, music, and text for this frame; add additional frames after this if needed.");
		text1.append("\n\nTODO: Set the background image, music, and text for this frame; add additional frames before this if needed.");
		frames[0].setText(text0.toString());
		frames[1].setText(text1.toString());
		return(new Sequence(frames,exitEvents));
	}
	
}