
package jp.riken.brain.ni.samuraigraph.base;

import java.awt.Color;
import java.util.ArrayList;
import java.util.List;


/**
 * The base class of drawing elements.
 */
public abstract class SGDrawingElement
	implements SGIDrawingElementConstants, SGIVisible, SGIDisposable
{

	// The magnification.
	private float mMagnification = 1.0f;

	// The list of colors.
	private List mColorList = new ArrayList();

	// Visibility flag.
	private boolean mVisibleFlag = true;

	/**
	 * The default constructor.
	 */
	public SGDrawingElement()
	{
		super();
	}


	/**
	 * Returns whether this drawing element "contains" the given point.
	 */
	public abstract boolean contains( final int x, final int y );


	/**
	 * 
	 */
	public boolean zoom( final float ratio )
	{
		this.setMagnification( ratio );
		return true;
	}


	/**
	 * 
	 * @return
	 */
	public final boolean isVisible()
	{
		return this.mVisibleFlag;
	}


	/**
	 * 
	 * @param b
	 */
	public void setVisible( final boolean b )
	{
		this.mVisibleFlag = b;
	}



	/**
	 * 
	 */
	public boolean setMagnification( final float mag )
	{
		this.mMagnification = mag;
		return true;
	}



	/**
	 * Clear the present colors and set given all colors.
	 * @param list of colors
	 */
	public boolean setColorList( final List list )
	{
		if( list==null )
		{
			new NullPointerException("list==null");
		}
		if( list.size()==0 )
		{
			new IllegalArgumentException("list.size()==0");
		}
		for( int ii=0; ii<list.size(); ii++ )
		{
			if( ( list.get(ii) instanceof Color ) == false )
			{
				throw new ClassCastException();
			}
		}
		this.mColorList.clear();
		this.mColorList.addAll( list );
		return true;
	}


	/**
	 * Clear the present colors and set given given color.
	 */
	public boolean setColor( final Color cl )
	{
		if( cl==null )
		{
			new NullPointerException("cl==null");
		}
		this.mColorList.clear();
		this.mColorList.add( cl );
		return true;
	}


	/**
	 * Add color to the list.
	 */
	public boolean addColor( final Color cl )
	{
		if( cl==null )
		{
			new NullPointerException("cl==null");
		}
		this.mColorList.add(cl);
		return true;
	}


	/**
	 * 
	 */
	public final List getColorList()
	{
		return new ArrayList( this.mColorList );
	}


	/**
	 * Returns the color with given index.
	 * @param index - the index to get color
	 */
	public final Color getColor( final int index )
	{
		if( index >= this.mColorList.size() )
		{
			new IllegalArgumentException("index >= this.mColorList.size()");
		}

		return (Color)this.mColorList.get(index);
	}


	/**
	 * 
	 */
	public final float getMagnification()
	{
		return this.mMagnification;
	}


	/**
	 * 
	 */
	public boolean setProperties( final SGDrawingElement element )
	{
		SGProperties p = element.getProperties();
		if( p==null ) return false;
		if( this.setProperties(p) == false ) return false;
		return true;
	}


	/**
	 * 
	 */
	public boolean setProperties( SGProperties p )
	{
		if( ( p instanceof DrawingElementProperties ) == false ) return false;

		DrawingElementProperties dp = (DrawingElementProperties)p;

		final Boolean b = dp.isVisible();
		if( b==null )
		{
			return false;
		}
		this.setVisible( b.booleanValue() );

		final List cList = dp.getColorList();
		if( cList==null )
		{
			return false;
		}
		this.setColorList( cList );

		return true;
	}


	/**
	 * Returns the properties of this object.
	 * @return
	 */
	public SGProperties getProperties()
	{
		final DrawingElementProperties p = new DrawingElementProperties();
		if( this.getProperties(p) == false )
		{
			return null;
		}
		return p;
	}



	/**
	 * Returns the properties of this object by setting given properties object.
	 * @param p
	 * @return
	 */
	public boolean getProperties( final SGProperties p )
	{
		if( ( p instanceof DrawingElementProperties ) == false )
		{
			return false;
		}
		
		final DrawingElementProperties dp = (DrawingElementProperties)p;
		dp.setVisible( this.isVisible() );
		dp.setColor( this.getColorList() );

		return true;
	}



	/**
	 * 
	 */
	public void dispose()
	{
		this.mColorList.clear();
		this.mColorList = null;
	}


	/**
	 * Properties of the drawing element.
	 */
	public static class DrawingElementProperties
		extends SGProperties
	{
		private boolean mVisible = true;
		private List mColorList = new ArrayList();

		/**
		 * 
		 */
		public DrawingElementProperties()
		{
			super();
		}

		/**
		 * 
		 */
		public void dispose()
		{
			this.mColorList.clear();
			this.mColorList = null;
		}

		/**
		 * 
		 */
		public boolean equals( final Object obj )
		{
			if( ( obj instanceof DrawingElementProperties ) == false ) return false;
			DrawingElementProperties p = (DrawingElementProperties)obj;

			if( this.mVisible!=p.mVisible ) return false;
			if( this.mColorList.equals(p.mColorList) == false ) return false;

			return true;
		}


		public Boolean isVisible()
		{
			return Boolean.valueOf( this.mVisible );
		}

		public List getColorList()
		{
			return new ArrayList( this.mColorList );
		}

		public void setVisible( final boolean b )
		{
			this.mVisible = b;
		}


		public void setColor( final Color cl )
		{
			if( cl==null )
			{
				new NullPointerException("cl==null");
			}
			this.mColorList.clear();
			this.mColorList.add( cl );
		}

		public void setColor( final List list )
		{
			if( list==null )
			{
				new NullPointerException("list==null");
			}
			if( list.size()==0 )
			{
				new IllegalArgumentException("list.size()==0");
			}
			for( int ii=0; ii<list.size(); ii++ )
			{
				if( ( list.get(ii) instanceof Color ) == false )
				{
					throw new ClassCastException();
				}
			}
			this.mColorList.clear();
			this.mColorList.addAll( list );
		}

	}

}

