/*
 *  iReport  --  Visual designer for generating JasperReports Documents
 *  Copyright (C) 2002  Giulio Toffoli gt@businesslogic.it
 *
 *  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., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Giulio Toffoli
 *  Via T.Aspetti, 233
 *  35100 Padova ITALY
 *  gt@businesslogic.it
 */
package com.businesslogic.ireport;

import com.businesslogic.ireport.ui.*;
import com.businesslogic.ireport.util.*;
import com.ms.wfc.app.*;
import com.ms.wfc.core.*;
import com.ms.wfc.ui.*;


public class ReportElement
{
	static int id_gen=1;
	public String name;
	public Point position;
	public int	 width;
	public int   height;
	Rectangle	 bounds;
	public Brush hached=null;
	public		 Band band;
	public		 String mode;
	
	public		 String printWhenExpression="";
	public		 String positionType="FixRelativeToTop";
	public		 boolean isPrintRepeatedValues=true;
	public		 boolean isRemoveLineWhenBlank=false;
	public		 boolean isPrintInFirstWholeBand=false;
	public		 boolean isPrintWhenDetailOverflows=false;
	public		 static Color lightcolor;
	
	public		 String printWhenGroupChanges="";
		
		
	double zoom_factor=1.0;
	
    public Color bgcolor = null;
	public Color fgcolor = null;
	
	public void drawObject(Graphics g, double zoom_factor, int x_shift_origin, int y_shift_origin)
	{
		position.x -= 10;
		position.y -= 10;
		x_shift_origin -= 10;
		y_shift_origin -= 10;
		
		this.zoom_factor = zoom_factor;
		g.fill( getZoomedDim(position.x)-x_shift_origin,
				getZoomedDim(position.y)-y_shift_origin,
				getZoomedDim(width),
				getZoomedDim(height), new Brush(Color.RED, BrushStyle.DIAGONALCROSS));
		
		g.drawLines(new Point[]{new Point(getZoomedDim(position.x)-x_shift_origin, getZoomedDim(position.y)-y_shift_origin),
								new Point(getZoomedDim(position.x+width)-1-x_shift_origin,getZoomedDim(position.y)-y_shift_origin),
								new Point(getZoomedDim(position.x+width)-1-x_shift_origin,getZoomedDim(position.y+height)-1-y_shift_origin),
								new Point(getZoomedDim(position.x)-x_shift_origin,getZoomedDim(position.y+height)-1-y_shift_origin),
								new Point(getZoomedDim(position.x)-x_shift_origin,getZoomedDim(position.y)-y_shift_origin)});
		
		position.x += 10;
		position.y += 10;
		x_shift_origin -= 10;
		y_shift_origin -= 10;
	}
	
