/*
 * ReportElement.java
 *
 *  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
 *
 *
 *  Created on 22 febbraio 2003, 15.03
 *
 *  Updated 3 July 2003, 2004 by Robert Lamping
 *  - Added: adjustBand()
      Moving a element will trigger iReports to see whether
 *    an element is entirely within another band
 *    If so, the element's band is modified to the band it is placed in.
 *  - Modified: trasform()
 *    Included adjustBand() at the end.
 *  Updated 3 July 2003, 2004 by Robert Lamping
 *  - added updateBounds in setHeight() and setWidth()
 */
package it.businesslogic.ireport;

import it.businesslogic.ireport.gui.*;
import it.businesslogic.ireport.util.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.util.Iterator;
import java.util.Vector;

public class ReportElement {
    
    static int id_gen=1;
    public String name;
    public Point position;
    public int width;
    public int height;
    Rectangle bounds;
    public static BufferedImage hached=null;
    public Band band;
    public String transparent;
    
    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;
    
    protected String stretchType;
    protected String elementGroup = "";
    
    
    public Vector intersections = new Vector();
    
    
    
    public ReportElement(int x, int y, int width, int height) {
        if (hached == null){
            hached = Misc.loadBufferedImageFromResources(new java.awt.Panel() ,"it/businesslogic/ireport/icons/layout/hached.gif");
        }
        this.position = new Point(x,y);
        this.width= Math.abs(width);
        this.height=Math.abs(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;
        
        if (lightcolor == null) {
            lightcolor = Color.LIGHT_GRAY;
        }
        transparent = "Opaque";
        stretchType = "NoStretch";
    }
    
    
    public void drawObject(Graphics2D 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.setPaint( new TexturePaint( red, new Rectangle2D.Double( zoomed_width+10-horizontal_scroll,9-vertical_scroll,9,9)));
        
        g.fillRect( getZoomedDim(position.x)-x_shift_origin,
        getZoomedDim(position.y)-y_shift_origin,
        getZoomedDim(width),
        getZoomedDim(height));
        
        //g.drawRect(getZoomedDim(position.x)-x_shift_origin, getZoomedDim(position.y)-y_shift_origin, getZoomedDim(width), getZoomedDim(height));
        
        position.x += 10;
        position.y += 10;
        x_shift_origin += 10;
        y_shift_origin += 10;
        
        drawGraphicsElement(g,"2Point", zoom_factor,  x_shift_origin,y_shift_origin);
        drawBorder(g, zoom_factor,  x_shift_origin,y_shift_origin);
    }
    
    public void  drawGraphicsElement(Graphics2D g, String pen, double zoom_factor, int x_shift_origin, int y_shift_origin) {
        drawGraphicsElement( g, pen, zoom_factor, x_shift_origin, y_shift_origin,0);
    }
    
    public void  drawGraphicsElement(Graphics2D g, String pen, double zoom_factor, int x_shift_origin, int y_shift_origin,int radius) {
        
        int correction = (zoom_factor <= 1 && (pen.equals("Thin") || pen.equals("1Point") || pen.equals("Dotted") )  ) ? -1 : 0;
        int xy_correction = (zoom_factor <= 1 && pen.equals("Dotted")) ? 1 : 0;
        
        Stroke stroke = getPenStroke( pen,zoom_factor );
        g.setColor( this.fgcolor );
        
        this.zoom_factor = zoom_factor;
        if (stroke==null || pen.equalsIgnoreCase("None")) return;
        
        position.x -= 10;
        position.y -= 10;
        x_shift_origin -= 10;
        y_shift_origin -= 10;
        
        Stroke oldStroke = g.getStroke();
        g.setStroke(stroke);
        
        
        if (radius != 0) {
            g.drawRoundRect(
            getZoomedDim(position.x)-x_shift_origin+xy_correction,
            getZoomedDim(position.y)-y_shift_origin+xy_correction,
            getZoomedDim(width)+correction,getZoomedDim(height)+correction,radius,radius);
        }
        else {
            g.drawRect(
            getZoomedDim(position.x)-x_shift_origin+xy_correction,
            getZoomedDim(position.y)-y_shift_origin+xy_correction,
            getZoomedDim(width) + correction,getZoomedDim(height)+correction);
        }
        
        position.x += 10;
        position.y += 10;
        
        g.setStroke(oldStroke);
    }
    
     public void  drawBorder(Graphics2D g,double zoom_factor, int x_shift_origin, int y_shift_origin) 
     {
         drawBorder(g, zoom_factor, x_shift_origin, y_shift_origin, null );
     }
     
     public void  drawBorder(Graphics2D g,double zoom_factor, int x_shift_origin, int y_shift_origin, Box box) 
     {
        this.zoom_factor = zoom_factor;
        
        int correction = (zoom_factor <= 1 ) ? -1 : 0;
                
        position.x -= 10;
        position.y -= 10;
        x_shift_origin -= 10;
        y_shift_origin -= 10;
        
        Stroke oldStroke = g.getStroke();
        
        
        if (box == null || !insideBand())
        {
            if ( insideBand() ) {
                g.setColor( lightcolor);
            } else {
                g.setColor( Color.RED);
            }
            g.drawRect(
                getZoomedDim(position.x)-x_shift_origin,
                getZoomedDim(position.y)-y_shift_origin,
                getZoomedDim(width) + correction,getZoomedDim(height)+correction);
        }
        else
        {
               // Left side
                boolean insideBand =  insideBand();
                int ax = getZoomedDim(position.x)-x_shift_origin;
                int ay = getZoomedDim(position.y)-y_shift_origin;
                int bx = ax+getZoomedDim(width)+correction;
                int by = ay+getZoomedDim(height)+correction;
                
                Stroke newBoxStroke = null;
                
                if (box.getLeftBorderColor() != null)  { g.setColor( box.getLeftBorderColor() ); }
                else g.setColor( lightcolor );
                if ((newBoxStroke = getPenStroke(box.getLeftBorder(),zoom_factor )) != null)
                {
                        g.setStroke( newBoxStroke );
                        g.drawLine(ax, ay, ax, by);
                }
                //else g.setStroke(oldStroke);
               
                
                if (box.getTopBorderColor() != null)  { g.setColor( box.getTopBorderColor() ); }
                else g.setColor( lightcolor );
                if ((newBoxStroke = getPenStroke(box.getTopBorder(),zoom_factor )) != null)
                {
                        g.setStroke( newBoxStroke );
                        g.drawLine(ax, ay, bx, ay);
                }
                
                if (box.getRightBorderColor() != null)  { g.setColor( box.getRightBorderColor() ); }
                else g.setColor( lightcolor );
                if ((newBoxStroke = getPenStroke(box.getRightBorder(),zoom_factor )) != null)
                {
                        g.setStroke( newBoxStroke );
                        g.drawLine(bx, ay, bx, by);
                } 
                
                if (box.getBottomBorderColor() != null)  { g.setColor( box.getBottomBorderColor() ); }
                else g.setColor( lightcolor );
                if ((newBoxStroke = getPenStroke(box.getBottomBorder(),zoom_factor )) != null)
                {
                        g.setStroke( newBoxStroke );
                        g.drawLine(ax, by, bx, by);
                }
                
                
                g.setStroke(oldStroke);
        }

        position.x += 10;
        position.y += 10;
        x_shift_origin += 10;
        y_shift_origin += 10;
    }
    
    public void drawCorona(Graphics2D 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;
        
        Rectangle2D r =  new Rectangle2D.Double(getZoomedDim(position.x)-5-x_shift_origin,
        getZoomedDim(position.y)-5-y_shift_origin,
        getZoomedDim(width)+10,
        getZoomedDim(height)+10);
        
        Rectangle2D r2 = new Rectangle2D.Double( getZoomedDim(position.x)-x_shift_origin,
        getZoomedDim(position.y)-y_shift_origin,
        getZoomedDim(width),
        getZoomedDim(height));
        java.awt.geom.Area area = new Area(r);
        area.exclusiveOr( new Area(r2));
        if (hached == null) {
            g.fill(area);
        }
        else {
            g.setPaint( new java.awt.TexturePaint( hached, new Rectangle2D.Double(0,0,2,2 ) ));
            g.fill(area);
        }
        // draw grips...
        g.setPaint(Color.BLUE);
        
        if (!selected) {
            g.setPaint(Color.GRAY);
        }
        
        // checking overlaps slows down the repainting
        if (intersectsElements() ) {
            if ( enclosesOtherElement() ) {
                g.setPaint(Color.PINK);
            } else {
                g.setPaint(Color.GREEN);
            }
            
        }
        
        if ( !insideBand()) {
            g.setPaint(Color.RED);
        }
        
        g.fillRect(getZoomedDim(position.x)-5-x_shift_origin, getZoomedDim(position.y)-5-y_shift_origin,5,5);
        g.fillRect(getZoomedDim(position.x+width)-x_shift_origin, getZoomedDim(position.y)-5-y_shift_origin,5,5);
        g.fillRect(getZoomedDim(position.x+width)-x_shift_origin, getZoomedDim(position.y+height)-y_shift_origin,5,5);
        g.fillRect(getZoomedDim(position.x)-5-x_shift_origin, getZoomedDim(position.y+height)-y_shift_origin,5,5);
        
        g.fillRect(getZoomedDim(position.x+(width/2))-2-x_shift_origin, getZoomedDim(position.y)-5-y_shift_origin,5,5);
        g.fillRect(getZoomedDim(position.x+(width/2))-2-x_shift_origin, getZoomedDim(position.y+height)-y_shift_origin,5,5);
        g.fillRect(getZoomedDim(position.x)-5-x_shift_origin, getZoomedDim(position.y+(height/2))-2-y_shift_origin,5,5);
        g.fillRect(getZoomedDim(position.x+width)-x_shift_origin, getZoomedDim(position.y+(height/2))-2-y_shift_origin,5,5);
        
        position.x += 10;
        position.y += 10;
    }
    
    public boolean enclosesOtherElement() {
        for (Iterator i = intersections.iterator(); i.hasNext(); ) {
            ReportElement e = (ReportElement) i.next();
            if (bounds.contains(e.bounds) ) {
                return true;
            }
        }
        return false;
    }
    
    public boolean intersectsElements() {
        int oldHeight = 0;
        boolean result = false;
        
        // do not stop after you found an intersection
        // list them all so that
        // later on you can see whether one is hidden or enclosed by the
        // current element.
        for (Iterator i = band.getParent().getElements().iterator(); i.hasNext(); ) {
            ReportElement e = (ReportElement) i.next();
            
            // do not compare with 'this' reportElement
            if ( ! this.equals( e ) ) {
                oldHeight = e.height;
                
                // make lines a little heigher,so that they can intersect
                // with a rectangle
                if (e.height == 0 ) {
                    e.height = 10;
                }
                
                if (e.bounds.intersects(bounds) ) {
                    // store the intersecting rectangle
                    this.intersections.add( e );
                    result = true;
                }
                e.height = oldHeight;
            }
        }
        
        return result;
    }
    
    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.intersects(p.x,p.y,1,1);
    }
    
