/*
 Tiamat - a role-playing game framework
 Location.java - represents a place a player can visit
 
 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;

import java.io.File;
import java.util.ArrayList;
import com.huguesjohnson.PathResolver;
import com.huguesjohnson.serialization.Formatter;
import com.huguesjohnson.serialization.Storable;

/** Location- represents a place a player can visit
* @author Hugues Johnson
 */
public class Location implements Storable{
//begin public properties
    //the exits from this Location
    private LocationExit[] exits;
    /** Retuns all the exits from this Location.
     * @return All the exits from this Location.
     */
    public LocationExit[] getExits(){
        return(this.exits);
    }
    /** Sets all the exits from this Location.
     * @param exits All the exits from this Location.
     */
    public void setExits(LocationExit[] exits){
        this.exits=exits;
    }
    //the relative path to the background music for this Area
    private String bgMusicPath;
    /** Returns the relative path to the background music.
     * @return The relative path to the background music.
     */
    public String getBgMusicPath(){
        return(this.bgMusicPath);
    }
    /** Sets the relative path to the background music.
     * @param bgMusicPath The relative path to the background music.
     */
    public void setBgMusicPath(String bgMusicPath){
        this.bgMusicPath=new String(bgMusicPath);
    }
    /** Returns the absolute path to the background music.
     * @return The absolute path to the background music.
     */
    public String getBgMusicPathAbsolute(){
        return(PathResolver.getAbsolutePath(this.absoluteDir,this.bgMusicPath));
    }
    //relative path to the background image for this CDArea, setting this reloads the actual image
    private String bgImagePath;
    /** Sets the relative path to the background image.
     * @param bgImagePath The relative path to the background image.
     */
    public void setBgImagePath(String bgImagePath){ 
        this.bgImagePath=bgImagePath; 
    }
    /** Returns the relative path to the background image.
     * @return The relative path to the background image.
     */
    public String getBgImagePath(){ 
        return(this.bgImagePath); 
    }
    /** Returns the absolute path to the background image.
     * @return The absolute path to the background image.
     */
    public String getBgImagePathAbsolute(){ 
        return(PathResolver.getAbsolutePath(this.absoluteDir,this.bgImagePath)); 
    }
    //relative path to the overlay image for this Location, setting this reloads the actual image
    private String overlayImagePath;
    /** Sets the relative path to the overlay image.
     * @param overlayImagePath The relative path to the overlay image.
     */
    public void setOverlayImagePath(String overlayImagePath){ 
        this.overlayImagePath=overlayImagePath; 
    }
    /** Returns the relative path to the overlay image.
     * @return The relative path to the overlay image.
     */
    public String getOverlayImagePath(){ 
        return(this.overlayImagePath); 
    }
    /** Returns the absolute path to the overlay image.
     * @return The absolute path to the overlay image.
     */
    public String getOverlayImagePathAbsolute(){
        return(PathResolver.getAbsolutePath(this.absoluteDir,this.overlayImagePath)); 
    }
    //the Items in the Location
    private LocationObjectData[] items;
    /** Returns a LocationObjectData array containing information about the Items in the Location.
     * @return A LocationObjectData array containing information about the Items in the Location.
     */
    public LocationObjectData[] getItems(){
    	return(this.items);
    }
    /** Sets the information about the Items in the Location.
     * @param items A LocationObjectData array containing information about the Items in the Location.
     */
    public void setItems(LocationObjectData[] items){
    	this.items=items;
    }
    //the Characters in the Location
    private LocationObjectData[] characters;
    /** Returns a LocationObjectData array containing information about the Characters in the Location.
     * @return A LocationObjectData array containing information about the Characters in the Location.
     */
    public LocationObjectData[] getCharacters(){
    	return(this.characters);
    }
    /** Sets the information about the Characters in the Location.
     * @param characters A LocationObjectData array containing information about the Characters in the Location.
     */
    public void setCharacters(LocationObjectData[] characters){
    	this.characters=characters;
    }
    //absolute path to the directory where objects are saved
    protected transient String absoluteDir;
    /** 
     * Sets the absolute working directory for files.
     * @param absoluteDir The full path to the working directory.
     */
    public void setAbsoluteDir(String absoluteDir){
        if(absoluteDir.endsWith(File.separator)){
            this.absoluteDir=absoluteDir;
        } else{
            this.absoluteDir=absoluteDir+File.separator;
        }
    }
//end public properties

//begin constructors
    /** Creates a new instance of Location.
     */
    public Location(){
    	//initialize arrays to prevent null problems
    	this.exits=new LocationExit[0];
    	this.characters=new LocationObjectData[0];
    	this.items=new LocationObjectData[0];
    }
//end constructors
    
//begin public methods
    /** Adds a Character with default settings.
     * @param name The name of the Character to add. 
     */
    public void addCharacter(String name){
    	LocationObjectData locationData=new LocationObjectData(name,true,LocationObjectData.XAlignment.CENTER,LocationObjectData.YAlignment.BOTTOM);
    	this.addCharacter(locationData);
    }
    /** Adds the Character defined by the LocationObjectData.
     * @param locationData The information about the Character.
     */
    public void addCharacter(LocationObjectData locationData){
    	int length=this.characters.length;
    	LocationObjectData[] newCharacters=new LocationObjectData[length+1];
    	if(length>0){
    		System.arraycopy(this.characters,0,newCharacters,0,length);
    	}
    	newCharacters[length]=locationData;
    	this.setCharacters(newCharacters);
    }
    /** Removes the Character with the specified name.
     * @param name The name of the Character to remove.
     */
    public void removeCharacter(String name){
    	ArrayList<LocationObjectData> temp=new ArrayList<LocationObjectData>();
    	int length=this.characters.length;
    	for(int index=0;index<length;index++){
    		if(!this.characters[index].getName().equals(name)){
    			temp.add(this.characters[index]);
    		}
    	}
    	this.setCharacters(temp.toArray(new LocationObjectData[0]));
    }
    /** Adds an Item with default settings.
     * @param name The name of the Item to add. 
     */
    public void addItem(String name){
    	LocationObjectData locationData=new LocationObjectData(name,LocationObjectData.DEFAULT_VISIBLE,LocationObjectData.DEFAULT_X_ALIGN,LocationObjectData.DEFAULT_Y_ALIGN);
    	this.addItem(locationData);
    }
    /** Adds the Item defined by the LocationObjectData.
     * @param locationData The information about the Item.
     */
    public void addItem(LocationObjectData locationData){
    	int length=this.items.length;
    	LocationObjectData[] newItems=new LocationObjectData[length+1];
    	if(length>0){
    		System.arraycopy(this.items,0,newItems,0,length);
    	}
    	newItems[length]=locationData;
    	this.setItems(newItems);
    }
    /** Removes the Item with the specified name.
     * @param name The name of the Item to remove.
     */
    public void removeItem(String name){
    	ArrayList<LocationObjectData> temp=new ArrayList<LocationObjectData>();
    	int length=this.items.length;
    	for(int index=0;index<length;index++){
    		if(!this.items[index].getName().equals(name)){
    			temp.add(this.items[index]);
    		}
    	}
    	this.setItems(temp.toArray(new LocationObjectData[0]));
    }
	/* (non-Javadoc)
	 * @see com.huguesjohnson.serialization.Storable#onDeserialize(com.huguesjohnson.serialization.Formatter, java.lang.String)
	 */
	public void onDeserialize(Formatter formatter,String absoluteDir){
        this.setAbsoluteDir(absoluteDir);
    	//initialize arrays to prevent null problems
    	if(this.exits==null){ this.exits=new LocationExit[0]; }
    	if(this.characters==null){ this.characters=new LocationObjectData[0]; }
    	if(this.items==null){ this.items=new LocationObjectData[0]; }
	}
//end public methods
}