	public void  drawGraphicsElement(Graphics g, String pen, double zoom_factor, int x_shift_origin, int y_shift_origin)
	{
		
		this.zoom_factor = zoom_factor;
		int penp = 0;
		if (pen==null || pen.equalsIgnoreCase("None")) return;
		
		position.x -= 10;
		position.y -= 10;
		x_shift_origin -= 10;
		y_shift_origin -= 10;
		
		if (pen.equalsIgnoreCase("Thin"))   penp=(int)(Math.max(1,1.0*zoom_factor));
		else if (pen.equalsIgnoreCase("1Point")) penp=(int)(Math.max(1,1.0*zoom_factor));
		else if (pen.equalsIgnoreCase("2Point")) penp=(int)(Math.max(1,2.0*zoom_factor));
		else if (pen.equalsIgnoreCase("4Point")) penp=(int)(Math.max(1,4.0*zoom_factor));
		else if (pen.equalsIgnoreCase("Dotted"))
		{
			penp=(int)(Math.max(1,1.0*zoom_factor));
			// 6_2_6_2...
			Pen oldp  = g.getPen();
			g.setPen(new Pen( fgcolor,PenStyle.INSIDEFRAME, penp ));
			
			
			int i=0;
			for ( i= getZoomedDim(position.x) ; i< getZoomedDim(position.x+width)-1; i+=getZoomedDim(8))
			{
				g.drawLine( i-x_shift_origin, getZoomedDim(position.y)-y_shift_origin,
							Math.min(i+getZoomedDim(6),getZoomedDim(position.x+width)-1)-x_shift_origin,getZoomedDim(position.y)-y_shift_origin);
				g.drawLine( i-x_shift_origin, getZoomedDim(position.y+height)-1-y_shift_origin,
							Math.min(i+getZoomedDim(6),getZoomedDim(position.x+width)-1)-x_shift_origin,getZoomedDim(position.y+height)-1-y_shift_origin);
			}
			
			for (i=getZoomedDim(position.y); i< getZoomedDim(position.y+height)-1; i+=getZoomedDim(8))
			{
				g.drawLine( getZoomedDim(position.x)-x_shift_origin ,i-y_shift_origin,
							getZoomedDim(position.x)-x_shift_origin,Math.min(i+getZoomedDim(6),getZoomedDim(position.y+height)-1)-y_shift_origin );
				g.drawLine( getZoomedDim(position.x+width)-1-x_shift_origin, i-x_shift_origin,
							getZoomedDim(position.x+width)-1-x_shift_origin,Math.min(i+getZoomedDim(6),getZoomedDim(position.y+height)-1)-y_shift_origin);
			}
			g.setPen(oldp);
			position.x += 10;
			position.y += 10;
			return;
		}
		
		Pen oldp  = g.getPen();
		g.setPen(new Pen(fgcolor,PenStyle.INSIDEFRAME, penp ));
		/*
		g.drawLines(new Point[]{new Point( getZoomedDim(position.x)-x_shift_origin,
										   getZoomedDim(position.y)-y_shift_origin),
							new Point(getZoomedDim(position.x+width)-1-x_shift_origin,
									  getZoomedDim(position.y)-y_shift_origin ),
							new Point(getZoomedDim(position.x+width)-1-x_shift_origin,
									  getZoomedDim(position.y+height)-1-x_shift_origin),
							new Point(getZoomedDim(position.x)-x_shift_origin,
									  getZoomedDim(position.y+height)-1-x_shift_origin),
							new Point(getZoomedDim(position.x)-x_shift_origin,
									  getZoomedDim(position.y)-y_shift_origin )});
		*/
		Region r = new Region();
		r = r.createRectangular(getZoomedDim(position.x)-x_shift_origin, 
								getZoomedDim(position.y)-y_shift_origin,
								getZoomedDim(width),
								getZoomedDim(height));
		
		Region r2 = new Region();
		r2 = r.createRectangular(getZoomedDim(position.x)+penp-x_shift_origin,
								 getZoomedDim(position.y)+penp-y_shift_origin,
								 getZoomedDim(width)-2*penp,
								 getZoomedDim(height)-2*penp);
		r = r.xorWith(r2);
		g.fill(r, new Brush(fgcolor,BrushStyle.SOLID )); 
		g.setPen(oldp);

		position.x += 10;
		position.y += 10;
	}
	
	
	public void  drawBorder(Graphics g,double zoom_factor, int x_shift_origin, int y_shift_origin)
	{
		if (lightcolor == null) return;
		this.zoom_factor = zoom_factor;
		int penp = 0;
		
		position.x -= 10;
		position.y -= 10;
		x_shift_origin -= 10;
		y_shift_origin -= 10;
		
		penp=1;
				
		Pen oldp  = g.getPen();
		
		Region r = new Region();
		r = r.createRectangular(getZoomedDim(position.x)-x_shift_origin, 
								getZoomedDim(position.y)-y_shift_origin,
								getZoomedDim(width),
								getZoomedDim(height));
		
		Region r2 = new Region();
		r2 = r.createRectangular(getZoomedDim(position.x)+penp-x_shift_origin,
								 getZoomedDim(position.y)+penp-y_shift_origin,
								 getZoomedDim(width)-2*penp,
								 getZoomedDim(height)-2*penp);
		r = r.xorWith(r2);
		Brush br; 
		if ( insideBand() )
		{
			br = new Brush(this.lightcolor,BrushStyle.SOLID );
		} else
		{
			br = new Brush(Color.RED,BrushStyle.SOLID );
		}
			
		g.fill(r, br); 
		g.setPen(oldp);

		position.x += 10;
		position.y += 10;
	}
	
