package org.greenstone.atlas.client;

import java.io.Serializable;
import java.util.ArrayList;

import com.google.gwt.user.client.rpc.AsyncCallback;

public class Place implements Serializable
{
	private static final long serialVersionUID = 6106265145261780206L;

	protected ArrayList<String> _childrenPlaceNames = new ArrayList<String>();

	protected String _placeName = null;
	protected String _parentPlaceName = null;
	protected String _placeType = null;

	protected Float _latitude = null;
	protected Float _longitude = null;

	protected long _population = 0;
	protected long _id = -1;
	protected int _score = 0;

	protected boolean _directlyReferenced = false;
	protected static boolean _loopDone = false;
	
	protected static Place _tempPlace = null;

	public Place()
	{

	}

	public Place(String placeName)
	{
		_placeName = placeName;
	}

	public void setParentPlaceName(String parentPlaceName)
	{
		_parentPlaceName = parentPlaceName;
	}

	public boolean addChildPlaceName(String placeName)
	{
		if (_childrenPlaceNames.contains(placeName))
		{
			return false;
		}
		else
		{
			_childrenPlaceNames.add(placeName);
			return true;
		}
	}

	public boolean equals(Object placeToCompare)
	{
		if (placeToCompare == null)
		{
			return false;
		}
		/*
		if (placeToCompare instanceof ServerPlace)
		{
			ServerPlace otherPlace = (ServerPlace)(placeToCompare);
			if(_placeName != null && otherPlace.getName() != null && _parentPlaceName != null && otherPlace.getParentPlaceName() != null && _placeName.equals(otherPlace.getName()))
			{
				String[] cols = _parentPlaceName.split(", ");
				String[] otherCols = otherPlace.getParentPlaceName().split(", ");
				
				if(cols.length == 3 && otherCols.length == 2)
				{
					if(cols[0].equals(otherPlace.getName()) && cols[1].equals(otherCols[0]) && cols[2].equals(otherCols[1]))
					{
						return true;
					}
				}
				else if(cols.length == 2 && otherCols.length == 3)
				{
					if(otherCols[0].equals(_placeName) && otherCols[1].equals(cols[0]) && otherCols[2].equals(cols[1]))
					{
						return true;
					}
				}
				else if(cols.length == 2 && otherCols.length == 1)
				{
					if(cols[0].equals(otherPlace.getName()) && cols[1].equals(otherCols[0]))
					{
						return true;
					}
				}
				else if(cols.length == 1 && otherCols.length == 2)
				{
					if(otherCols[0].equals(_placeName) && otherCols[1].equals(cols[0]))
					{
						return true;
					}
				}
			}
			
			if (_id != -1 && ((ServerPlace)(placeToCompare)).getId() != -1 && _id == otherPlace.getId())
			{
				return true;
			}

			String otherPlaceName = otherPlace.getName();
			String otherParentName = otherPlace.getParentPlaceName();

			if ((_placeName == null && otherPlaceName == null) && (_parentPlaceName == null && otherParentName == null))
			{
				return true;
			}

			if ((_placeName == null && otherPlaceName == null) && _parentPlaceName != null && otherParentName != null && _parentPlaceName.equals(otherParentName))
			{
				return true;
			}

			if ((_parentPlaceName == null && otherParentName == null) && _placeName != null && otherPlaceName != null && _placeName.equals(otherPlaceName))
			{
				return true;
			}

			if (_placeName != null && otherPlaceName != null && _parentPlaceName != null && otherParentName != null && _parentPlaceName.equals(otherPlace.getParentPlaceName()) && _placeName.equals(otherPlace.getName()))
			{
				return true;
			}
		}
*/
		if (placeToCompare instanceof Place)
		{
			Place otherPlace = (Place)(placeToCompare);
			if(_placeName != null && otherPlace.getName() != null && _parentPlaceName != null && otherPlace.getParentPlaceName() != null && _placeName.equals(otherPlace.getName()))
			{
				String[] cols = _parentPlaceName.split(", ");
				String[] otherCols = otherPlace.getParentPlaceName().split(", ");
				
				if(cols.length == 3 && otherCols.length == 2)
				{
					if(cols[0].equals(otherPlace.getName()) && cols[1].equals(otherCols[0]) && cols[2].equals(otherCols[1]))
					{
						return true;
					}
				}
				else if(cols.length == 2 && otherCols.length == 3)
				{
					if(otherCols[0].equals(_placeName) && otherCols[1].equals(cols[0]) && otherCols[2].equals(cols[1]))
					{
						return true;
					}
				}
				else if(cols.length == 2 && otherCols.length == 1)
				{
					if(cols[0].equals(otherPlace.getName()) && cols[1].equals(otherCols[0]))
					{
						return true;
					}
				}
				else if(cols.length == 1 && otherCols.length == 2)
				{
					if(otherCols[0].equals(_placeName) && otherCols[1].equals(cols[0]))
					{
						return true;
					}
				}
			}
			
			if (_id != -1 && ((Place)(placeToCompare)).getId() != -1 && _id == ((Place)(placeToCompare)).getId())
			{
				return true;
			}

			String otherPlaceName = otherPlace.getName();
			String otherParentName = otherPlace.getParentPlaceName();

			if ((_placeName == null && otherPlaceName == null) && (_parentPlaceName == null && otherParentName == null))
			{
				return true;
			}

			if ((_placeName == null && otherPlaceName == null) && _parentPlaceName != null && otherParentName != null && _parentPlaceName.equals(otherParentName))
			{
				return true;
			}

			if ((_parentPlaceName == null && otherParentName == null) && _placeName != null && otherPlaceName != null && _placeName.equals(otherPlaceName))
			{
				return true;
			}

			if (_placeName != null && otherPlaceName != null && _parentPlaceName != null && otherParentName != null && _parentPlaceName.equals(otherPlace.getParentPlaceName()) && _placeName.equals(otherPlace.getName()))
			{
				return true;
			}
		}
		return false;
	}

