

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

import java.awt.BasicStroke;
import java.awt.Color;

import jp.riken.brain.ni.samuraigraph.base.SGDrawingElement;
import jp.riken.brain.ni.samuraigraph.base.SGProperties;
import jp.riken.brain.ni.samuraigraph.base.SGTuple2f;


/**
 * The basic class of the rectangular shape.
 */
public abstract class SGDrawingElementRectangle extends SGDrawingElement
{

	/**
	 * 
	 */
	protected float mX;


	/**
	 * 
	 */
	protected float mY;


	/**
	 * Width of the rectangle.
	 * The negative value is permitted.
	 */
	protected float mWidth;

	/**
	 * Height of the rectangle.
	 * The negative value is permitted.
	 */
	protected float mHeight;


	/**
	 * 
	 */
	protected float mEdgeLineWidth;


	/**
	 * 
	 */
	protected int mEdgeLineType;


	/**
	 * 
	 */
	protected Color mEdgeLineColor;


	/**
	 * 
	 */
	protected boolean mTransparentFlag;



	/**
	 * 
	 */
	protected int mCap = BasicStroke.CAP_BUTT;


	/**
	 * 
	 */
	protected int mJoin = BasicStroke.JOIN_ROUND;


	/**
	 * 
	 */
	protected float mMiterLimit = 1.0f;


	/**
	 * 
	 */
	protected float mDashPhase = 0.0f;



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



	/**
	 * 
	 */
	public void dispose()
	{
		super.dispose();
		this.mEdgeLineColor = null;
	}


	/**
	 * 
	 */
	public float getX()
	{
		return this.mX;
	}


	/**
	 * 
	 */
	public float getY()
	{
		return this.mY;
	}


	/**
	 * 
	 * @return
	 */
	public SGTuple2f getLocation()
	{
		return new SGTuple2f( this.getX(), this.getY() );
	}


	/**
	 * 
	 */
	public float getWidth()
	{
		return this.mWidth;
	}


	/**
	 * 
	 */
	public float getHeight()
	{
		return this.mHeight;
	}


	/**
	 * 
	 */
	public float getEdgeLineWidth()
	{
		return this.mEdgeLineWidth;
	}


	/**
	 * 
	 */
	public Color getEdgeLineColor()
	{
		return this.mEdgeLineColor;
	}


	/**
	 * 
	 * @return
	 */
	public int getEdgeLineType()
	{
		return this.mEdgeLineType;
	}


	/**
	 * 
	 * @return
	 */
	public boolean isTransparent()
	{
		return this.mTransparentFlag;
	}


	/**
	 * 
	 */
	public boolean setEdgeLineWidth( final float width )
	{
		this.mEdgeLineWidth = width;
		return true;
	}


	/**
	 * 
	 * @param type
	 * @return
	 */
	public boolean setEdgeLineType( final int type )
	{
		this.mEdgeLineType = type;
		return true;
	}


	/**
	 * 
	 */
	public boolean setEdgeLineColor( final Color color )
	{
		this.mEdgeLineColor = color;
		return true;
	}


	/**
	 * 
	 */
	public boolean setTransparent( final boolean b )
	{
		this.mTransparentFlag = b;
		return true;
	}


	/**
	 * 
	 */
	public boolean setX( final float x )
	{
		this.mX = x;
		return true;
	}


	/**
	 * 
	 */
	public boolean setY( final float y )
	{
		this.mY = y;
		return true;
	}


	/**
	 * 
	 * @param x
	 * @param y
	 * @return
	 */
	public boolean setLocation( final float x, final float y )
	{
		this.setX(x);
		this.setY(y);
		return true;
	}


	/**
	 * 
	 * @param point
	 * @return
	 */
	public boolean setLocation( final SGTuple2f point )
	{
		this.setLocation( point.x, point.y );
		return true;
	}


	/**
	 * 
	 */
	public boolean setWidth( final float w )
	{
		this.mWidth = w;
		return true;
	}

	/**
	 * 
	 */
	public boolean setHeight( final float h )
	{
		this.mHeight = h;
		return true;
	}


	/**
	 * 
	 * @param w
	 * @param h
	 * @return
	 */
	public boolean setSize( final float w, final float h )
	{
		this.setWidth(w);
		this.setHeight(h);
		return true;
	}


	/**
	 * 
	 */
	public boolean setBounds(
		final float x,
		final float y,
		final float w,
		final float h )
	{
		this.setLocation(x,y);
		this.setSize(w,h);		
		return true;		
	}