	public void drawCorona(Graphics g, double zoom_factor, int x_shift_origin, int y_shift_origin, boolean selected)
	{
		this.zoom_factor = zoom_factor;
		// draw a  corona...
		position.x -= 10;
		position.y -= 10;
		x_shift_origin -= 10;
		y_shift_origin -= 10;
		
		Region r = new Region();
		r = r.createRectangular(getZoomedDim(position.x)-5-x_shift_origin, 
								getZoomedDim(position.y)-5-y_shift_origin,
								getZoomedDim(width)+10,
								getZoomedDim(height)+10);
		
		Region r2 = new Region();
		r2 = r.createRectangular(getZoomedDim(position.x)-x_shift_origin,
								 getZoomedDim(position.y)-y_shift_origin,
								 getZoomedDim(width),
								 getZoomedDim(height));
		r = r.xorWith(r2);
		if (hached == null)		g.fill(r, new Brush(Color.BLACK,BrushStyle.SOLID )); 
		else	g.fill(r, hached); 
		
		// draw grips...
		Brush blu = new Brush(Color.BLUE);
		if (!selected)
		{
			blu = new Brush(Color.GRAY);
		}
		if ( !insideBand())
		{
		  blu = new Brush(Color.RED);
		} 
		
		g.fill(getZoomedDim(position.x)-5-x_shift_origin, getZoomedDim(position.y)-5-y_shift_origin,5,5, blu);
		g.fill(getZoomedDim(position.x+width)-x_shift_origin, getZoomedDim(position.y)-5-y_shift_origin,5,5, blu);
		g.fill(getZoomedDim(position.x+width)-x_shift_origin, getZoomedDim(position.y+height)-y_shift_origin,5,5, blu);
		g.fill(getZoomedDim(position.x)-5-x_shift_origin, getZoomedDim(position.y+height)-y_shift_origin,5,5, blu);
		
		g.fill(getZoomedDim(position.x+(width/2))-2-x_shift_origin, getZoomedDim(position.y)-5-y_shift_origin,5,5, blu);
		g.fill(getZoomedDim(position.x+(width/2))-2-x_shift_origin, getZoomedDim(position.y+height)-y_shift_origin,5,5, blu);	
		g.fill(getZoomedDim(position.x)-5-x_shift_origin, getZoomedDim(position.y+(height/2))-2-y_shift_origin,5,5, blu);
		g.fill(getZoomedDim(position.x+width)-x_shift_origin, getZoomedDim(position.y+(height/2))-2-y_shift_origin,5,5, blu);
		
		position.x += 10;
		position.y += 10;
	}	
	
	public ReportElement(int x, int y, int width, int height, Brush hached)
	{
		this.position = new Point(x,y);
		this.width=width;
		this.height=height;
		
		bounds = new Rectangle(position.x,position.y,width,height);
		name = "element-"+id_gen;
		id_gen++;
		this.hached = hached;
		
		bgcolor = Color.WHITE;
		fgcolor = Color.BLACK;
		mode = "Opaque";
	}
	
	public boolean intersects(Point p)
	{
		Rectangle r = new Rectangle(bounds);
		if (height == 0)
		{
			r.height = 10;
			r.y -= 5;
		}		
		if (width  == 0)
		{
			r.width = 10;
			r.x -= 5;
		}	
		return r.intersectsWith(new Rectangle(p.x,p.y,1,1));
		/*
		if (p.x > position.x+this.width) return false;
		if (p.x < position.x) return false;
		if (p.y > position.y+height) return false;
		if (p.y < position.y) return false;
		return true;
		*/
	}
	
	public boolean insideBand()
	{
	  if ( band == null )
		  return false; // no parent ?????
      int yband = band.getBandYLocation();
      if ( position.y - yband < 0 )
		  return false;
      if ( position.x - band.parent.leftMargin < 0 )
		  return false;
	  if ( position.y - yband + height > band.height )
		  return false;
	  if ( position.x -  band.parent.leftMargin + width > band.getUsableWidth() )
		return false  ;
      return true; 
	}
	
	public boolean intersects(Rectangle r2)
	{
		Rectangle r = new Rectangle(bounds);
		if (height == 0)
		{
			r.height = 10;
			r.y -= 5;
		}		
		if (width  == 0)
		{
			r.width = 10;
			r.x -= 5;
		}	
		
		return r.intersectsWith(r2);

	}
	
	public void setPosition(Point p)
	{
		if (p == null) return;
		if (p.x == position.x && p.y == position.y) return;
		position.x = p.x;
		position.y = p.y;
		bounds = new Rectangle(position.x,position.y,width,height);
	}
	
