package org.greenstone.atlas.server;

import java.io.Serializable;
import org.greenstone.atlas.client.Place;

public class ServerPlace implements Serializable
{
	private static final long serialVersionUID = 6106265145261780206L;
	protected static FindPlaceServiceImpl _fpsi = new FindPlaceServiceImpl();

	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 ServerPlace _tempPlace = null;

	public ServerPlace()
	{

	}

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

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

	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 = ";

		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 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 ServerPlace createPlaceFromInformation(long id, String placeName, String subRegionName, String regionName, String countryName, String placeType, Float longitude, Float latitude, long population)
	{
		ServerPlace newPlace = new ServerPlace(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 static ServerPlace convert(Place p)
	{
		ServerPlace sp = ServerPlace.createPlaceFromInformation(p.getId(), p.getName(), null, null, p.getParentPlaceName(), p.getPlaceType(), p.getLongitude(), p.getLatitude(), p.getPopulation()); 
		
		sp.setScore(p.getScore());
		
		if(p.isDirectlyReferenced())
		{
			sp.directReference();
		}
		
		return sp;
	}

	public static ServerPlace createPlaceFromId(long id)
	{
		Place p = _fpsi.getPlaceById(id);
		
		//System.out.println("P = " + p);
		
		return ServerPlace.createPlaceFromInformation(p.getId(), p.getName(), null, null, p.getParentPlaceName(), p.getPlaceType(), p.getLongitude(), p.getLatitude(), p.getPopulation());
	}
}