    public boolean insideBandReal() {
        position.x -= 10;
        position.y -= 10;
        
        boolean result = insideBand();
        
        position.x += 10;
        position.y += 10;
        
        return result;
    }
    public boolean insideBand() {
        if ( band == null )
            return false; // no parent ?????
        
        int yband = band.getBandYLocation();
        
        // lower left corner of element is below the band.
        if ( position.y - yband < 0 )
            return false;
        
        // lower left corner of element is left from the left margin
        if ( position.x - band.getParent().getLeftMargin() < 0 )
            return false;
        
        // with element on the bottom the element is too high for the band
        if ( position.y - yband + height > band.getHeight() )
            return false;
        
        // with element on the left margin, the width is larger than usable width of page.
        if ( position.x -  band.getParent().getLeftMargin() + 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.intersects(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;
    }
    
    /**
     * Try to move the element to another band if the element is placed entirely
     * within the band.
     *
     * @author RFL
     */
    
    public void adjustBand() {
        position.x -= 10;
        position.y -= 10;
        
        for (Iterator i = band.getParent().getBands().iterator(); i.hasNext(); ) {
            Band b = (Band) i.next();
            
            if ( position.y - band.getParent().getBandYLocation(b) >= 0) {
                if ( position.y - band.getParent().getBandYLocation(b) + height <= b.getHeight() ) {
                    // element is within this band.
                    band = b;
                    break;
                }
            }
        }
        
        position.x += 10;
        position.y += 10;
    }
    
    /*
     *  This method should be called when you modify height, width,
     *  or position manually.
     */
    public void updateBounds() {
        bounds = new Rectangle(position.x,position.y,width,height);
    }
    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.x-band.getParent().getRightMargin()-10)+","+ (position.y-band.getBandYLocation()-10) + "]";
    }
    
    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);
        newReportElement.name = new String(name);
        newReportElement.band = band;
        newReportElement.transparent = transparent;
        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;
    }
    
    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;
    }
    
    public static Stroke getPenStroke(String pen, double zoom_factor) {
        
        if (pen == null || pen.equals("None")) return null;
        if (pen.equals("Dotted")) {
            return (Stroke)new BasicStroke(
            (float)(1f * zoom_factor),
            BasicStroke.CAP_BUTT,
            BasicStroke.JOIN_BEVEL,
            0f,
            new float[]{5f, 3f},
            0f
            );
        }
        else if (pen.equals("2Point")) {
            return (Stroke)new BasicStroke((float)(2f*zoom_factor));
        }
        else if (pen.equals("3Point")) {
            return (Stroke)new BasicStroke((float)(3f*zoom_factor));
        }
        else if (pen.equals("4Point")) {
            return (Stroke)new BasicStroke((float)(4f*zoom_factor));
        }
        else if (pen.equals("Thin")) {
            
            return (Stroke)new BasicStroke( (float)(1f*zoom_factor));
        }
        else //if (pen.equals("1Point"))
        {
            return (Stroke)new BasicStroke((float)(1f*zoom_factor));
        }
    }
    
    
    
    
    /** Getter for property width.
     * @return Value of property width.
     *
     */
    public int getWidth() {
        return width;
    }
    
    /** Setter for property width.
     * @param width New value of property width.
     *
     */
    public void setWidth(int width) {
        this.width = width;
        updateBounds();
    }
    
    /** Getter for property height.
     * @return Value of property height.
     *
     */
    public int getHeight() {
        return height;
    }
    
    /** Setter for property height.
     * @param height New value of property height.
     *
     */
    public void setHeight(int height) {
        this.height = height;
        updateBounds();
    }
    
    /** Getter for property position.
     * @return Value of property position.
     *
     */
    public java.awt.Point getPosition() {
        return position;
    }
    
    /** Getter for property band.
     * @return Value of property band.
     *
     */
    public it.businesslogic.ireport.Band getBand() {
        return band;
    }
    
    /** Setter for property band.
     * @param band New value of property band.
     *
     */
    public void setBand(it.businesslogic.ireport.Band band) {
        this.band = band;
    }
    
    /** Getter for property transparent.
     * @return Value of property transparent.
     *
     */
    public java.lang.String getTransparent() {
        return transparent;
    }
    
    /** Setter for property transparent.
     * @param transparent New value of property transparent.
     *
     */
    public void setTransparent(java.lang.String transparent) {
        this.transparent = transparent;
    }
    
    /** Getter for property positionType.
     * @return Value of property positionType.
     *
     */
    public java.lang.String getPositionType() {
        return positionType;
    }
    
    /** Setter for property positionType.
     * @param positionType New value of property positionType.
     *
     */
    public void setPositionType(java.lang.String positionType) {
        this.positionType = positionType;
    }
    
    /** Getter for property isPrintInFirstWholeBand.
     * @return Value of property isPrintInFirstWholeBand.
     *
     */
    public boolean isIsPrintInFirstWholeBand() {
        return isPrintInFirstWholeBand;
    }
    
    /** Setter for property isPrintInFirstWholeBand.
     * @param isPrintInFirstWholeBand New value of property isPrintInFirstWholeBand.
     *
     */
    public void setIsPrintInFirstWholeBand(boolean isPrintInFirstWholeBand) {
        this.isPrintInFirstWholeBand = isPrintInFirstWholeBand;
    }
    
    /** Getter for property printWhenExpression.
     * @return Value of property printWhenExpression.
     *
     */
    public java.lang.String getPrintWhenExpression() {
        return printWhenExpression;
    }
    
    /** Setter for property printWhenExpression.
     * @param printWhenExpression New value of property printWhenExpression.
     *
     */
    public void setPrintWhenExpression(java.lang.String printWhenExpression) {
        this.printWhenExpression = printWhenExpression;
    }
    
    /** Getter for property isPrintRepeatedValues.
     * @return Value of property isPrintRepeatedValues.
     *
     */
    public boolean isIsPrintRepeatedValues() {
        return isPrintRepeatedValues;
    }
    
    /** Setter for property isPrintRepeatedValues.
     * @param isPrintRepeatedValues New value of property isPrintRepeatedValues.
     *
     */
    public void setIsPrintRepeatedValues(boolean isPrintRepeatedValues) {
        this.isPrintRepeatedValues = isPrintRepeatedValues;
    }
    
    /** Getter for property fgcolor.
     * @return Value of property fgcolor.
     *
     */
    public java.awt.Color getFgcolor() {
        return fgcolor;
    }
    
    /** Setter for property fgcolor.
     * @param fgcolor New value of property fgcolor.
     *
     */
    public void setFgcolor(java.awt.Color fgcolor) {
        this.fgcolor = fgcolor;
    }
    
    /** Getter for property bgcolor.
     * @return Value of property bgcolor.
     *
     */
    public java.awt.Color getBgcolor() {
        return bgcolor;
    }
    
    /** Setter for property bgcolor.
     * @param bgcolor New value of property bgcolor.
     *
     */
    public void setBgcolor(java.awt.Color bgcolor) {
        this.bgcolor = bgcolor;
    }
    
    /** Getter for property isRemoveLineWhenBlank.
     * @return Value of property isRemoveLineWhenBlank.
     *
     */
    public boolean isIsRemoveLineWhenBlank() {
        return isRemoveLineWhenBlank;
    }
    
    /** Setter for property isRemoveLineWhenBlank.
     * @param isRemoveLineWhenBlank New value of property isRemoveLineWhenBlank.
     *
     */
    public void setIsRemoveLineWhenBlank(boolean isRemoveLineWhenBlank) {
        this.isRemoveLineWhenBlank = isRemoveLineWhenBlank;
    }
    
    /** Getter for property printWhenGroupChanges.
     * @return Value of property printWhenGroupChanges.
     *
     */
    public java.lang.String getPrintWhenGroupChanges() {
        return printWhenGroupChanges;
    }
    
    /** Setter for property printWhenGroupChanges.
     * @param printWhenGroupChanges New value of property printWhenGroupChanges.
     *
     */
    public void setPrintWhenGroupChanges(java.lang.String printWhenGroupChanges) {
        this.printWhenGroupChanges = printWhenGroupChanges;
    }
    
    /** Getter for property name.
     * @return Value of property name.
     *
     */
    public java.lang.String getName() {
        return name;
    }
    
    /** Setter for property name.
     * @param name New value of property name.
     *
     */
    public void setName(java.lang.String name) {
        this.name = name;
    }
    
    /** Getter for property isPrintWhenDetailOverflows.
     * @return Value of property isPrintWhenDetailOverflows.
     *
     */
    public boolean isIsPrintWhenDetailOverflows() {
        return isPrintWhenDetailOverflows;
    }
    
    /** Setter for property isPrintWhenDetailOverflows.
     * @param isPrintWhenDetailOverflows New value of property isPrintWhenDetailOverflows.
     *
     */
    public void setIsPrintWhenDetailOverflows(boolean isPrintWhenDetailOverflows) {
        this.isPrintWhenDetailOverflows = isPrintWhenDetailOverflows;
    }
    
    public void  copyBaseReportElement(ReportElement destination, ReportElement source) {
        // Canonical report elements....
        destination.setName( new String(source.getName()) );
        destination.setBgcolor( source.getBgcolor());
        destination.setFgcolor( source.getFgcolor() );
        destination.setBand( source.getBand() );
        destination.setPositionType(new String(source.getPositionType()));
        destination.setIsPrintRepeatedValues( source.isIsPrintRepeatedValues());
        destination.setIsPrintWhenDetailOverflows( source.isIsPrintWhenDetailOverflows());
        destination.setIsRemoveLineWhenBlank(source.isIsRemoveLineWhenBlank());
        destination.setPrintWhenExpression(new String( source.getPrintWhenExpression()));
        destination.setPrintWhenGroupChanges(new String(source.getPrintWhenGroupChanges()));
        destination.setTransparent(new String(source.getTransparent()));
        destination.setIsPrintInFirstWholeBand(source.isIsPrintInFirstWholeBand());
    }
    
    
    
    
    /** Getter for property key.
     * @return Value of property key.
     *
     */
    public java.lang.String getKey() {
        return name;
    }
    
    /** Setter for property key.
     * @param key New value of property key.
     *
     */
    public void setKey(java.lang.String key) {
        this.name = key;
    }
    
    
    
    /** Getter for property stretchType.
     * @return Value of property stretchType.
     *
     */
    public java.lang.String getStretchType() {
        return stretchType;
    }
    
    /** Setter for property stretchType.
     * @param stretchType New value of property stretchType.
     *
     */
    public void setStretchType(java.lang.String stretchType) {
        this.stretchType = stretchType;
    }
    
    /**
     * Getter for property bounds.
     * @return Value of property bounds.
     */
    public java.awt.Rectangle getBounds() {
        return bounds;
    }    
    
    /**
     * Setter for property bounds.
     * @param bounds New value of property bounds.
     */
     public void setBounds(java.awt.Rectangle bounds) {
         this.position.x = bounds.x;
         this.position.y = bounds.y;
         this.width = bounds.width;
         this.height = bounds.height;
         this.updateBounds();
    }    
    
    public void addToGroup(String groupname)
    {
    	if (elementGroup == null || elementGroup.equals("")) elementGroup += groupname;
    	else elementGroup = groupname + "." + elementGroup;
    }
    
    public void removeFromGroup(String groupname)
    {
    	if (elementGroup == null || elementGroup.equals("")) return;
    	if (elementGroup.startsWith(groupname))
    	{
    		elementGroup = elementGroup.substring(groupname.length());
    		if (elementGroup.startsWith(".")) elementGroup = elementGroup.substring(1);
    	}
    }
    
    public void removeFromAllGroups()
    {
    	elementGroup="";
    }
} 