	public Point trasform(Point delta, int type)
	{
		if (delta == null) return null;
		Point result = new Point(delta);
		int old_x = 0;
		int old_y = 0;
		if (type == TransformationType.TRANSFORMATION_MOVE)
		{
			position.x += delta.x;
			position.y += delta.y;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_E)
		{
			old_x = width;
			width += delta.x;
			if (width <0) width=0;
			result.x = width - old_x;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_W)
		{
			old_x = width;
			int d = Math.min(delta.x,width);
			width -= d;
			position.x += d;
			result.x = d;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_N)
		{
			int d = Math.min(delta.y,height);
			height -= d;
			position.y += d;
			result.y = d;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_S)
		{
			old_y = height;
			height += delta.y;
			if (height <0) height=0;
			result.y = height - old_y;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_SE)
		{
			old_y = height;
			old_x = width;
			height += delta.y;
			if (height <0) height=0;
			width += delta.x;
			if (width <0) width=0;
			result.x = width - old_x;
			result.y = height - old_y;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_SW)
		{
			old_y = height;
			height += delta.y;
			if (height <0) height=0;
			int d = Math.min(delta.x,width);
			width -= d;
			position.x += d;
			
			result.x = d;
			result.y = height - old_y;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_NE)
		{
			old_x = width;
			int d = Math.min(delta.y,height);
			height -= d;
			position.y += d;
			width += delta.x;
			if (width <0) width=0;
			result.x = width - old_x;
			result.y = d;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_NW)
		{
			
			int d = Math.min(delta.y,height);
			height -= d;
			position.y += d;
			result.y = d;
			d = Math.min(delta.x,width);
			width -= d;
			position.x += d;
			result.x = d;
		}

		bounds = new Rectangle(position.x,position.y,width,height);
		return result;
	}
	
	
	public Point trasformTest(Point delta, int type)
	{
		if (delta == null) return null;
		Point result = new Point(delta);
		int old_x = 0;
		int old_y = 0;
		if (type == TransformationType.TRANSFORMATION_MOVE)
		{
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_E)
		{
			old_x = width;
			old_x += delta.x;
			if (old_x <0) old_x=0;
			result.x = old_x-width;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_W)
		{
			result.x = Math.min(delta.x,width);
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_N)
		{
			result.y = Math.min(delta.y,height);
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_S)
		{
			old_y = height;
			old_y += delta.y;
			if (old_y <0) old_y=0;
			result.y = old_y - height;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_SE)
		{
			old_y = height;
			old_x = width;
			old_y += delta.y;
			if (old_y <0) old_y=0;
			old_x += delta.x;
			if (old_x <0) old_x=0;
			result.x = old_x - width;
			result.y = old_y - height;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_SW)
		{
			old_y = height;
			old_y += delta.y;
			if (old_y <0) old_y=0;
			result.x = Math.min(delta.x,width);
			result.y =old_y - height;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_NE)
		{
			old_x = width;
			result.y = Math.min(delta.y,height);
			old_x += delta.x;
			if (old_x <0) old_x=0;
			result.x = old_x - width;
		}
		else if (type == TransformationType.TRANSFORMATION_RESIZE_NW)
		{
			
			result.y = Math.min(delta.y,height);
			result.x = Math.min(delta.x,width);
		}
		return result;
	}
	
	public String toString()
	{
		return name+" "+position;
	}
	
	public int getZoomedDim(int dim)
	{
		if (zoom_factor == 1.0) return dim;
		//if (((double)dim*(double)zoom_factor)<0.5) return 1;
		// Truncate, don't round!!
		return (int)((double)dim*zoom_factor);
		//return (int)Math.ceil((double)dim*zoom_factor);
	}
		
	public double getZoomedDim(double dim)
	{
		if (zoom_factor == 1.0) return dim;
		//if (((double)dim*(double)zoom_factor)<0.5) return 1;
		// Truncate, don't round!!
		return ((double)dim*zoom_factor);
		//return (int)Math.ceil((double)dim*zoom_factor);
	}
	
	public int getLogicalDim(int dim)
	{
		if (zoom_factor == 1.0) return dim;
		//if (Math.abs(  ((double)dim/(double)zoom_factor)) < 1 &&
		//	Math.abs(  ((double)dim/(double)zoom_factor)) > 0) return 1;
		// Truncate, don't round!!
		return (int)((double)dim/zoom_factor);
		//return (int)Math.ceil((double)dim/zoom_factor);
	}
	
	
	public ReportElement cloneMe()
	{
		ReportElement newReportElement = new ReportElement(position.x, position.y, width, height, hached);
		copyElementPropertiesTo(newReportElement);
		return newReportElement;
	}
	
	public void copyElementPropertiesTo(ReportElement newReportElement)
	{
		newReportElement.printWhenExpression = printWhenExpression;
	    newReportElement.positionType = positionType;
	    newReportElement.isPrintRepeatedValues = isPrintRepeatedValues;
	    newReportElement.isRemoveLineWhenBlank = isRemoveLineWhenBlank;
	    newReportElement.isPrintInFirstWholeBand = isPrintInFirstWholeBand;
	    newReportElement.isPrintWhenDetailOverflows = isPrintWhenDetailOverflows;
		newReportElement.name = name; 
		newReportElement.band = band;
		newReportElement.mode = mode;	
		newReportElement.bgcolor = bgcolor;
	    newReportElement.fgcolor = fgcolor;		  
	}
	
	public static String string_replace(String s1, String s2, String s3)
 {
	   String string="";
	   string = "";

    	if (s2 == null || s3 == null || s2.length() == 0) return s3;
	   
	   int pos_i = 0; // posizione corrente.
	   int pos_f = 0; // posizione corrente finale
	   
	   int len = s2.length();
	   while ( (pos_f = s3.indexOf(s2, pos_i)) >= 0)
	   {
		   string += s3.substring(pos_i,pos_f)+s1;
		   //+string.substring(pos+ s2.length());
		   pos_f = pos_i = pos_f + len;

	   }

	   string += s3.substring(pos_i);

	   return string;
 }
}