	public String toString()
	{
		String info = "*************************";

		info += "\nPlace name = " + _placeName + "\nParents = " + _parentPlaceName + "\nChildren = ";

		for (String p : _childrenPlaceNames)
		{
			info += "->" + p;
		}

		info += "\nPlace type = " + _placeType;
		info += "\nPopulation = " + _population;
		info += "\nLatitude = " + _latitude + " Longitude = " + _longitude;
		info += "\n*************************";

		return info;
	}

	// Get Methods

	public int getScore()
	{
		return _score;
	}

	public String getPlaceType()
	{
		return _placeType;
	}

	public String getParentPlaceName()
	{
		return _parentPlaceName;
	}

	public ArrayList<String> getChildrenPlaceNames()
	{
		return _childrenPlaceNames;
	}

	public String getName()
	{
		return _placeName;
	}

	public Float getLatitude()
	{
		return _latitude;
	}

	public Float getLongitude()
	{
		return _longitude;
	}

	public long getPopulation()
	{
		return _population;
	}

	public long getId()
	{
		return _id;
	}

	public boolean isDirectlyReferenced()
	{
		return _directlyReferenced;
	}

	// Set Methods

	public void setScore(int score)
	{
		_score = score;
	}

	public void setPlaceType(String placeType)
	{
		_placeType = placeType;
	}

	public void setLatitude(Float latitude)
	{
		_latitude = latitude;
	}

	public void setLongitude(Float longitude)
	{
		_longitude = longitude;
	}

	public void setPopulation(long population)
	{
		_population = population;
	}

	public void setId(long id)
	{
		_id = id;
	}

	public void directReference()
	{
		_directlyReferenced = true;
	}

	/**
	 * Figures out what sort of place the line in the file is refering to (e.g.
	 * locality, region, etc.)
	 * 
	 * @param placeName
	 *            is the name of the place
	 * @param subRegionName
	 *            is the possible sub region the place is in
	 * @param regionName
	 *            is the possible region the place is in
	 * @param countryName
	 *            is the country the place is in
	 * @param placeType
	 *            is the type of place
	 * @return returns the place
	 */
	public static Place createPlaceFromInformation(long id, String placeName, String subRegionName, String regionName, String countryName, String placeType, Float longitude, Float latitude, long population)
	{
		Place newPlace = new Place(placeName);

		String parentPlaceName = null;
		if (!(subRegionName == null))
		{
			parentPlaceName = subRegionName;
		}
		if (!(regionName == null))
		{
			if (parentPlaceName == null)
			{
				parentPlaceName = regionName;
			}
			else
			{
				parentPlaceName += ", " + regionName;
			}
		}
		if (!(countryName == null))
		{
			if (parentPlaceName == null)
			{
				parentPlaceName = countryName;
			}
			else
			{
				parentPlaceName += ", " + countryName;
			}
		}

		if (parentPlaceName == null && countryName == null)
		{
			if (placeType.equals("country"))
			{
				countryName = placeName;
			}
			else
			{
				return null;
			}
		}
		
		newPlace.setId(id);
		newPlace.setParentPlaceName(parentPlaceName);
		newPlace.setLatitude(latitude);
		newPlace.setLongitude(longitude);
		newPlace.setPopulation(population);
		newPlace.setPlaceType(placeType);
		return newPlace;
	}
	
	public boolean isIn(Place p)
	{
		if(_parentPlaceName == null)
		{
			return false;
		}
		
		String[] cols = _parentPlaceName.split(", ");
		
		if(p.getParentPlaceName() == null)
		{
			if(cols[cols.length-1].equals(p.getName()))
			{
				return true;
			}
			return false;
		}
		String[] otherCols = p.getParentPlaceName().split(", ");
		
		if(cols.length <= otherCols.length)
		{
			return false;
		}
		
		else if(otherCols.length == 1)
		{
			if(cols[cols.length-1].equals(otherCols[0]) && cols[cols.length-2].equals(p.getName()))
			{
				return true;
			}
		}
		else if(otherCols.length == 2)
		{
			if(cols[cols.length-1].equals(otherCols[1]) && cols[cols.length-2].equals(otherCols[0]) && cols[cols.length-3].equals(p.getName()))
			{
				return true;
			}
		}
		
		return false;
	}
	
	public static Place createPlaceFromId(long id)
	{
		_loopDone = false;
		GS3MapLibrary.getServerConnection().getPlaceById(id, new AsyncCallback<Place>()
		{
			@Override
			public void onSuccess(Place p)
			{
				_tempPlace = p;
				_loopDone = true;
			}

			@Override
			public void onFailure(Throwable arg0)
			{
				_tempPlace = null;
				_loopDone = true;
			}
		});
		
		while(!_loopDone);
		
		return _tempPlace;
	}

	public void unDirectReference()
	{
		_directlyReferenced = false;
	}
}