	/**
	 * 
	 */
	public boolean setProperty( final SGDrawingElement element )
	{
		if( !(element instanceof SGDrawingElementRectangle) )
		{
			return false;
		}

		if( super.setProperty( element ) == false )
		{
			return false;
		}

		SGDrawingElementRectangle rect = (SGDrawingElementRectangle)element;
		this.setWidth( rect.getWidth() );
		this.setHeight( rect.getHeight() );
		this.setEdgeLineWidth( rect.getEdgeLineWidth() );
		this.setEdgeLineType( rect.getEdgeLineType() );
		this.setEdgeLineColor( rect.getEdgeLineColor() );
		this.setTransparent( rect.isTransparent() );

		return true;
	}




	/**
	 * 
	 */
	public SGProperties getProperties()
	{
		RectangleProperties p = new RectangleProperties();

		if( this.getProperties(p) == false ) return null;

		return p;
	}




	/**
	 * 
	 */
	public boolean getProperties( SGProperties p )
	{
		if( ( p instanceof RectangleProperties ) == false ) return false;

		if( super.getProperties(p) == false ) return false;

		RectangleProperties bp = (RectangleProperties)p;
		bp.setHeight( this.getHeight() );
		bp.setWidth( this.getWidth() );
		bp.setEdgeLineWidth( this.getEdgeLineWidth() );
		bp.setEdgeLineType( this.getEdgeLineType() );
		bp.setEdgeLineColor( this.getEdgeLineColor() );
		bp.setTransparent( this.isTransparent() );

		return true;
	}



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

		if( super.setProperties(p) == false ) return false;

		RectangleProperties bp = (RectangleProperties)p;

		final Float width = bp.getWidth();
		if( width==null )
		{
			return false;
		}
		this.setWidth( width.floatValue() );

		final Float height = bp.getHeight();
		if( height==null )
		{
			return false;
		}
		this.setHeight( height.floatValue() );
		
		final Float edgeLineWidth = bp.getEdgeLineWidth();
		if( edgeLineWidth==null )
		{
			return false;
		}
		this.setEdgeLineWidth( edgeLineWidth.floatValue() );

		final int edgeLineType = bp.getEdgeLineType();
		if( edgeLineType==-1 )
		{
			return false;
		}
		this.setEdgeLineType( edgeLineType );

		final Color edgeLineColor = bp.getEdgeLineColor();
		if( edgeLineColor==null )
		{
			return false;
		}
		this.setEdgeLineColor( edgeLineColor );

		this.setTransparent( bp.isTransparent() );

		return true;
	}



	/**
	 * 
	 */
	public static class RectangleProperties extends DrawingElementProperties
	{
		private float mWidth = 0.0f;
		private float mHeight = 0.0f;
		private float mEdgeLineWidth = 0.0f;
		private int mEdgeLineType = -1;
		private Color mEdgeLineColor = null;
		private boolean mTransparent = false;

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


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

			if( super.equals(obj) == false ) return false;

			RectangleProperties p = (RectangleProperties)obj;
			if( this.mWidth!=p.mWidth ) return false;
			if( this.mHeight!=p.mHeight ) return false;
			if( this.mEdgeLineWidth!=p.mEdgeLineWidth ) return false;
			if( this.mEdgeLineType!=p.mEdgeLineType ) return false;
			if( this.mEdgeLineColor.equals(p.mEdgeLineColor) == false ) return false;
			if( this.mTransparent!=p.mTransparent ) return false;

			return true;
		}


		public Float getWidth()
		{
			return new Float( this.mWidth );
		}

		public Float getHeight()
		{
			return new Float( this.mHeight );
		}

		public Float getEdgeLineWidth()
		{
			return new Float( this.mEdgeLineWidth );
		}

		public int getEdgeLineType()
		{
			return this.mEdgeLineType;
		}

		public Color getEdgeLineColor()
		{
			return this.mEdgeLineColor;
		}

		public boolean isTransparent()
		{
			return this.mTransparent;
		}

		public boolean setWidth( final float value )
		{
			this.mWidth = value;
			return true;
		}

		public boolean setHeight( final float value )
		{
			this.mHeight = value;
			return true;
		}

		public boolean setEdgeLineWidth( final float width )
		{
			if( width<0.0f )
			{
				throw new IllegalArgumentException("width<0.0f");
			}
			this.mEdgeLineWidth = width;
			return true;
		}

		public boolean setEdgeLineType( final int type )
		{
			this.mEdgeLineType = type;
			return true;
		}

		public boolean setEdgeLineColor( final Color cl )
		{
			if( cl==null )
			{
				throw new IllegalArgumentException("cl==null");
			}
			this.mEdgeLineColor = cl;
			return true;
		}

		public boolean setTransparent( final boolean b )
		{
			this.mTransparent = b;
			return true;
		}

	}


}
