/*
 * Report.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 10 febbraio 2003, 19.32
 * 
 * Updated by Robert Lamping:
 * dtd updated with the new package path net/sf/  etc...
 * Added Try catch to catch a missing dtd.
 * Changed Mainframe.openFile to catch this exception and stop opening a file in case of an exception.
 */

package it.businesslogic.ireport;

//import java.util.*;
import java.util.Vector;
import java.util.Iterator;
import java.util.Properties;
import java.util.Enumeration;

import java.awt.Point;

import it.businesslogic.ireport.JRField;

//import it.businesslogic.ireport.util.*;
import it.businesslogic.ireport.util.Misc;
import it.businesslogic.ireport.util.PageSize;
import it.businesslogic.ireport.gui.JReportFrame;
import it.businesslogic.ireport.gui.event.*;

//import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.JRReport;
import net.sf.jasperreports.engine.JasperManager;

import org.apache.xerces.parsers.DOMParser;

//import org.w3c.dom.*;
import org.w3c.dom.Document;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import org.xml.sax.SAXException;

import java.io.IOException;
import java.io.File;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;


//import org.syntax.jedit.*;
import org.syntax.jedit.IReportKeywordLookup;
import org.syntax.jedit.KeywordLookupIF;

/**
 *
 * @author  Administrator
 */
public class Report {
    
    public static int SCRIPTLET_IREPORT_INTERNAL_HANDLING = 1;
    public static int SCRIPTLET_NOT_USED = 0;
    public static int SCRIPTLET_CLASSIC_HANDLING = 2;
    
    private IReportFont defaultFont = new IReportFont();
    
    private boolean modified = true;
    
    private boolean readOnly = false;
    
    private int height = 0;
    
    private int width = 0;
    
    private String name = "";
    
    private Vector elements = new Vector();
    
    private Vector bands = new Vector();
    
    private Vector groups = new Vector();
    
    private Vector imports = new Vector();
    
    private String filename = "";
    
    private String query = "";
    
    private String encoding = "UTF-8";
    
    private int columnCount = 1;
    
    private String printOrder = "Vertical";
    
    private String orientation = "Portrait";
    
    private String whenNoDataType = "NoPages";
    
    private int columnWidth = 535;
    
    private int columnSpacing = 0 ;
    
    private int leftMargin = 20;
    
    private int rightMargin = 20;
    
    private int topMargin = 30;
    
    private int bottomMargin = 30;
    
    private boolean isTitleNewPage = false;
    
    private boolean isSummaryNewPage = false;
    
    private String scriptletClass = "";
    
    private long loadTime = 0;
    
    private Vector fields = new Vector();
    
    private Vector parameters = new Vector();
    
    private Vector variables = new Vector();
    
    private Vector fonts = new Vector();
    
    private JReportFrame reportFrame;
    
    private String reportFormat;
    
    static int untitledId = 1;
    
    private int dirty = 1;
    
    private String ResourceBundleBaseName = "";
    
    private IReportKeywordLookup keywordLookup = new IReportKeywordLookup();
    
    private boolean floatColumnFooter = false;
    
    
    /** used to tell the report when outputting to XML that it needs to set isCode="true" in expressions */
    protected boolean usingMultiLineExpressions = false;
    
    private java.util.Vector JRproperties = new Vector();
    
    private ScriptletCode scripletCode;
    
    private int scriptletHandling = 2;
    
     private String language = "java";

     private java.util.HashMap proposedValues = null;
     
    /**
     * Utility field used by event firing mechanism.
     */
    private javax.swing.event.EventListenerList listenerList =  null;
     
    /** Creates a new instance of Report */
    
    public Report() {
        name = "Untitled_report_" + untitledId;
        untitledId++;
        
        proposedValues = new java.util.HashMap();
        // Add basic variables...
        addVariable(new JRVariable("PAGE_NUMBER","java.lang.Integer", true ));
        addVariable(new JRVariable("COLUMN_NUMBER","java.lang.Integer", true));
        addVariable(new JRVariable("REPORT_COUNT","java.lang.Integer", true));
        addVariable(new JRVariable("PAGE_COUNT","java.lang.Integer", true));
        addVariable(new JRVariable("COLUMN_COUNT","java.lang.Integer", true));
        
        addParameter(new JRParameter("REPORT_PARAMETERS_MAP","java.util.Map",false,"",true));
        addParameter(new JRParameter("REPORT_CONNECTION","java.sql.Connection",false,"",true));
        addParameter(new JRParameter("REPORT_DATASOURCE","net.sf.jasperreports.engine.JRDataSource",false,"",true));
        addParameter(new JRParameter("REPORT_SCRIPTLET","net.sf.jasperreports.engine.JRAbstractScriptlet",false,"",true));
        addParameter(new JRParameter("REPORT_LOCALE","java.util.Locale",false,"",true));
        addParameter(new JRParameter("REPORT_RESOURCE_BUNDLE","java.util.ResourceBundle",false,"",true));
        addParameter(new JRParameter("REPORT_MAX_COUNT","java.lang.Integer",false,"",true));
        
        
        keywordLookup.addKeyword("$R{*}");
        
        //addParameter(new JRParameter("COLUMN_COUNT", "", ));
        
        bands.addElement( new Band(this,"background",0) );
        bands.addElement( new Band(this,"title", 50));
        bands.addElement( new Band(this,"pageHeader", 50) );
        bands.addElement( new Band(this,"columnHeader",30) );
        bands.addElement( new Band(this,"detail",100));
        bands.addElement( new Band(this,"columnFooter",30) );
        bands.addElement( new Band(this,"pageFooter",50));
        bands.addElement( new Band(this,"lastPageFooter",50));
        bands.addElement( new Band(this,"summary",50) );
        
        //addImport("it.businesslogic.ireport.IReportScriptlet");
        addImport("java.util.*");
        addImport("net.sf.jasperreports.engine.*");
        addImport("net.sf.jasperreports.engine.data.*");
        
        try {
            scripletCode = new ScriptletCode(ScriptletCode.class.getClassLoader().getResourceAsStream("scriptlet_template.jav"));
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        
        // Set the user option default...
        this.setLanguage( it.businesslogic.ireport.gui.MainFrame.getMainInstance().getProperties().getProperty("DefaultScriptingLanguage","java") );
    }

    /** Creates a new instance of Report reading it by a file...*/
    public Report(String xmlFile) throws Exception {

        this();
        
        // Set the real default...
        this.setLanguage("java");
        untitledId--;

        //reset bands, prevents page height overflow for unused bands
        for(int i = 0; i < bands.size(); i++) {
            ((Band)bands.elementAt(i)).setHeight(0);
        }
        
        //  Create a Xerces DOM Parser
        //  Parse the Document
        //  and traverse the DOM

        this.setFilename(xmlFile);
        checkReadOnlyFlag();

        // set load time...
        this.setLoadTime( Misc.getLastWriteTime( xmlFile ));

        try {
            
            if (xmlFile.toLowerCase().endsWith(".jasper")) {
                JRReport report = JasperManager.loadReport(xmlFile);
                this.setWidth(report.getPageWidth());
                this.setHeight(report.getPageHeight());
                this.setTopMargin(report.getTopMargin());
                this.setLeftMargin(report.getLeftMargin());
                this.setBottomMargin(report.getBottomMargin());
                this.setRightMargin(report.getRightMargin());
                this.setOrientation( ( (report.getOrientation() == JRReport.ORIENTATION_PORTRAIT) ? "Portrait" : "Landscape"));
                this.setColumnCount( report.getColumnCount() );
                this.setColumnSpacing( report.getColumnSpacing());
                this.setColumnWidth( report.getColumnWidth());
                this.setQuery( ( report.getQuery() != null) ? report.getQuery().getText() : "");
                
                // Read all bands...
                net.sf.jasperreports.engine.JRField[] reportFields = report.getFields();
                for (int i=0; reportFields != null && i<reportFields.length; ++i) {
                    it.businesslogic.ireport.JRField field = 
                      new it.businesslogic.ireport.JRField(  reportFields[i].getName(), 
                                    reportFields[i].getValueClass().getClass().getName());
                    field.setDescription( reportFields[i].getDescription());
                    addField(field);
                }
                
            } else {
                DOMParser parser = new DOMParser();
                
                 java.io.InputStream input_source = null;
                 File ffile = new File(xmlFile);
                if (ffile.exists())
                {
                    input_source = new java.io.FileInputStream(ffile);

                } else {

                    input_source = this.getClass().getClassLoader().getResourceAsStream(xmlFile);
                }
                 
                parser.setEntityResolver( new org.xml.sax.EntityResolver() {
                    
                    /* Code by Teodor Danciu */
                    public org.xml.sax.InputSource resolveEntity( String publicId, String systemId )
                           throws SAXException, IOException
                    {
                        org.xml.sax.InputSource inputSource = null;
                        
                        if (systemId != null) {
                            String dtd = null;
                            
                            if ( systemId.equals("http://jasperreports.sourceforge.net/dtds/jasperreport.dtd") ||
                            systemId.equals("http://www.jasperreports.com/dtds/jasperreport.dtd") ) {
                                //dtd = "dori/jasper/engine/dtds/jasperreport.dtd";
                                dtd = "net/sf/jasperreports/engine/dtds/jasperreport.dtd";
                               
                            } else if (
                            systemId.equals("http://jasperreports.sourceforge.net/dtds/jasperprint.dtd") ||
                            systemId.equals("http://www.jasperreports.com/dtds/jasperprint.dtd") ) {
                                dtd = "net/sf/jasperreports/engine/dtds/jasperprint.dtd";
                            } else {
                                return new org.xml.sax.InputSource(systemId);
                            }


                            ClassLoader classLoader = this.getClass().getClassLoader();
                            java.net.URL url = null;

                            if (classLoader != null) {
                                url = classLoader.getResource(dtd);
                                if (url == null) {
                                    classLoader = this.getClass().getClassLoader();
                                }

                            } else {
                                // url is certainly null
                                // classLoader stays null
                            }


                            java.io.InputStream is = classLoader.getResourceAsStream(dtd);
                            if (is != null) {
                                java.io.InputStreamReader isr = new java.io.InputStreamReader(is);
                                inputSource = new org.xml.sax.InputSource(isr);
                            } else {
                                // dtd could not be found
                                // this error occurs e.g. when the package name / path changes to this dtd
                                // the error will be caught by MainFrame.openFile() en the report file won't open
                                throw new java.io.IOException( "iReport Internal error in report.java: Could not find: " + dtd + "\n" );
                            }
                        }
                        return inputSource;
                        
                    }
                });
                /* End Code by Teodor Danciu */
                
                    //String f = new java.io.File(xmlFile).toURI().toString();
                    org.xml.sax.InputSource input_sss  = new org.xml.sax.InputSource( input_source );
                    
                    
                    parser.parse( input_sss );
                    Document document = parser.getDocument();
                    traverse(document.getDocumentElement());

            }

            /* Begin Code by Robert Lamping
             * 2 July 2004
             * Now height and width are known and a format can be guessed.
             * using PageSize.deductPageFormat();
             */
            
            this.setReportFormat( PageSize.deductPageFormat( this.getWidth(), this.getHeight()) );
            
            /* Begin Code by Robert Lamping */
            
            for (int i = 0; i < groups.size(); i++) {
                it.businesslogic.ireport.Group grp = (it.businesslogic.ireport.Group)groups.elementAt(i);
                addGroup(grp,false);
            }
            
            // Translate coords to iReport coord system...
            for (Iterator i = elements.iterator(); i.hasNext(); ) {
                ReportElement re = (ReportElement) i.next();
                re.trasform(new java.awt.Point(this.getLeftMargin()+10, this.getBandYLocation(re.getBand())+10), TransformationType.TRANSFORMATION_MOVE);
            }
            
            // Scriptlet loading....
            
            // Process custom properties (ireport.* properties).
            // We cut out ireport properties...
            //System.out.println("Analizing properties...");
            //System.out.println("Possible file: "+this.getScriptletFileName());

            for (int pk= 0; pk < this.getJRproperties().size(); ++pk) {
                JRProperty prop = (JRProperty)getJRproperties().elementAt( pk );
                
                //System.out.println(""+prop.getName());
                
                if (prop.getName().equals("ireport.scriptlethandling")) {
                    if (prop.getValue().equals("0")) {
                        this.setScriptletHandling(0);
                    } else if (prop.getValue().equals("1")) {
                        this.setScriptletHandling( this.SCRIPTLET_IREPORT_INTERNAL_HANDLING );
                        // Try to load the source file...
                        File scriptletFile = new File(this.getScriptletFileName());
                        if (scriptletFile.exists()) {
                            scripletCode = new ScriptletCode(this.getScriptletFileName());
                            //System.out.println("Caricato scriptlet");
                        }
                    }
                }
                
                if (prop.getValue().startsWith("ireport.")) {
                    getJRproperties().remove( prop );
                    pk--;
                }
            }
            
            if (this.getScriptletHandling() == 2 &&
            	(scriptletClass == null || scriptletClass.equals("")) )
            	{
            		this.setScriptletHandling(0);
            	}
            
            // } catch (SAXException e) {
            //            System.err.println(e);
        } catch (IOException e) {
            System.err.println(e);
            throw e ; 
            
        } catch (net.sf.jasperreports.engine.JRException e) {
            System.err.println(e);
            
        } catch (Exception e) {
            System.err.println(e);
            e.printStackTrace();
        }
        
        this.setDirty(false);
        
    }
    
    //  Traverse DOM Tree.  Print out Element Names
    private void traverse(Node node) {
        
        if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("jasperReport")) {

            // Find encoding...
            NamedNodeMap nnm = node.getAttributes();
            
            this.setName((( nnm.getNamedItem("name") != null) ? nnm.getNamedItem("name").getNodeValue() : ""));
            
            if ( nnm.getNamedItem("columnCount") != null) {
                this.setColumnCount( Integer.parseInt(nnm.getNamedItem("columnCount").getNodeValue()));
            }
            if ( nnm.getNamedItem("printOrder") != null) {
                this.setPrintOrder( nnm.getNamedItem("printOrder").getNodeValue());
            }
            if ( nnm.getNamedItem("orientation") != null) {
                this.setOrientation( nnm.getNamedItem("orientation").getNodeValue());
            }
            if ( nnm.getNamedItem("scriptletClass") != null) {
                this.setScriptletClass( nnm.getNamedItem("scriptletClass").getNodeValue());
            }
            if ( nnm.getNamedItem("resourceBundle") != null) {
                this.setResourceBundleBaseName( nnm.getNamedItem("resourceBundle").getNodeValue());
            }
            if ( nnm.getNamedItem("pageWidth") != null) {
                this.setWidth( Integer.parseInt(nnm.getNamedItem("pageWidth").getNodeValue()));
            }
            if ( nnm.getNamedItem("pageHeight") != null) {
                this.setHeight( Integer.parseInt(nnm.getNamedItem("pageHeight").getNodeValue()));
            }
            if ( nnm.getNamedItem("columnWidth") != null) {
                this.setColumnWidth( Integer.parseInt(nnm.getNamedItem("columnWidth").getNodeValue()));
            }
            if ( nnm.getNamedItem("columnSpacing") != null) {
                this.setColumnSpacing( Integer.parseInt(nnm.getNamedItem("columnSpacing").getNodeValue()));
            }
            if ( nnm.getNamedItem("leftMargin") != null) {
                this.setLeftMargin( Integer.parseInt(nnm.getNamedItem("leftMargin").getNodeValue()));
            }
            if ( nnm.getNamedItem("rightMargin") != null) {
                this.setRightMargin( Integer.parseInt(nnm.getNamedItem("rightMargin").getNodeValue()));
            }
            if ( nnm.getNamedItem("topMargin") != null) {
                this.setTopMargin( Integer.parseInt(nnm.getNamedItem("topMargin").getNodeValue()));
            }
            if ( nnm.getNamedItem("bottomMargin") != null) {
                this.setBottomMargin( Integer.parseInt(nnm.getNamedItem("bottomMargin").getNodeValue()));
            }
            if ( nnm.getNamedItem("whenNoDataType") != null) {
                this.setWhenNoDataType( nnm.getNamedItem("whenNoDataType").getNodeValue());
            }
            if ( nnm.getNamedItem("isTitleNewPage") != null) {
                this.setIsTitleNewPage(nnm.getNamedItem("isTitleNewPage").getNodeValue().equalsIgnoreCase("true") );
            }
            if ( nnm.getNamedItem("isSummaryNewPage") != null) {
                this.setIsSummaryNewPage(  nnm.getNamedItem("isSummaryNewPage").getNodeValue().equalsIgnoreCase("true"));
            }
            
            if ( nnm.getNamedItem("isFloatColumnFooter") != null) {
                this.setFloatColumnFooter(nnm.getNamedItem("isFloatColumnFooter").getNodeValue().equalsIgnoreCase("true") );
            }
            
            if ( nnm.getNamedItem("language") != null) {
                this.setLanguage( nnm.getNamedItem("language").getNodeValue());
            }
            
            
        } else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("property")) {

            // Load report property...
            JRProperty property = new JRProperty();
            NamedNodeMap nnm = node.getAttributes();
            if ( nnm.getNamedItem("name") != null) {
                property.setName( nnm.getNamedItem("name").getNodeValue());
            }
            if ( nnm.getNamedItem("value") != null) {
                property.setValue( nnm.getNamedItem("value").getNodeValue());
            }
            
            JRproperties.addElement( property );
        } else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("import")) {

            // Load report IMPORT...
            NamedNodeMap nnm = node.getAttributes();
            if ( nnm.getNamedItem("value") != null) {
                addImport( nnm.getNamedItem("value").getNodeValue() );
            }            
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("reportFont")) {
            
            // Load report font...
            boolean isDefaultFont = false;
            IReportFont font = new IReportFont();
            
            NamedNodeMap nnm = node.getAttributes();
            if ( nnm.getNamedItem("name") != null) {
                font.setReportFont( nnm.getNamedItem("name").getNodeValue());
            }
            if ( nnm.getNamedItem("isDefault") != null) {
                isDefaultFont = nnm.getNamedItem("isDefault").getNodeValue().equals("true");
                font.setDefaultFont(isDefaultFont);
            }
            if ( nnm.getNamedItem("fontName") != null) {
                font.setFontName( nnm.getNamedItem("fontName").getNodeValue());
            }
            if ( nnm.getNamedItem("size") != null) {
                font.setFontSize( Integer.parseInt( nnm.getNamedItem("size").getNodeValue()) );
            }
            if ( nnm.getNamedItem("isBold") != null) {
                font.setBold( nnm.getNamedItem("isBold").getNodeValue().equals("true"));
            }
            if ( nnm.getNamedItem("isItalic") != null) {
                font.setItalic( nnm.getNamedItem("isItalic").getNodeValue().equals("true"));
            }
            if ( nnm.getNamedItem("isUnderline") != null) {
                font.setUnderline( nnm.getNamedItem("isUnderline").getNodeValue().equals("true"));
            }
            if ( nnm.getNamedItem("isStrikeThrough") != null) {
                font.setStrikeTrought( nnm.getNamedItem("isStrikeThrough").getNodeValue().equals("true"));
            }
            if ( nnm.getNamedItem("pdfFontName") != null) {
                font.setPDFFontName( nnm.getNamedItem("pdfFontName").getNodeValue());
            }
            if ( nnm.getNamedItem("pdfEncoding") != null) {
                font.setPdfEncoding( nnm.getNamedItem("pdfEncoding").getNodeValue());
            }
            if ( nnm.getNamedItem("isPdfEmbedded") != null) {
                font.setPdfEmbedded( nnm.getNamedItem("isPdfEmbedded").getNodeValue().equals("true"));
            }
            
            if (isDefaultFont){
                defaultFont = (IReportFont) font.clone();
            }
            
            fonts.addElement( font );
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("parameter")) {
            
            // Load parameter...
            it.businesslogic.ireport.JRParameter parameter = new it.businesslogic.ireport.JRParameter("","java.lang.String",true,"");
            
            NamedNodeMap nnm = node.getAttributes();
            if ( nnm.getNamedItem("name") != null) {
                parameter.setName( nnm.getNamedItem("name").getNodeValue());
            }
            if ( nnm.getNamedItem("class") != null) {
                parameter.setClassType( nnm.getNamedItem("class").getNodeValue() );
            }
            if ( nnm.getNamedItem("isForPrompting") != null) {
                parameter.setIsForPrompting( nnm.getNamedItem("isForPrompting").getNodeValue().equalsIgnoreCase("true") );
            }
            
            // Check for description and expression...
            NodeList children = node.getChildNodes();
            if (children != null) {
                for (int k=0; k< children.getLength(); k++) {
                    Node nodeChild = (Node)children.item(k);
                    if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("parameterDescription")) {
                        // Take the CDATA...
                        
                        NodeList list_child = nodeChild.getChildNodes();
                        for (int ck = 0; ck< list_child.getLength(); ck++) {
                            Node child_child = (Node)list_child.item(ck);
                            if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                            child_child.getNodeType() == Node.TEXT_NODE) {
                                parameter.setDescription( child_child.getNodeValue() );
                            }
                        }
                    } else if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("defaultValueExpression")) {
                        // Take the CDATA...
                        NodeList list_child = nodeChild.getChildNodes();
                        for (int ck = 0; ck < list_child.getLength(); ck++) {
                            Node child_child = (Node)list_child.item(ck);
                            if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                            child_child.getNodeType() == Node.TEXT_NODE) {
                                parameter.setDefaultValueExpression( child_child.getNodeValue() );
                            }
                        }
                    }
                }
            }
            
            if (parameter.getName() != null && parameter.getName().length() != 0) {
                this.addParameter( parameter );
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("queryString")) {
            // Load queryString
            this.setQuery( readPCDATA(node) );
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("field")) {
            // Load field
            it.businesslogic.ireport.JRField field = new it.businesslogic.ireport.JRField("","java.lang.String");
            field.setDescription("");
            
            NamedNodeMap nnm = node.getAttributes();
            if ( nnm.getNamedItem("name") != null) {
                field.setName( nnm.getNamedItem("name").getNodeValue());
            }
            if ( nnm.getNamedItem("class") != null) {
                field.setClassType( nnm.getNamedItem("class").getNodeValue() );
            }
            
            NodeList children = node.getChildNodes();
            if (children != null) {
                for (int k=0; k< children.getLength(); k++) {
                    Node nodeChild = (Node)children.item(k);
                    
                    if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("fieldDescription")) {
                        // Take the CDATA...
                        NodeList list_child = nodeChild.getChildNodes();
                        
                        for (int ck=0; ck< list_child.getLength(); ck++) {
                            
                            Node child_child = (Node)list_child.item(ck);
                            if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                            child_child.getNodeType() == Node.TEXT_NODE) {
                                field.setDescription( child_child.getNodeValue() );
                            }
                        }
                    }
                }
                
            }
            
            if (field.getName() != null && field.getName().length() != 0) {
                this.addField( field );
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("variable")) {
            // Load variable
            it.businesslogic.ireport.JRVariable variable = new it.businesslogic.ireport.JRVariable("",false);
            variable.setResetType("Report"); //Default value...
            variable.setResetGroup(""); //Default value...
            
            variable.setIncrementType("None"); //Default value...
            variable.setIncrementGroup(""); //Default value...
            
            variable.setCalculation("Nothing"); //Default value...
            
            NamedNodeMap nnm = node.getAttributes();
            if ( nnm.getNamedItem("name") != null) {
                variable.setName( nnm.getNamedItem("name").getNodeValue());
            }
            if ( nnm.getNamedItem("class") != null) {
                variable.setClassType( nnm.getNamedItem("class").getNodeValue() );
            }
            if ( nnm.getNamedItem("resetType") != null) {
                variable.setResetType( nnm.getNamedItem("resetType").getNodeValue() );
            }
            if ( nnm.getNamedItem("resetGroup") != null) {
                variable.setResetGroup( nnm.getNamedItem("resetGroup").getNodeValue() );
            }
            if ( nnm.getNamedItem("calculation") != null) {
                variable.setCalculation( nnm.getNamedItem("calculation").getNodeValue() );
            }
            if ( nnm.getNamedItem("incrementerFactoryClass") != null) {
                variable.setIncrementerFactoryClass( nnm.getNamedItem("incrementerFactoryClass").getNodeValue() );
            }
            if ( nnm.getNamedItem("incrementType") != null) {
                variable.setIncrementType( nnm.getNamedItem("incrementType").getNodeValue());
            }
            if ( nnm.getNamedItem("incrementGroup") != null) {
                variable.setIncrementGroup( nnm.getNamedItem("incrementGroup").getNodeValue());
            }
            
            // Check for description and expression...
            NodeList children = node.getChildNodes();
            if (children != null) {
                for (int k=0; k< children.getLength(); k++) {
                    Node nodeChild = (Node)children.item(k);
                    if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("variableExpression")) {
                        // Take the CDATA...
                        NodeList list_child = nodeChild.getChildNodes();
                        for (int ck=0; ck< list_child.getLength(); ck++) {
                            Node child_child = (Node)list_child.item(ck);
                            if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                            child_child.getNodeType() == Node.TEXT_NODE) {
                                variable.setExpression( child_child.getNodeValue() );
                            }
                        }
                    }
                    else if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("initialValueExpression")) {
                        // Take the CDATA...
                        NodeList list_child = nodeChild.getChildNodes();
                        for (int ck=0; ck< list_child.getLength(); ck++) {
                            Node child_child = (Node)list_child.item(ck);
                            if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                            child_child.getNodeType() == Node.TEXT_NODE) {
                                variable.setInitialValueExpression( child_child.getNodeValue() );
                            }
                        }
                    }
                }
            }
            
            if (variable.getName() != null && variable.getName().length() != 0) {
                this.addVariable( variable );
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("group")) {
            // Load group
            NamedNodeMap nnm = node.getAttributes();
            it.businesslogic.ireport.Group group = new it.businesslogic.ireport.Group(this, ""+nnm.getNamedItem("name").getNodeValue());
            
            if ( nnm.getNamedItem("isStartNewColumn") != null) group.setIsStartNewColumn( nnm.getNamedItem("isStartNewColumn").getNodeValue().equals("true") );
            if ( nnm.getNamedItem("isStartNewPage") != null) group.setIsStartNewPage( nnm.getNamedItem("isStartNewPage").getNodeValue().equals("true") );
            if ( nnm.getNamedItem("isResetPageNumber") != null) group.setIsResetPageNumber( nnm.getNamedItem("isResetPageNumber").getNodeValue().equals("true") );
            if ( nnm.getNamedItem("isReprintHeaderOnEachPage") != null) group.setIsReprintHeaderOnEachPage( nnm.getNamedItem("isReprintHeaderOnEachPage").getNodeValue().equals("true") );
            if ( nnm.getNamedItem("minHeightToStartNewPage") != null) group.setMinHeightToStartNewPage( Integer.parseInt(nnm.getNamedItem("minHeightToStartNewPage").getNodeValue()));
            
            if (group.getName() != null && group.getName().length() != 0) {
                groups.addElement(group); // We don't use here addGroup method!
            }
            
            // Looking for header, footer and expression...
            NodeList children = node.getChildNodes();
            if (children != null) {
                for (int k=0; k< children.getLength(); k++) {
                    Node nodeChild = (Node)children.item(k);
                    if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("groupExpression")) {
                        // Take the CDATA...
                        NodeList list_child = nodeChild.getChildNodes();
                        for (int ck=0; ck< list_child.getLength(); ck++) {
                            Node child_child = (Node)list_child.item(ck);
                            if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                            child_child.getNodeType() == Node.TEXT_NODE) {
                                group.setGroupExpression( child_child.getNodeValue() );
                            }
                        }
                    }
                    else if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("groupHeader")) {
                        // Take the band...
                        NodeList list_child = nodeChild.getChildNodes();
                        for (int ck=0; ck< list_child.getLength(); ck++) {
                            Node bandNode = (Node)list_child.item(ck);
                            if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                                // Read the band...
                                NamedNodeMap bandAttributes = bandNode.getAttributes();
                                if ( bandAttributes.getNamedItem("height") != null) group.getGroupHeader().setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                                if ( bandAttributes.getNamedItem("isSplitAllowed") != null) group.getGroupHeader().setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                                readBandElements(bandNode,group.getGroupHeader());
                            }
                        }
                    }
                    else if (nodeChild.getNodeType() == Node.ELEMENT_NODE && nodeChild.getNodeName().equals("groupFooter")) {
                        // Take the band...
                        NodeList list_child = nodeChild.getChildNodes();
                        for (int ck=0; ck< list_child.getLength(); ck++) {
                            Node bandNode = (Node)list_child.item(ck);
                            if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                                // Read the band...
                                NamedNodeMap bandAttributes = bandNode.getAttributes();
                                if ( bandAttributes.getNamedItem("height") != null) group.getGroupFooter().setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                                if ( bandAttributes.getNamedItem("isSplitAllowed") != null) group.getGroupFooter().setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                                readBandElements(bandNode,group.getGroupFooter());
                            }
                        }
                    }
                }
            }
            
            
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("background")) {
            // Load background band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("background");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("title")) {
            // Load title band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("title");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("pageHeader")) {
            // Load pageHeader band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("pageHeader");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("columnHeader")) {
            // Load columnHeader band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("columnHeader");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("detail")) {
            // Load detail band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("detail");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("columnFooter")) {
            // Load columnFooter band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("columnFooter");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("pageFooter")) {
            // Load pageFooter band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("pageFooter");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("lastPageFooter")) {
            // Load title band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("lastPageFooter");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    readBandElements(bandNode,b);
                }
            }
        }
        else if (node.getNodeType() == Node.ELEMENT_NODE && node.getNodeName().equals("summary")) {
            // Load summary band
            NodeList list_child = node.getChildNodes();
            for (int ck=0; ck< list_child.getLength(); ck++) {
                Node bandNode = (Node)list_child.item(ck);
                if (bandNode.getNodeType() == Node.ELEMENT_NODE && bandNode.getNodeName().equals("band")) {
                    // Read the band...
                    NamedNodeMap bandAttributes = bandNode.getAttributes();
                    Band b = this.getBandByName("summary");
                    if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                    if ( bandAttributes.getNamedItem("isSplitAllowed") != null) b.setSplitAllowed( bandAttributes.getNamedItem("isSplitAllowed").getNodeValue().equals("true") );
                    
                    readBandElements(bandNode,b);
                }
            }
        }
        
        NodeList children = node.getChildNodes();
        if (children != null) {
            for (int i=0; i< children.getLength(); i++)
                traverse(children.item(i));
        }
    }
    
    private void readBandElements(Node bandNode, Band band) {
        
        NodeList list_child = bandNode.getChildNodes();
        for (int ck=0; ck< list_child.getLength(); ck++) {
            Node child = (Node)list_child.item(ck);
            if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("printWhenExpression")) {
                // Read the band...
                //NamedNodeMap bandAttributes = bandNode.getAttributes();
                //if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
                // Take subelements and lloking for the expression...
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    if (child_child.getNodeType() == Node.CDATA_SECTION_NODE ||
                    child_child.getNodeType() == Node.TEXT_NODE) {
                        band.setPrintWhenExpression(child_child.getNodeValue());
                    }
                }
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("staticText")) {
                StaticTextReportElement re = new StaticTextReportElement(0,0,0,0);
                re.setIReportFont(defaultFont);
                
                re.setBand(band);
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("textElement")) {
                        readXMLTextElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("text")) {
                        re.setText( readPCDATA(child_child, false) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("box")) {
                        readBoxElement(child_child,re);
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                elements.addElement(re);
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("image")) {
                ImageReportElement re = new ImageReportElement(0,0,0,0);
                re.setBand(band);
                NamedNodeMap nodeAttributes = child.getAttributes();
                if (nodeAttributes.getNamedItem("isUsingCache") != null)
                    re.setIsUsingCache( (""+nodeAttributes.getNamedItem("isUsingCache").getNodeValue()).equals("true") );
                if (nodeAttributes.getNamedItem("scaleImage") != null)
                    re.setScaleImage(""+nodeAttributes.getNamedItem("scaleImage").getNodeValue());
                if (nodeAttributes.getNamedItem("vAlign") != null)
                    re.setVerticalAlignment( ""+nodeAttributes.getNamedItem("vAlign").getNodeValue());
                if (nodeAttributes.getNamedItem("hAlign") != null)
                    re.setHorizontalAlignment(""+nodeAttributes.getNamedItem("hAlign").getNodeValue());
                if (nodeAttributes.getNamedItem("evaluationTime") != null)
                    re.setEvaluationTime( ""+nodeAttributes.getNamedItem("evaluationTime").getNodeValue());
                if (nodeAttributes.getNamedItem("evaluationGroup") != null)
                    re.setEvaluationGroup( ""+nodeAttributes.getNamedItem("evaluationGroup").getNodeValue());
                if (nodeAttributes.getNamedItem("hyperlinkType") != null)
                    re.setHyperlinkType(""+nodeAttributes.getNamedItem("hyperlinkType").getNodeValue());
                if (nodeAttributes.getNamedItem("hyperlinkTarget") != null)
                    re.setHyperlinkTarget(""+nodeAttributes.getNamedItem("hyperlinkTarget").getNodeValue());
                
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }		// Element properties...
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("graphicElement")) {
                        if (subNodeAttributes.getNamedItem("pen") != null) {
                            re.setGraphicElementPen( ""+subNodeAttributes.getNamedItem("pen").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("stretchType") != null) {
                            re.setStretchType(""+subNodeAttributes.getNamedItem("stretchType").getNodeValue());
                        }
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("imageExpression")) {
                        if (subNodeAttributes.getNamedItem("class") != null) {
                            re.setImageClass(""+subNodeAttributes.getNamedItem("class").getNodeValue());
                        }
                        re.setImageExpression( readPCDATA(child_child));
                        re.setReportDirectory(new java.io.File(this.filename).getParentFile());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("anchorNameExpression")) {
                        re.setAnchorNameExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkAnchorExpression")) {
                        re.setHyperlinkAnchorExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkPageExpression")) {
                        re.setHyperlinkPageExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkReferenceExpression")) {
                        re.setHyperlinkReferenceExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("box")) {
                        readBoxElement(child_child,re);
                    }
                }
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                
                if (re.getImageExpression().indexOf("it.businesslogic.ireport.chart.DefaultChartFactory.drawChart(") >= 0) {
                    ChartReportElement chart = new ChartReportElement( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    chart.setBand( re.getBand() );
                    chart.setHyperlinkReferenceExpression( re.getHyperlinkReferenceExpression());
                    chart.setHyperlinkPageExpression( re.getHyperlinkPageExpression());
                    chart.setHyperlinkAnchorExpression( re.getHyperlinkAnchorExpression());
                    chart.setHyperlinkType( re.getHyperlinkType());
                    chart.setBgcolor( re.getBgcolor());
                    chart.setEvaluationGroup( re.getEvaluationGroup());
                    chart.setEvaluationTime( re.getEvaluationTime());
                    chart.setFgcolor( re.getFgcolor());
                    chart.setFill( re.getFill());
                    chart.setGraphicElementPen( re.getGraphicElementPen());
                    chart.setHorizontalAlignment( re.getHorizontalAlignment());
                    chart.setImageClass( re.getImageClass());
                    chart.setImageExpression( re.getImageExpression());
                    chart.setName( re.getName());
                    chart.setPositionType( re.getPositionType());
                    chart.setPrintWhenExpression( re.getPrintWhenExpression() );
                    chart.setPrintWhenGroupChanges( re.getPrintWhenGroupChanges());
                    chart.setScaleImage( re.getScaleImage());
                    chart.setStretchType( re.getStretchType());
                    chart.setTransparent( re.getTransparent());
                    chart.setVerticalAlignment( re.getVerticalAlignment());
                    chart.parseProperties( this.getJRproperties() );
                    re = chart;
                }
                
                if (re.getImageExpression().indexOf("it.businesslogic.ireport.barcode.BcImage.getBarcodeImage(") >= 0) {
                    BarcodeReportElement bc = new BarcodeReportElement( re.getPosition().x, re.getPosition().y, re.getWidth(), re.getHeight());
                    bc.setBand( re.getBand() );
                    bc.setHyperlinkReferenceExpression( re.getHyperlinkReferenceExpression());
                    bc.setHyperlinkPageExpression( re.getHyperlinkPageExpression());
                    bc.setHyperlinkAnchorExpression( re.getHyperlinkAnchorExpression());
                    bc.setHyperlinkType( re.getHyperlinkType());
                    bc.setBgcolor( re.getBgcolor());
                    bc.setEvaluationGroup( re.getEvaluationGroup());
                    bc.setEvaluationTime( re.getEvaluationTime());
                    bc.setFgcolor( re.getFgcolor());
                    bc.setFill( re.getFill());
                    bc.setGraphicElementPen( re.getGraphicElementPen());
                    bc.setHorizontalAlignment( re.getHorizontalAlignment());
                    bc.setImageClass( re.getImageClass());
                    bc.setImageExpression( re.getImageExpression());
                    bc.setName( re.getName());
                    bc.setPositionType( re.getPositionType());
                    bc.setPrintWhenExpression( re.getPrintWhenExpression() );
                    bc.setPrintWhenGroupChanges( re.getPrintWhenGroupChanges());
                    bc.setScaleImage( re.getScaleImage());
                    bc.setStretchType( re.getStretchType());
                    bc.setTransparent( re.getTransparent());
                    bc.setVerticalAlignment( re.getVerticalAlignment());
                    
                    re = bc;
                }
                
                elements.addElement(re);
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("rectangle")) {
                RectangleReportElement re = new RectangleReportElement(0,0,0,0);
                re.setBand(band);
                NamedNodeMap nodeAttributes = child.getAttributes();
                /* CompatibilitySupport.saveRoundedRectangle */
                if (nodeAttributes.getNamedItem("radius") != null)
                    re.setRadius( Integer.parseInt( (""+nodeAttributes.getNamedItem("radius").getNodeValue())) );
                // Element properties...
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }		// Element properties...
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("graphicElement")) {
                        if (subNodeAttributes.getNamedItem("pen") != null) {
                            re.setGraphicElementPen( ""+subNodeAttributes.getNamedItem("pen").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("stretchType") != null) {
                            re.setStretchType(""+subNodeAttributes.getNamedItem("stretchType").getNodeValue());
                        }
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                elements.addElement(re);
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("line")) {
                LineReportElement re = new LineReportElement(0,0,0,0);
                re.setBand(band);
                NamedNodeMap nodeAttributes = child.getAttributes();
                /* CompatibilitySupport.saveRoundedRectangle */
                if (nodeAttributes.getNamedItem("direction") != null)
                    re.setDirection( ""+nodeAttributes.getNamedItem("direction").getNodeValue() );
                
                // Element properties...
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }		// Element properties...
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("graphicElement")) {
                        if (subNodeAttributes.getNamedItem("pen") != null) {
                            re.setGraphicElementPen( ""+subNodeAttributes.getNamedItem("pen").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("stretchType") != null) {
                            re.setStretchType(""+subNodeAttributes.getNamedItem("stretchType").getNodeValue());
                        }
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                elements.addElement(re);
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("ellipse")) {
                EllipseReportElement re = new EllipseReportElement(0,0,0,0);
                re.setBand(band);
                NamedNodeMap nodeAttributes = child.getAttributes();
                /* CompatibilitySupport.saveRoundedRectangle */
                //if (nodeAttributes.getNamedItem("direction") != null)
                //	re.setDirection( ""+nodeAttributes.getNamedItem("direction").getNodeValue() );
                
                // Element properties...
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }		// Element properties...
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("graphicElement")) {
                        if (subNodeAttributes.getNamedItem("pen") != null) {
                            re.setGraphicElementPen( ""+subNodeAttributes.getNamedItem("pen").getNodeValue());
                        }
                        if (subNodeAttributes.getNamedItem("stretchType") != null) {
                            re.setStretchType(""+subNodeAttributes.getNamedItem("stretchType").getNodeValue());
                        }
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                elements.addElement(re);
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("textField")) {
                TextFieldReportElement re = new TextFieldReportElement(0,0,0,0);
                re.setIReportFont(defaultFont);
                
                re.setBand(band);
                NamedNodeMap nodeAttributes = child.getAttributes();
                /* CompatibilitySupport.saveRoundedRectangle */
                if (nodeAttributes.getNamedItem("evaluationTime") != null)
                    re.setEvaluationTime( ""+nodeAttributes.getNamedItem("evaluationTime").getNodeValue() );
                if (nodeAttributes.getNamedItem("evaluationGroup") != null)
                    re.setGroup( ""+nodeAttributes.getNamedItem("evaluationGroup").getNodeValue() );
                if (nodeAttributes.getNamedItem("isStretchWithOverflow") != null)
                    re.setStretchWithOverflow( nodeAttributes.getNamedItem("isStretchWithOverflow").getNodeValue().equals("true"));
                if (nodeAttributes.getNamedItem("isBlankWhenNull") != null)
                    re.setBlankWhenNull(nodeAttributes.getNamedItem("isBlankWhenNull").getNodeValue().equals("true") );
                if (nodeAttributes.getNamedItem("pattern") != null)
                    re.setPattern( ""+nodeAttributes.getNamedItem("pattern").getNodeValue() );
                if (nodeAttributes.getNamedItem("hyperlinkType") != null)
                    re.setHyperlinkType( ""+nodeAttributes.getNamedItem("hyperlinkType").getNodeValue() );
                if (nodeAttributes.getNamedItem("hyperlinkTarget") != null)
                    re.setHyperlinkTarget( ""+nodeAttributes.getNamedItem("hyperlinkTarget").getNodeValue() );
                
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("textElement")) {
                        readXMLTextElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("textFieldExpression")) {
                        if (subNodeAttributes.getNamedItem("class") != null) {
                            re.setClassExpression(""+subNodeAttributes.getNamedItem("class").getNodeValue());
                        }
                        re.setText( readPCDATA(child_child).trim());
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("anchorNameExpression")) {
                        re.setAnchorNameExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkAnchorExpression")) {
                        re.setHyperlinkAnchorExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkPageExpression")) {
                        re.setHyperlinkPageExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("hyperlinkReferenceExpression")) {
                        re.setHyperlinkReferenceExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("box")) {
                        readBoxElement(child_child,re);
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                elements.addElement(re);
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("elementGroup")) {
                readBandElements( child,band);
            }
            else if (child.getNodeType() == Node.ELEMENT_NODE && child.getNodeName().equals("subreport")) {
                SubReportElement re = new SubReportElement(0,0,0,0);
                re.setBand(band);
                NamedNodeMap nodeAttributes = child.getAttributes();
                if (nodeAttributes.getNamedItem("isUsingCache") != null)
                    re.setIsUsingCache(nodeAttributes.getNamedItem("isUsingCache").getNodeValue().equals("true") );
                
                NodeList childsOfChild = child.getChildNodes();
                for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
                    Node child_child = (Node)childsOfChild.item(c_count);
                    NamedNodeMap subNodeAttributes = child_child.getAttributes();
                    
                    if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("reportElement")) {
                        readXMLReportElement(child_child,re);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("parametersMapExpression")) {
                        re.setParametersMapExpression( readPCDATA(child_child) );
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("subreportParameter")) {
                        String name = "";
                        if (subNodeAttributes.getNamedItem("name") != null) {
                            name = ""+subNodeAttributes.getNamedItem("name").getNodeValue();
                        }
                        // Find expression in childs......
                        String expression = "";
                        NodeList childsOfChildOfChild = child_child.getChildNodes();
                        for (int c_count_2=0; c_count_2< childsOfChildOfChild.getLength(); c_count_2++) {
                            Node child_child_child = (Node)childsOfChildOfChild.item(c_count_2);
                            if (child_child_child.getNodeType() == Node.ELEMENT_NODE && child_child_child.getNodeName().equals("subreportParameterExpression")) {
                                expression = readPCDATA(child_child_child);
                                break;
                            }
                        }
                        re.getSubreportParameters().addElement( new it.businesslogic.ireport.JRSubreportParameter( name, expression));
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("connectionExpression")) {
                        re.setConnectionExpression( readPCDATA(child_child));
                        re.setUseConnection(true);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("dataSourceExpression")) {
                        re.setDataSourceExpression(readPCDATA(child_child));
                        re.setUseConnection(false);
                    }
                    else if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("subreportExpression")) {
                        re.setSubreportExpression(readPCDATA(child_child));
                        if (subNodeAttributes.getNamedItem("class") != null) {
                            re.setSubreportExpressionClass(""+subNodeAttributes.getNamedItem("class").getNodeValue());
                        }
                    }
                }
                
                re.setPosition(re.position);
                re.trasform(new java.awt.Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE);
                elements.addElement(re);
            }
            //System.out.println(""+child.getNodeName());
        }
    }
    
    
    private void readXMLReportElement(Node xmlReportElement, ReportElement re) {
        NamedNodeMap nodeAttributes = xmlReportElement.getAttributes();
        //if ( bandAttributes.getNamedItem("height") != null) b.setHeight( Integer.parseInt(bandAttributes.getNamedItem("height").getNodeValue()) );
        if (nodeAttributes.getNamedItem("x") != null)
            re.getPosition().x = Integer.parseInt(""+nodeAttributes.getNamedItem("x").getNodeValue());
        if (nodeAttributes.getNamedItem("y") != null)
            re.getPosition().y = Integer.parseInt(""+nodeAttributes.getNamedItem("y").getNodeValue());
        if (nodeAttributes.getNamedItem("width") != null)
            re.setWidth( Integer.parseInt(""+nodeAttributes.getNamedItem("width").getNodeValue()) );
        if (nodeAttributes.getNamedItem("height") != null)
            re.setHeight( Integer.parseInt(""+nodeAttributes.getNamedItem("height").getNodeValue()) );
        if (nodeAttributes.getNamedItem("key") != null)
            re.setKey( ""+nodeAttributes.getNamedItem("key").getNodeValue() );
        
        if (nodeAttributes.getNamedItem("stretchType") != null)
            re.setStretchType( ""+nodeAttributes.getNamedItem("stretchType").getNodeValue() );
        
        if (nodeAttributes.getNamedItem("isPrintRepeatedValues") != null)
            re.setIsPrintRepeatedValues( (""+nodeAttributes.getNamedItem("isPrintRepeatedValues").getNodeValue()).equalsIgnoreCase("true") );
        
        if (nodeAttributes.getNamedItem("positionType") != null)
            re.setPositionType( ""+nodeAttributes.getNamedItem("positionType").getNodeValue() );
        else
            re.setPositionType( "FixRelativeToTop" );
        
        if (nodeAttributes.getNamedItem("isPrintRepeatedValues") != null)
            re.setIsPrintRepeatedValues( (""+nodeAttributes.getNamedItem("isPrintRepeatedValues").getNodeValue()).equalsIgnoreCase("true") );
        
        if (nodeAttributes.getNamedItem("isRemoveLineWhenBlank") != null)
            re.setIsRemoveLineWhenBlank( (""+nodeAttributes.getNamedItem("isRemoveLineWhenBlank").getNodeValue()).equalsIgnoreCase("true") ) ;
        
        if (nodeAttributes.getNamedItem("isPrintInFirstWholeBand") != null)
            re.setIsPrintInFirstWholeBand( (""+nodeAttributes.getNamedItem("isPrintInFirstWholeBand").getNodeValue()).equalsIgnoreCase("true") );
        
        if (nodeAttributes.getNamedItem("isPrintWhenDetailOverflows") != null)
            re.setIsPrintWhenDetailOverflows( (""+nodeAttributes.getNamedItem("isPrintWhenDetailOverflows").getNodeValue()).equalsIgnoreCase("true") );
        
        if (nodeAttributes.getNamedItem("printWhenGroupChanges") != null)
            re.setPrintWhenGroupChanges( ""+nodeAttributes.getNamedItem("printWhenGroupChanges").getNodeValue() );
        
        
        if (nodeAttributes.getNamedItem("forecolor") != null) {
            String color = ""+nodeAttributes.getNamedItem("forecolor").getNodeValue();
            re.setFgcolor(decodeColor(color) );
        }
        if (nodeAttributes.getNamedItem("backcolor") != null) {
            String color = ""+nodeAttributes.getNamedItem("backcolor").getNodeValue();
            re.setBgcolor(decodeColor(color) );
            
        }
        if (nodeAttributes.getNamedItem("mode") != null) {
            re.setTransparent(""+nodeAttributes.getNamedItem("mode").getNodeValue());
        }
        
        NodeList childsOfChild = xmlReportElement.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("printWhenExpression")) {
                re.setPrintWhenExpression( readPCDATA(child_child) );
            }
        }
    }
    
     private void readBoxElement(Node xmlReportElement, ReportElement re) {
        NamedNodeMap nodeAttributes = xmlReportElement.getAttributes();
        
        Box box = new Box();
        // ------- defaults --------
        if (nodeAttributes.getNamedItem("border") != null)
        {
            box.setBorder(""+nodeAttributes.getNamedItem("border").getNodeValue() );
            box.setLeftBorder(""+nodeAttributes.getNamedItem("border").getNodeValue() );
            box.setRightBorder(""+nodeAttributes.getNamedItem("border").getNodeValue() );
            box.setTopBorder(""+nodeAttributes.getNamedItem("border").getNodeValue() );
            box.setBottomBorder(""+nodeAttributes.getNamedItem("border").getNodeValue() );
        }
        
        if (nodeAttributes.getNamedItem("padding") != null)
        {
            box.setPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("padding").getNodeValue() ));
            box.setLeftPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("padding").getNodeValue() ));
            box.setRightPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("padding").getNodeValue() ));
            box.setTopPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("padding").getNodeValue() ));
            box.setBottomPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("padding").getNodeValue() ));
        }
        
        if (nodeAttributes.getNamedItem("borderColor") != null)
        {
            String color = ""+nodeAttributes.getNamedItem("borderColor").getNodeValue();
            java.awt.Color colorObj = decodeColor(color);
                
            box.setBorderColor(new java.awt.Color(colorObj.getRGB()));
            box.setLeftBorderColor(new java.awt.Color(colorObj.getRGB()));
            box.setRightBorderColor(new java.awt.Color(colorObj.getRGB()));
            box.setTopBorderColor(new java.awt.Color(colorObj.getRGB()));
            box.setBottomBorderColor(new java.awt.Color(colorObj.getRGB()));
            
        }
        // ------- top --------
        if (nodeAttributes.getNamedItem("topBorder") != null)
        {
            box.setTopBorder(""+nodeAttributes.getNamedItem("topBorder").getNodeValue() );
        }
        
         if (nodeAttributes.getNamedItem("topPadding") != null)
        {
            box.setTopPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("topPadding").getNodeValue() ));
        }
        
        if (nodeAttributes.getNamedItem("topBorderColor") != null)
        {
            String color = ""+nodeAttributes.getNamedItem("topBorderColor").getNodeValue();
            box.setTopBorderColor(decodeColor(color));
        }
        
        // ------- left --------
        if (nodeAttributes.getNamedItem("leftBorder") != null)
        {
            box.setLeftBorder(""+nodeAttributes.getNamedItem("leftBorder").getNodeValue() );
        }
        
         if (nodeAttributes.getNamedItem("leftPadding") != null)
        {
            box.setLeftPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("leftPadding").getNodeValue() ));
        }
        
        if (nodeAttributes.getNamedItem("leftBorderColor") != null)
        {
            String color = ""+nodeAttributes.getNamedItem("leftBorderColor").getNodeValue();
            box.setLeftBorderColor(decodeColor(color));
        }
        
        // ------- right --------
        if (nodeAttributes.getNamedItem("rightBorder") != null)
        {
            box.setRightBorder(""+nodeAttributes.getNamedItem("rightBorder").getNodeValue() );
        }
        
         if (nodeAttributes.getNamedItem("rightPadding") != null)
        {
            box.setRightPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("rightPadding").getNodeValue() ));
        }
        
        if (nodeAttributes.getNamedItem("rightBorderColor") != null)
        {
            String color = ""+nodeAttributes.getNamedItem("rightBorderColor").getNodeValue();
            box.setRightBorderColor(decodeColor(color));
        }
        
        // ------- bottom --------
        if (nodeAttributes.getNamedItem("bottomBorder") != null)
        {
            box.setBottomBorder(""+nodeAttributes.getNamedItem("bottomBorder").getNodeValue() );
        }
        
         if (nodeAttributes.getNamedItem("bottomPadding") != null)
        {
            box.setBottomPadding(Integer.parseInt(""+nodeAttributes.getNamedItem("bottomPadding").getNodeValue() ));
        }
        
        if (nodeAttributes.getNamedItem("bottomBorderColor") != null)
        {
            String color = ""+nodeAttributes.getNamedItem("bottomBorderColor").getNodeValue();
            box.setBottomBorderColor(decodeColor(color));
        }
        
        if (re instanceof ImageReportElement) ((ImageReportElement)re).setBox(box);
        if (re instanceof TextReportElement) ((TextReportElement)re).setBox(box);
        
    }
    
    static public String readPCDATA(Node textNode) {
        return readPCDATA(textNode,true);
    }
    
    
    static java.awt.Color decodeColor(String colorString)
    {
        java.awt.Color color = null;
        char firstChar = colorString.charAt(0);
        if (firstChar == '#')
        {
               color = new java.awt.Color(Integer.parseInt(colorString.substring(1), 16));
        }
        else if ('0' <= firstChar && firstChar <= '9')
        {
               color = new java.awt.Color(Integer.parseInt(colorString));
        }
        else
        {
                if (net.sf.jasperreports.engine.xml.JRXmlConstants.getColorMap().containsKey(colorString))
                {
                        color = (java.awt.Color)net.sf.jasperreports.engine.xml.JRXmlConstants.getColorMap().get(colorString);
                }
                else
                {
                        color = java.awt.Color.black;
                }
        }
        return color;
        
    }
    
    
    static public String readPCDATA(Node textNode, boolean trim) {
        NodeList list_child = textNode.getChildNodes();
        for (int ck=0; ck< list_child.getLength(); ck++) {
            Node child_child = (Node)list_child.item(ck);
            
            // --- start solution: if there is another node this should be the PCDATA-node
            Node ns = child_child.getNextSibling();
            if (ns != null)
            child_child = ns;
            // --- end solution

            final short nt = child_child.getNodeType();
            if ((nt == Node.CDATA_SECTION_NODE) || (nt == Node.TEXT_NODE)) {
               if (trim) return ((String)child_child.getNodeValue()).trim();
                return (String)child_child.getNodeValue();
            }
        }
        return "";
    }
    
    
    private void readXMLTextElement(Node xmlReportElement, TextReportElement re) {
        NamedNodeMap nodeAttributes = xmlReportElement.getAttributes();
        if (nodeAttributes.getNamedItem("textAlignment") != null)
            re.setAlign(""+nodeAttributes.getNamedItem("textAlignment").getNodeValue());
        
        if (nodeAttributes.getNamedItem("verticalAlignment") != null)
            re.setVerticalAlign(""+nodeAttributes.getNamedItem("verticalAlignment").getNodeValue());
        
        if (nodeAttributes.getNamedItem("lineSpacing") != null)
            re.setLineSpacing( ""+nodeAttributes.getNamedItem("lineSpacing").getNodeValue());
        
        if (nodeAttributes.getNamedItem("rotation") != null)
            re.setRotate(""+nodeAttributes.getNamedItem("rotation").getNodeValue());
        
        if (nodeAttributes.getNamedItem("isStyledText") != null)
            re.setIsStyledText( (""+nodeAttributes.getNamedItem("isStyledText").getNodeValue()).equals("true") );
        
        
        // Check for Font sub_element...
        NodeList childsOfChild = xmlReportElement.getChildNodes();
        for (int c_count=0; c_count< childsOfChild.getLength(); c_count++) {
            Node child_child = (Node)childsOfChild.item(c_count);
            if (child_child.getNodeType() == Node.ELEMENT_NODE && child_child.getNodeName().equals("font")) {
                NamedNodeMap subNodeAttributes = child_child.getAttributes();
                if (subNodeAttributes.getNamedItem("reportFont") != null) {
                    
                    IReportFont baseFont = null;
                    re.setReportFont(subNodeAttributes.getNamedItem("reportFont").getNodeValue());
                    for (int fn =0; fn < this.fonts.size(); ++fn) {
                        baseFont = (IReportFont)this.fonts.elementAt(fn);
                        if (baseFont != null && baseFont.getReportFont().equals(re.getReportFont())) {
                            break;
                        }
                        else
                            baseFont = null;
                    }
                    if (baseFont != null) {
                        re.setFontSize(baseFont.getFontSize());
                        re.setFontName(baseFont.getFontName());
                        re.setPDFFontName( baseFont.getPDFFontName());
                        re.setPdfEncoding( baseFont.getPdfEncoding());
                        re.setPdfEmbedded( baseFont.isPdfEmbedded());
                        re.setBold(baseFont.isBold()) ;
                        re.setItalic( baseFont.isItalic());
                        re.setStrikeTrought(baseFont.isStrikeTrought());
                        re.setUnderline(baseFont.isUnderline());
                    }else{
                        
                        //using default font
                        re.setFontSize(defaultFont.getFontSize());
                        re.setFontName(defaultFont.getFontName());
                        re.setPDFFontName( defaultFont.getPDFFontName());
                        re.setPdfEncoding( defaultFont.getPdfEncoding());
                        re.setPdfEmbedded( defaultFont.isPdfEmbedded());
                        re.setBold(defaultFont.isBold()) ;
                        re.setItalic(defaultFont.isItalic());
                        re.setStrikeTrought(defaultFont.isStrikeTrought());
                        re.setUnderline(defaultFont.isUnderline());
                    }
                    
                }
                if (subNodeAttributes.getNamedItem("fontName") != null)
                    re.setFontName(subNodeAttributes.getNamedItem("fontName").getNodeValue());
                if (subNodeAttributes.getNamedItem("pdfFontName") != null)
                    re.setPDFFontName(subNodeAttributes.getNamedItem("pdfFontName").getNodeValue());
                if (subNodeAttributes.getNamedItem("size") != null)
                    re.setFontSize( Integer.parseInt(""+subNodeAttributes.getNamedItem("size").getNodeValue()) );
                if (subNodeAttributes.getNamedItem("isBold") != null)
                    re.setBold( (new String(""+subNodeAttributes.getNamedItem("isBold").getNodeValue())).equalsIgnoreCase("true") );
                if (subNodeAttributes.getNamedItem("isItalic") != null)
                    re.setItalic( (new String(""+subNodeAttributes.getNamedItem("isItalic").getNodeValue())).equalsIgnoreCase("true") );
                if (subNodeAttributes.getNamedItem("isUnderline") != null)
                    re.setUnderline( (new String(""+subNodeAttributes.getNamedItem("isUnderline").getNodeValue())).equalsIgnoreCase("true") );
                if (subNodeAttributes.getNamedItem("isStrikeThrough") != null)
                    re.setStrikeTrought( (new String(""+subNodeAttributes.getNamedItem("isStrikeThrough").getNodeValue())).equalsIgnoreCase("true") );
                if (subNodeAttributes.getNamedItem("isPdfEmbedded") != null)
                    re.setPdfEmbedded((new String(""+subNodeAttributes.getNamedItem("isPdfEmbedded").getNodeValue())).equalsIgnoreCase("true") );
                if (subNodeAttributes.getNamedItem("pdfEncoding") != null)
                    re.setPdfEncoding( ""+subNodeAttributes.getNamedItem("pdfEncoding").getNodeValue() );
                re.setFont(null);
            }
        }
    }
    
    private Node findNextNode(Node node) {
        int type = node.getNodeType();
        if (type == Node.ELEMENT_NODE){
            return node;
        }
        NodeList children = node.getChildNodes();
        if (children != null) {
            for (int i=0; i< children.getLength(); i++) {
                return findNextNode  (children.item(i));
            }
        }
        return null;
    }
    
    
    /** Getter for property bands.
     * @return Value of property bands.
     *
     */
    public java.util.Vector getBands() {
        return bands;
    }
    
    /** Setter for property bands.
     * @param bands New value of property bands.
     *
     */
    public void setBands(java.util.Vector bands) {
        this.bands = bands;
    }
    
    /** Getter for property bottomMargin.
     * @return Value of property bottomMargin.
     *
     */
    public int getBottomMargin() {
        return bottomMargin;
    }
    
    /** Setter for property bottomMargin.
     * @param bottomMargin New value of property bottomMargin.
     *
     */
    public void setBottomMargin(int bottomMargin) {
        this.bottomMargin = bottomMargin;
    }
    
    /** Getter for property columnCount.
     * @return Value of property columnCount.
     *
     */
    public int getColumnCount() {
        return columnCount;
    }
    
    /** Setter for property columnCount.
     * @param columnCount New value of property columnCount.
     *
     */
    public void setColumnCount(int columnCount) {
        this.columnCount = columnCount;
    }
    
    /** Getter for property columnSpacing.
     * @return Value of property columnSpacing.
     *
     */
    public int getColumnSpacing() {
        return columnSpacing;
    }
    
    /** Setter for property columnSpacing.
     * @param columnSpacing New value of property columnSpacing.
     *
     */
    public void setColumnSpacing(int columnSpacing) {
        this.columnSpacing = columnSpacing;
    }
    
    /** Getter for property columnWidth.
     * @return Value of property columnWidth.
     *
     */
    public int getColumnWidth() {
        return columnWidth;
    }
    
    /** Setter for property columnWidth.
     * @param columnWidth New value of property columnWidth.
     *
     */
    public void setColumnWidth(int columnWidth) {
        this.columnWidth = columnWidth;
    }
    
    /** Getter for property elements.
     * @return Value of property elements.
     *
     */
    public java.util.Vector getElements() {
        return elements;
    }
    
    /** Setter for property elements.
     * @param elements New value of property elements.
     *
     */
    public void setElements(java.util.Vector elements) {
        this.elements = elements;
    }
    
    /** Getter for property encoding.
     * @return Value of property encoding.
     *
     */
    public java.lang.String getEncoding() {
        return encoding;
    }
    
    /** Setter for property encoding.
     * @param encoding New value of property encoding.
     *
     */
    public void setEncoding(java.lang.String encoding) {
        this.encoding = encoding;
    }
    
    public IReportKeywordLookup getKeywordLookup() {
        return keywordLookup;
    }
    
    /** Getter for property fields.
     * @return Value of property fields.
     *
     */
    public java.util.Vector getFields() {
        return fields;
    }
    
    public void addField(JRField field) {
        this.fields.add(field);
        keywordLookup.addKeyword("$F{"  + field.getName() + "}");
        this.fireReportObjectChangedListenerValueChanged( new ReportObjectChangedEvent(this,ReportObjectChangedEvent.FIELD, ReportObjectChangedEvent.ADDED, field, field));
    }
    
    public void addJRProperty(JRProperty property) {
        this.JRproperties.add(property);
    }
    
    public void removeField(JRField field) {
        this.fields.remove(field);
        keywordLookup.removeKeyword("$F{" + field.getName() + "}");
        this.fireReportObjectChangedListenerValueChanged( new ReportObjectChangedEvent(this,ReportObjectChangedEvent.FIELD, ReportObjectChangedEvent.DELETED, field, field));
    }
    
    public void removeJRProperty(JRProperty property) {
        this.JRproperties.remove(property);
    }
    
    /** Setter for property fields.
     * @param fields New value of property fields.
     *
     */
    public void setFields(java.util.Vector fields) {
        this.fields = fields;
    }
    
    /** Getter for property filename.
     * @return Value of property filename.
     *
     */
    public java.lang.String getFilename() {
        return filename;
    }
    
    /** Setter for property filename.
     * @param filename New value of property filename.
     *
     */
    public void setFilename(java.lang.String filename) {
        this.filename = filename;
    }
    
    /** Getter for property fonts.
     * @return Value of property fonts.
     *
     */
    public java.util.Vector getFonts() {
        return fonts;
    }
    
    /** Setter for property fonts.
     * @param fonts New value of property fonts.
     *
     */
    public void setFonts(java.util.Vector fonts) {
        this.fonts = fonts;
    }
    
    /** Getter for property groups.
     * @return Value of property groups.
     *
     */
    public java.util.Vector getGroups() {
        return groups;
    }
    
    /** Setter for property groups.
     * @param groups New value of property groups.
     *
     */
    public void setGroups(java.util.Vector groups) {
        this.groups = groups;
    }
    
    /** 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;
    }
    
    /** Getter for property isSummaryNewPage.
     * @return Value of property isSummaryNewPage.
     *
     */
    public boolean isIsSummaryNewPage() {
        return isSummaryNewPage;
    }
    
    /** Setter for property isSummaryNewPage.
     * @param isSummaryNewPage New value of property isSummaryNewPage.
     *
     */
    public void setIsSummaryNewPage(boolean isSummaryNewPage) {
        this.isSummaryNewPage = isSummaryNewPage;
    }
    
    /** Getter for property isTitleNewPage.
     * @return Value of property isTitleNewPage.
     *
     */
    public boolean isIsTitleNewPage() {
        return isTitleNewPage;
    }
    
    /** Setter for property isTitleNewPage.
     * @param isTitleNewPage New value of property isTitleNewPage.
     *
     */
    public void setIsTitleNewPage(boolean isTitleNewPage) {
        this.isTitleNewPage = isTitleNewPage;
    }
    
    /** Getter for property leftMargin.
     * @return Value of property leftMargin.
     *
     */
    public int getLeftMargin() {
        return leftMargin;
    }
    
    /** Setter for property leftMargin.
     * @param leftMargin New value of property leftMargin.
     *
     */
    public void setLeftMargin(int leftMargin) {
        this.leftMargin = leftMargin;
    }
    
    /** Getter for property loadTime.
     * @return Value of property loadTime.
     *
     */
    public long getLoadTime() {
        return loadTime;
    }
    
    /** Setter for property loadTime.
     * @param loadTime New value of property loadTime.
     *
     */
    public void setLoadTime(long loadTime) {
        this.loadTime = loadTime;
    }
    
    /** Getter for property modified.
     * @return Value of property modified.
     *
     */
    public boolean isModified() {
        return modified;
    }
    
    /** Setter for property modified.
     * @param modified New value of property modified.
     *
     */
    public void setModified(boolean modified) {
        this.modified = modified;
    }
    
    /** 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 orientation.
     * @return Value of property orientation.
     *
     */
    public java.lang.String getOrientation() {
        return orientation;
    }
    
    /** Setter for property orientation.
     * @param orientation New value of property orientation.
     *
     */
    public void setOrientation(java.lang.String orientation) {
        this.orientation = orientation;
    }
    
    /** Getter for property parameters.
     * @return Value of property parameters.
     *
     */
    public java.util.Vector getParameters() {
        return parameters;
    }
    
    /** Setter for property parameters.
     * @param parameters New value of property parameters.
     *
     */
    public void setParameters(java.util.Vector parameters) {
        this.parameters = parameters;
    }
    
    public void addParameter(JRParameter parameter) {
        this.parameters.add(parameter);
        keywordLookup.addKeyword("$P{" + parameter.getName() + "}");
        this.fireReportObjectChangedListenerValueChanged( new ReportObjectChangedEvent(this,ReportObjectChangedEvent.PARAMETER, ReportObjectChangedEvent.ADDED, parameter, parameter));
    }
    
    public void removeParameter(JRParameter parameter) {
        if (parameter.isBuiltin()) return;
        
        this.parameters.remove(parameter);
        keywordLookup.removeKeyword("$P{" + parameter.getName() + "}");
        this.fireReportObjectChangedListenerValueChanged( new ReportObjectChangedEvent(this,ReportObjectChangedEvent.PARAMETER, ReportObjectChangedEvent.DELETED, parameter, parameter));
    }
    
    /** Getter for property printOrder.
     * @return Value of property printOrder.
     *
     */
    public java.lang.String getPrintOrder() {
        return printOrder;
    }
    
    /** Setter for property printOrder.
     * @param printOrder New value of property printOrder.
     *
     */
    public void setPrintOrder(java.lang.String printOrder) {
        this.printOrder = printOrder;
    }
    
    /** Getter for property query.
     * @return Value of property query.
     *
     */
    public java.lang.String getQuery() {
        return query;
    }
    
    /** Setter for property query.
     * @param query New value of property query.
     *
     */
    public void setQuery(java.lang.String query) {
        this.query = query;
    }
    
    /** Getter for property rightMargin.
     * @return Value of property rightMargin.
     *
     */
    public int getRightMargin() {
        return rightMargin;
    }
    
    /** Setter for property rightMargin.
     * @param rightMargin New value of property rightMargin.
     *
     */
    public void setRightMargin(int rightMargin) {
        this.rightMargin = rightMargin;
    }
    
    /** Getter for property scriptletClass.
     * @return Value of property scriptletClass.
     *
     */
    public java.lang.String getScriptletClass() {
        return scriptletClass;
    }
    
    /** Setter for property scriptletClass.
     * @param scriptletClass New value of property scriptletClass.
     *
     */
    public void setScriptletClass(java.lang.String scriptletClass) {
        this.scriptletClass = scriptletClass;
    }
    
    /** Getter for property topMargin.
     * @return Value of property topMargin.
     *
     */
    public int getTopMargin() {
        return topMargin;
    }
    
    /** Setter for property topMargin.
     * @param topMargin New value of property topMargin.
     *
     */
    public void setTopMargin(int topMargin) {
        this.topMargin = topMargin;
    }
    
    /** Getter for property variables.
     * @return Value of property variables.
     *
     */
    public java.util.Vector getVariables() {
        return variables;
    }
    
    public void addVariable(JRVariable variable) {
        this.variables.add(variable);
        keywordLookup.addKeyword("$V{" + variable.getName() + "}");
        this.fireReportObjectChangedListenerValueChanged( new ReportObjectChangedEvent(this,ReportObjectChangedEvent.VARIABLE, ReportObjectChangedEvent.ADDED, variable, variable));
    }
    
    public void addImport(String _import) {
        if (!imports.contains(_import)) { 
            this.imports.add(_import);
        }
    }
    
    public void removeVariable(JRVariable variable) {
        this.variables.remove(variable);
        keywordLookup.removeKeyword("$V{" + variable.getName() + "}");
        this.fireReportObjectChangedListenerValueChanged( new ReportObjectChangedEvent(this,ReportObjectChangedEvent.VARIABLE, ReportObjectChangedEvent.DELETED, variable, variable));
    }
    
    /** Setter for property variables.
     * @param variables New value of property variables.
     *
     */
    public void setVariables(java.util.Vector variables) {
        this.variables = variables;
    }
    
    /** Getter for property whenNoDataType.
     * @return Value of property whenNoDataType.
     *
     */
    public java.lang.String getWhenNoDataType() {
        return whenNoDataType;
    }
    
    /** Setter for property whenNoDataType.
     * @param whenNoDataType New value of property whenNoDataType.
     *
     */
    public void setWhenNoDataType(java.lang.String whenNoDataType) {
        this.whenNoDataType = whenNoDataType;
    }
    
    /** 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;
    }
    
    /**
     *  This function compute the Y location of the band.
     *  In the designer panel, there is as space of 10 pixels (the space
     *  between the top border of the panel, and the begin of the
     *  virtual page) that are not added to this measure. This is
     *  important because permit to multiply this height for a
     *  zoom factor.
     *
     * @param b it.businesslogic.ireport.Band The band to compute.
     */
    public int getBandYLocation(Band b) {
        int y = topMargin;
        
        for (Iterator i = this.bands.iterator(); i.hasNext(); ) {
            Band band = (Band) i.next();
            if (band != b) {
                y += band.getHeight();
            } else {
                break;
            }
        }
        
        return y;
    }
    
    /** Getter for property reportFrame.
     * @return Value of property reportFrame.
     *
     */
    public it.businesslogic.ireport.gui.JReportFrame getReportFrame() {
        return reportFrame;
    }
    
    /** Setter for property reportFrame.
     * @param reportFrame New value of property reportFrame.
     *
     */
    public void setReportFrame(it.businesslogic.ireport.gui.JReportFrame reportFrame) {
        this.reportFrame = reportFrame;
    }
    
    /** Getter for property reportFormat.
     * @return Value of property reportFormat.
     *
     */
    public java.lang.String getReportFormat() {
        return reportFormat;
    }
    
    /** Setter for property reportFormat.
     * @param reportFormat New value of property reportFormat.
     *
     */
    public void setReportFormat(java.lang.String reportFormat) {
        this.reportFormat = reportFormat;
    }
    
    /**
     *  This method return the height needed by a graphics to
     *  draw all the document.
     */
    public int getDesignHeight() {
        int y = topMargin + bottomMargin;
        
        for (Iterator i = this.bands.iterator(); i.hasNext(); ) {
            y += ((Band) i.next()).getHeight();
        }
        
        return y;
    }
    
    public int getDesignHeightNoBG() {
        int y=0;
        y  += topMargin;
        y  += bottomMargin;
        
        for (Iterator i = this.bands.iterator(); i.hasNext(); ) {
            Band b = (Band) i.next();
            if (!b.getName().equals("background"))
                y += b.getHeight();
        }
        
        return y;
    }
    
    /** Add a group to the reprot and perform an adjust on jReportFrame
     * @param group New group to be inserted.
     *
     */
    public void addGroup(Group grp) {
        addGroup(grp,true);
    }
    
    /** Add a group to the reprot and perform an adjust on jReportFrame if
     *  specified
     * @param group New group to be inserted.
     * @param adjust If true, perform an adjust on jReportFrame
     */
    public void addGroup(Group grp, boolean adjust) {
        if (!groups.contains(grp)) {
            groups.addElement(grp);
        }
        String bandsstr = "";
        
        /*
         * start looking for the detail band.
         * and place header and footer of new group around it if (Adjust)
         */
        for (int i = 0; i < bands.size(); i++) {
            Band b = (Band)bands.elementAt(i);
            
            if (b.getName().equals("detail")) {
                
                if (adjust) {
                    
                    int bandYLocation = getBandYLocation(b);
                    
                    for (Iterator i2 = elements.iterator(); i2.hasNext(); ) {
                        ReportElement elem = (ReportElement) i2.next();
                        int delta_y = grp.getGroupHeader().getHeight();
                        
                        if (elem.band == grp.getGroupHeader() || elem.band == grp.getGroupFooter()) {
                            // Do nothing
                        }
                        else if (elem.position.y >= bandYLocation + 10 + b.getHeight()) {
                            delta_y += grp.getGroupFooter().getHeight();
                            elem.trasform(new java.awt.Point(0, delta_y), TransformationType.TRANSFORMATION_MOVE);
                        }
                        else if (elem.position.y >= bandYLocation  + 10) {
                            elem.trasform(new java.awt.Point(0, delta_y), TransformationType.TRANSFORMATION_MOVE);
                        }
                    }
                }
                
                // All elements with top >  detail.top must be shifted of groupHeader height
                bands.insertElementAt(grp.getGroupHeader(),i);
                // All elements with top > detail.top + detail.bottom must be shifted of groupFooter height
                bands.insertElementAt(grp.getGroupFooter(),i+2);
                
                break;
            }
        }
    }
    
    /**
     *  grpOne will be palce within grpTwo
     *  This means the header band of grpOne will come after the header band of grpTwo
     *  And the footer band of grpOne will come before the footer band of grpTwo
     * @author: Robert Lamping
     * @param direction  1 = down, -1 -up
     * @param grp  The group that must be moved
     */
    public synchronized void moveGroup(Group grp, int direction ) {
        
        Group grpOne = null;
        Group grpTwo = null;
        
        if ( getGroups().size() <=1 ) {
            return; // nothing to do
        }
        
        if (direction == 1) {
            // down
            // there must be at least one element below:
            if ( getGroups().lastElement() ==  grp ) {
                return ;               // nothing to do
            }
            grpOne = grp;
            grpTwo = (Group) getGroups().get( getGroups().indexOf(grp) + 1);
            
        } else {
            // up
            // there must be at least one element above
            if ( getGroups().firstElement() ==  grp ) {
                return ;               // nothing to do
            }
            grpTwo = grp;
            grpOne = (Group) getGroups().get( getGroups().indexOf(grp) - 1);
        }
        
        Band bandGrpOneHeader = getBandByName( grpOne.getGroupHeader().getName());
        Band bandGrpTwoHeader = getBandByName( grpTwo.getGroupHeader().getName());
        Band bandGrpOneFooter = getBandByName( grpOne.getGroupFooter().getName());
        Band bandGrpTwoFooter = getBandByName( grpTwo.getGroupFooter().getName());
        
        int delta1 = bandGrpOneHeader.getHeight();
        int delta2 = bandGrpTwoHeader.getHeight();
        int delta3 = bandGrpOneFooter.getHeight();
        int delta4 = bandGrpTwoFooter.getHeight();
        
        // Move the elements
        for (Iterator i = elements.iterator(); i.hasNext(); ) {
            ReportElement re = (ReportElement) i.next();
            
            if (re.band == bandGrpOneHeader ) {
                re.trasform(new java.awt.Point(0, delta2 ), TransformationType.TRANSFORMATION_MOVE);
            } else if (re.band ==  bandGrpTwoHeader ) {
                re.trasform(new java.awt.Point(0, -delta1 ), TransformationType.TRANSFORMATION_MOVE);
            } else if ( re.band == bandGrpTwoFooter ) {
                re.trasform(new java.awt.Point(0, delta3 ), TransformationType.TRANSFORMATION_MOVE);
            } else if ( re.band ==  bandGrpOneFooter ) {
                re.trasform(new java.awt.Point(0, -delta4 ), TransformationType.TRANSFORMATION_MOVE);
            }
        }
        
        // Now move the groups withing the bands array.
        // Move Band Group Headers
        int pos1 = bands.indexOf( bandGrpOneHeader);
        Band bandBuffer = (Band) bands.get(pos1);
        bands.remove(pos1);
        bands.insertElementAt(bandBuffer, pos1+1);
        
        // Move Band Group Footers
        int pos3 = bands.indexOf( bandGrpTwoFooter);
        bandBuffer = (Band) bands.get(pos3);
        bands.remove(pos3);
        bands.insertElementAt(bandBuffer, pos3+1);
        
        // Now move the groups within the group array
        int groupPos = groups.indexOf( grpOne );
        // groupTwo is always after grpOne
        Group groupBuffer = (Group) groups.get( groupPos);
        groups.remove(groupPos);
        groups.insertElementAt( groupBuffer, groupPos + 1);
        
    }
    
    public void delGroup(Group grp) {
        if (!groups.contains(grp)) return;
        
        String bandsstr = "";
        
        for (int i=0; i<elements.size(); ++i) {
            // Remove all elements of this group...
            ReportElement elem = (ReportElement)elements.elementAt(i);
            if (elem.getBand() == grp.getGroupHeader() || elem.getBand() == grp.getGroupFooter()) {
                elements.removeElementAt(i);
                i--;
                continue;
            }
            // Adjust elements posisitions...
            // Il element
            int delta_y = grp.getGroupHeader().getHeight();
            if (elem.position.y >= getBandYLocation(grp.getGroupFooter())+10+grp.getGroupFooter().getHeight()) {
                delta_y += grp.getGroupFooter().getHeight();
                elem.trasform(new java.awt.Point(0, -delta_y), TransformationType.TRANSFORMATION_MOVE);
            }
            else if (elem.position.y >= getBandYLocation(grp.getGroupHeader())+10+grp.getGroupHeader().getHeight()) {
                elem.trasform(new java.awt.Point(0, -delta_y), TransformationType.TRANSFORMATION_MOVE);
            }
        }
        
        bands.removeElement(grp.getGroupHeader());
        bands.removeElement(grp.getGroupFooter());
        groups.removeElement(grp);
    }
    
    public Group getGroupByName(String name) {
        for (int i = 0; i < groups.size(); i++) {
            Group grp = (Group)groups.elementAt(i);
            if (grp.getName().equals(name)) {
                return grp;
            }
        }
        return null;
    }
    
    public Band getBandByName(String name) {
        for (int i=0; i< bands.size(); i++) {
            Band band = (Band)bands.elementAt(i);
            if (band.getName().equals(name)) {
                return band;
            }
        }
        return null;
    }
    
    
    
    public void saveXMLFile() {
        saveXMLFile( this.getFilename());
    }
    
    public void saveXMLFile( String aFilename ) {
        if(isReadOnly()){
            javax.swing.JOptionPane.showMessageDialog(getReportFrame().getMainFrame(),
            it.businesslogic.ireport.util.I18n.getString("fileReadOnly", "File is read only and cannot be saved."),
            it.businesslogic.ireport.util.I18n.getString("save","Save"),javax.swing.JOptionPane.INFORMATION_MESSAGE);
            return;
        }
        
        String scriptletFileName = getScriptletFileName(aFilename);
        
        String className = "";
        java.io.File classFile = new  java.io.File(scriptletFileName);
        
        className = classFile.getName().substring(0, classFile.getName().length()-5);
        
        if (getScriptletHandling() == SCRIPTLET_IREPORT_INTERNAL_HANDLING) {
            this.setScriptletClass( className );
        }
        
        for (int pk= 0; pk < this.getJRproperties().size(); ++pk) {
            JRProperty prop = (JRProperty)getJRproperties().elementAt( pk );
            if (prop.getName().equals("ireport.scriptlethandling")) {
                getJRproperties().remove( prop );
                pk--;
            }
        }
        
        JRProperty prop = new JRProperty();
        prop.setName( "ireport.scriptlethandling" );
        prop.setValue( ""+ this.getScriptletHandling() );
        this.getJRproperties().add( prop );
        
        try {
            
            // Default file encoding
            String fileencoding = "UTF-8";
            if (encoding != null && !encoding.trim().equals("")) {
                fileencoding = encoding;
                if (fileencoding.equalsIgnoreCase("UTF-8")){
                    fileencoding = "UTF8"; // Hack for J++
                }
            } else{
                encoding = "UTF-8"; // Default XML encoding
            }
            
            //this.setCursor(Cursor.WAIT );
            //java.io.PrintWriter pw = new java.io.PrintWriter( new java.io.FileOutputStream( filename ));
            PrintWriter pw = new PrintWriter( new java.io.OutputStreamWriter( new java.io.FileOutputStream( aFilename ), fileencoding )); //UTF8
            
            pw.print("<?xml version=\"1.0\"");
            if (encoding != null && encoding.length()>0) {
                pw.print(" encoding=\""+ encoding +"\" ");
            }
            pw.println(" ?>");
            pw.println("<!-- Created with iReport - A designer for JasperReports -->");
            pw.println("<!DOCTYPE jasperReport PUBLIC \"//JasperReports//DTD Report Design//EN\" \"http://jasperreports.sourceforge.net/dtds/jasperreport.dtd\">");
            //pw.println("-->");
            // Jasper report element...
            pw.println("<jasperReport");
            pw.println("\t\t name=\""+ this.getName()  +"\"");
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR066 && this.getLanguage() != null &&
               !this.getLanguage().trim().equals("") && !this.getLanguage().equals("java") )
            {
                pw.print("\n\t\t language=\"" + this.getLanguage().trim() + "\"");
            }

            pw.println("\t\t columnCount=\""+ columnCount  +"\"");
            pw.println("\t\t printOrder=\""+ printOrder +"\"");
            pw.println("\t\t orientation=\""+ this.getOrientation() +"\"");
            pw.println("\t\t pageWidth=\""+ this.getWidth() +"\"");
            pw.println("\t\t pageHeight=\""+ this.getHeight() +"\"");
            pw.println("\t\t columnWidth=\""+  columnWidth +"\"");
            pw.println("\t\t columnSpacing=\""+ columnSpacing  +"\"");
            pw.println("\t\t leftMargin=\""+ leftMargin +"\"");
            pw.println("\t\t rightMargin=\""+ rightMargin +"\"");
            pw.println("\t\t topMargin=\""+ topMargin +"\"");
            pw.println("\t\t bottomMargin=\""+ bottomMargin +"\"");
            pw.println("\t\t whenNoDataType=\""+ whenNoDataType +"\"");
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR063 && isFloatColumnFooter() )
            {
                    pw.println("\t\t isFloatColumnFooter=\"true\"");
            }
            
            if (scriptletClass != null && scriptletClass.length()>0){
                pw.println("\t\t scriptletClass=\""+ scriptletClass +"\"");
            }
            
            pw.println("\t\t isTitleNewPage=\""+ this.isTitleNewPage  +"\"");
            pw.print("\t\t isSummaryNewPage=\""+ this.isSummaryNewPage +"\"");
             if ( CompatibilitySupport.version >= CompatibilitySupport.JR062 && this.getResourceBundleBaseName()!=null 
             	  && !this.getResourceBundleBaseName().trim().equals(""))
            {
                pw.print("\n\t\t resourceBundle=\"" + this.getResourceBundleBaseName().trim() + "\"");
            }
            pw.println(">");
            
            // Fonts...
            Enumeration e = null;
            
            e = JRproperties.elements();
            while (e.hasMoreElements()) {
                JRProperty property = (JRProperty)e.nextElement();
                if (!property.getName().startsWith("chart."))
                {
                    pw.print("\t<property name=\""+ property.getName() + "\" ");
                    pw.println("value=\""+ property.getValue() + "\" />");
                }
                
                
                
            }
            // For any chart element...
            Enumeration enum_chartElements = this.getElements().elements();
                while (enum_chartElements.hasMoreElements())
                {
                    ReportElement re = (ReportElement)enum_chartElements.nextElement();
                    if (re instanceof ChartReportElement)
                    {
                        Properties props = ((ChartReportElement)re).getProps();
                        String name = re.getName();
                        
                        Iterator keys = props.keySet().iterator();
                        int i=0;
                        while (keys.hasNext())
                        {
                            String key = ""+keys.next();
                            String val = props.getProperty(key);
                            pw.print("\t<property name=\""+ "chart." + name + "."+key + "\" ");
                            pw.println("value=\""+ Misc.xmlEscape( val) + "\" />");
                        }
                    }
                }
            
            // For IMPORTS..
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR062 )
            {
                e = imports.elements();
                while (e.hasMoreElements()) {
                    String _import = (String)e.nextElement();
                    pw.print("\t<import ");
                    pw.println("value=\""+ _import + "\" />");
                }
            }
            
            e = fonts.elements();
            
            while (e.hasMoreElements()) {
                IReportFont font = (IReportFont)e.nextElement();
                pw.print("\t<reportFont name=\""+ font.getReportFont() + "\" ");
                pw.print("isDefault=\""+ font.isDefaultFont() + "\" ");
                pw.print("fontName=\""+ font.getFontName() + "\" ");
                pw.print("size=\""+ font.getFontSize() + "\" ");
                pw.print("isBold=\""+ font.isBold() + "\" ");
                pw.print("isItalic=\""+ font.isItalic() + "\" ");
                pw.print("isUnderline=\""+ font.isUnderline() + "\" ");
                pw.print("isStrikeThrough=\""+ font.isStrikeTrought() + "\" ");
                if (Misc.nvl(font.getPDFFontName(), "").indexOf("TTF") > 0)
                    //TODO: this line cause write "" to xml when pdfFontName terminate with "TTF".
                    //this error was solved in IReportFont.setPDFFontName() take a look.
                    pw.print("pdfFontName=\""+ font.getTTFFont() + "\" ");
                else
                    pw.print("pdfFontName=\""+ font.getPDFFontName() + "\" ");
                pw.print("pdfEncoding=\""+ font.getPdfEncoding() + "\" ");
                pw.println("isPdfEmbedded=\""+ font.isPdfEmbedded() + "\"/>");
            }
            
            // Parameters
            e = parameters.elements();
            while (e.hasMoreElements()) {
                it.businesslogic.ireport.JRParameter p = (it.businesslogic.ireport.JRParameter)e.nextElement();
                if (p.isBuiltin()) continue;
                
                pw.print("\t<parameter name=\""+ p.getName() +"\" ");
                if (p.getClassType() == null ) p.setClassType("java.lang.String");
                pw.print("isForPrompting=\""+ p.isIsForPrompting() +"\" ");
                pw.print("class=\""+ p.getClassType() +"\"");
                
                if (p.getDefaultValueExpression().trim().length()> 0 ||
                p.getDescription().trim().length()>0) {
                    pw.println(">");
                    if (p.getDescription().trim().length()> 0)
                        pw.println("\t\t<parameterDescription>"+ getCDATAString(p.getDescription(),2) +"</parameterDescription>");
                    if (p.getDefaultValueExpression().trim().length()> 0) {
                        pw.print("\t\t<defaultValueExpression ");
                                                /*
                                                if( this.isUsingMultiLineExpressions() ) {
                                                        pw.print(" isCode=\"true\" ");
                                                }
                                                 */
                        pw.println(">" + getCDATAString(p.getDefaultValueExpression(),2 ) +"</defaultValueExpression>");
                    }
                    pw.println("\t</parameter>");
                }
                else
                    pw.println("/>");
                
            }
            // QueryString
            if (query != null && query.trim().length() >0 ) {
                pw.println("\t<queryString>"+ getCDATAString(query,1) + "</queryString>");
            }
            // fileds...
            e = fields.elements();
            while (e.hasMoreElements()) {
                it.businesslogic.ireport.JRField f = (it.businesslogic.ireport.JRField)e.nextElement();
                pw.print("\t<field name=\""+ f.getName() +"\" ");
                if (f.getClassType() == null ) f.setClassType("java.lang.String");
                pw.print("class=\""+ f.getClassType() +"\"");
                
                if (f.getDescription().trim().length()>0) {
                    pw.println(">");
                    if (f.getDescription().trim().length()> 0)
                        pw.println("\t\t<fieldDescription>"+ getCDATAString(f.getDescription(),2) +"</fieldDescription>");
                    pw.println("\t</field>");
                }
                else
                    pw.println("/>");
            }
            
            // variables...
            e = variables.elements();
            while (e.hasMoreElements()) {
                it.businesslogic.ireport.JRVariable f = (it.businesslogic.ireport.JRVariable)e.nextElement();
                if (f.isBuiltin()) continue;
                pw.print("\t<variable name=\""+ f.getName() +"\" ");
                if (f.getClassType() == null ) f.setClassType("java.lang.String");
                pw.print("class=\""+ f.getClassType() +"\" ");
                pw.print("resetType=\""+ f.getResetType() +"\" ");
                
                // From JasperReport 0.5.3
                if (f.getIncrementerFactoryClass() != null &&
                f.getIncrementerFactoryClass().trim().length() > 0) {
                    pw.print("incrementerFactoryClass=\""+ f.getIncrementerFactoryClass() +"\" ");
                }
                
                if ( CompatibilitySupport.version >= CompatibilitySupport.JR066 && f.getIncrementType() !=null 
             	  && !f.getIncrementType().trim().equals("None"))
                {
                    pw.print("incrementType=\"" + f.getIncrementType().trim() + "\" ");
                    if (f.getIncrementType().equals("Group"))
                    {
                        pw.print("incrementGroup=\"" + f.getIncrementGroup().trim() + "\" ");
                    }
                }
                
                if (f.getResetGroup().length() >0 ) pw.print("resetGroup=\""+ f.getResetGroup() +"\" ");
                pw.println("calculation=\""+ f.getCalculation()  +"\">");
                if (f.getExpression().length()>0) {
                    pw.print("\t\t<variableExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+ getCDATAString(f.getExpression(),2) + "</variableExpression>");
                }
                if (f.getInitialValueExpression().length()>0) {
                    pw.print("\t\t<initialValueExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+getCDATAString(f.getInitialValueExpression(),2) +"</initialValueExpression>");
                }
                pw.println("\t</variable>");
            }
            
            
            // groups...
            writeXMLGroups(pw);
            // if ( CompatibilitySupport.saveBackground)
            {
                writeXMLSection("background", pw);
            }
            
            writeXMLSection("title", pw);
            writeXMLSection("pageHeader", pw);
            writeXMLSection("columnHeader", pw);
            writeXMLSection("detail", pw);
            writeXMLSection("columnFooter", pw);
            writeXMLSection("pageFooter", pw);
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR061 )
            {
                writeXMLSection("lastPageFooter", pw);
            }
            writeXMLSection("summary", pw);
            
            pw.println("</jasperReport>");
            pw.close();
            
            if (aFilename != null) {	/*
                                com.ms.wfc.io.File f = new com.ms.wfc.io.File(filename, com.ms.wfc.io.FileMode.OPEN);
                                this.loadTime = f.getLastWriteTime().toLong();
                                f.close();
             */
            }
        } catch (Exception ex) {
            //this.setCursor(Cursor.DEFAULT);
            //MessageBox.show(ex.getMessage());
            
            java.io.StringWriter s = new java.io.StringWriter();
            ex.printStackTrace(new java.io.PrintWriter(s));
            javax.swing.JOptionPane.showMessageDialog(getReportFrame().getMainFrame(),ex.getMessage()+" "+s,"Exception",javax.swing.JOptionPane.ERROR_MESSAGE);
        }
        //this.setCursor(Cursor.DEFAULT);
        this.setLoadTime( Misc.getLastWriteTime( this.getFilename() ));
        
        // saving the scriptlet...
        if (getScriptletHandling() == SCRIPTLET_IREPORT_INTERNAL_HANDLING) {
            try {
                
                String allcode = new String(scripletCode.getAll() +"");
                
                allcode = Misc.string_replace(className,"<ScriptletClassName>", allcode);
                java.io.FileOutputStream fos = new java.io.FileOutputStream(scriptletFileName);
                fos.write( allcode.getBytes() );
                fos.close();
                
            } catch (Exception ex) {
                java.io.StringWriter s = new java.io.StringWriter();
                ex.printStackTrace(new java.io.PrintWriter(s));
                javax.swing.JOptionPane.showMessageDialog(getReportFrame().getMainFrame(),ex.getMessage()+" "+s,"Exception",javax.swing.JOptionPane.ERROR_MESSAGE);
            }
        }
        
    }
    
    void writeXMLSection(String section, PrintWriter pw) {
        // Find band...
        Band band = null;

        for (Iterator i = this.bands.iterator(); i.hasNext(); ) {
            band = (Band) i.next();
            if (band.getName().equalsIgnoreCase(section)) {
                break;
            }
        }
        if (band == null) {
            return;
        }
        
        if (section.equals("lastPageFooter") 
            && band.getHeight() == 0) return;
        
        pw.println("\t\t<"+ section +">");
        writeXMLBand(band, pw);
        pw.println("\t\t</"+ section +">");
    }
    
    
    void writeXMLGroups(java.io.PrintWriter pw) {
        // Find band...
        for (int i=0; i< groups.size(); i++) {
            Group grp = (Group)groups.elementAt(i);
            pw.print("\t\t<group ");
            pw.print(" name=\""+grp.getName()  +"\"");
            pw.print(" isStartNewColumn=\""+grp.isIsStartNewColumn() +"\"");
            pw.print(" isStartNewPage=\""+grp.isIsStartNewPage() +"\"");
            pw.print(" isResetPageNumber=\""+grp.isIsResetPageNumber() +"\"");
            pw.print(" isReprintHeaderOnEachPage=\""+grp.isIsReprintHeaderOnEachPage() +"\"");
            pw.print(" minHeightToStartNewPage=\""+grp.getMinHeightToStartNewPage() +"\"");
            pw.println(" >");
            pw.print("\t\t\t<groupExpression");
                        /*
                        if(this.isUsingMultiLineExpressions()) {
                                pw.print(" isCode=\"true\" ");
                        }
                         */
            pw.println(">" + getCDATAString(grp.getGroupExpression() ,3) +"</groupExpression>");
            pw.println("\t\t\t<groupHeader>");
            writeXMLBand(grp.getGroupHeader(), pw);
            pw.println("\t\t\t</groupHeader>");
            pw.println("\t\t\t<groupFooter>");
            writeXMLBand(grp.getGroupFooter(), pw);
            pw.println("\t\t\t</groupFooter>");
            pw.println("\t\t</group>");
        }
    }
    
    void writeXMLBand(Band band, PrintWriter pw) {
        pw.print("\t\t\t<band height=\""+ band.getHeight() + "\" ");
        
        //if () //JasperReports 0.5.0 is supported...
        {
            pw.print(" isSplitAllowed=\"" + band.isSplitAllowed() + "\" ");
        }
        pw.println(">");
        
        if (band.getPrintWhenExpression().trim().length() > 0) {
            pw.print("\t\t\t\t<printWhenExpression");
                        /*
                        if(this.isUsingMultiLineExpressions()) {
                                pw.print(" isCode=\"true\" ");
                        }
                         */
            pw.println(">" + getCDATAString(band.getPrintWhenExpression(),4) + "</printWhenExpression>");
        }
        
        for (Iterator i = this.elements.iterator(); i.hasNext(); ) {
            ReportElement re = (ReportElement) i.next();
            if (re.band == band) {
                writeXMLReportElement(re,pw);
            }
        }
        pw.println("\t\t\t</band>");
    }
    
    void writeXMLReportElement(ReportElement re, PrintWriter pw) {
        if (re instanceof StaticTextReportElement) {
            pw.println("\t\t\t\t<staticText>");
            
            writeXMLReportElementElement(re, pw);
            writeBoxElement( re,  pw, ((TextReportElement)re).getBox() );
            writeXMLTextElementElement((TextReportElement)re, pw);
            pw.println("\t\t\t\t<text>"+getCDATAString(((StaticTextReportElement)re).getText(), 4)+"</text>");
            pw.println("\t\t\t\t</staticText>");
            
        }
        else if (re instanceof TextFieldReportElement) {
            TextFieldReportElement tfre = (TextFieldReportElement)re;
            pw.print("\t\t\t\t<textField");
            pw.print(" isStretchWithOverflow=\""+ tfre.isStretchWithOverflow() +"\"");
            pw.print(" pattern=\"" + tfre.getPattern() + "\"");
            pw.print(" isBlankWhenNull=\"" + tfre.isBlankWhenNull() +"\"");
            pw.print(" evaluationTime=\""+ tfre.getEvaluationTime() +"\"");
            if (tfre.getEvaluationTime().equals("Group")) {
                pw.print(" evaluationGroup=\"" + tfre.getGroup() +"\" ");
            }
            pw.print(" hyperlinkType=\"" + tfre.getHyperlinkType() +"\" ");
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR062 )
            {
                pw.print(" hyperlinkTarget=\"" + tfre.getHyperlinkTarget() +"\" ");
            }
            
            pw.println(">");
           
            writeXMLReportElementElement(tfre, pw);
             writeBoxElement( re,  pw, ((TextReportElement)re).getBox() );
            writeXMLTextElementElement(tfre, pw);
            pw.print("\t\t\t\t<textFieldExpression ");
            if (tfre.getClassExpression().length() > 0) {
                pw.print("  class=\""+ tfre.getClassExpression()+"\"");
            }
                        /*
                        if(this.isUsingMultiLineExpressions()) {
                                pw.print(" isCode=\"true\" ");
                        }
                         */
            pw.println(">"+getCDATAString(((TextFieldReportElement)re).getText(),4)+"</textFieldExpression>");
            
            if (tfre.getAnchorNameExpression() != null && tfre.getAnchorNameExpression().length() > 0) {
                pw.print("\t\t\t\t\t<anchorNameExpression");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"+getCDATAString(tfre.getAnchorNameExpression(),5)+"</anchorNameExpression>");
            }
            if (tfre.getHyperlinkType() != null && tfre.getHyperlinkType().length() > 0) {
                if ( tfre.getHyperlinkType().equals("Reference") ||
                tfre.getHyperlinkType().equals("RemoteAnchor") ||
                tfre.getHyperlinkType().equals("RemotePage")) {
                    pw.print("\t\t\t\t\t<hyperlinkReferenceExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+getCDATAString(tfre.getHyperlinkReferenceExpression(),5)+"</hyperlinkReferenceExpression>");
                }
                if ( tfre.getHyperlinkType().equals("LocalAnchor") ||
                tfre.getHyperlinkType().equals("RemoteAnchor")) {
                    pw.print("\t\t\t\t\t<hyperlinkAnchorExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+getCDATAString(tfre.getHyperlinkAnchorExpression(),5)+"</hyperlinkAnchorExpression>");
                }
                
                if ( tfre.getHyperlinkType().equals("LocalPage") ||
                tfre.getHyperlinkType().equals("RemotePage")) {
                    pw.print("\t\t\t\t\t<hyperlinkPageExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.println(">"+getCDATAString(tfre.getHyperlinkPageExpression(),5)+"</hyperlinkPageExpression>");
                }
            }
            
            pw.println("\t\t\t\t</textField>");
        }
        else if (re instanceof ImageReportElement) {
            ImageReportElement ire = (ImageReportElement)re;
            pw.print("\t\t\t\t<image ");
            pw.print(" scaleImage=\""+ ire.getScaleImage()  +"\"");
            
            //if ( CompatibilitySupport.saveImgVerticalAlignement)
            {
                pw.print(" vAlign=\""+ ire.getVerticalAlignment()  +"\"");
            }
            //if ( CompatibilitySupport.saveImgHorizontalAlignement)
            {
                pw.print(" hAlign=\""+ ire.getHorizontalAlignment()  +"\"");
            }
            pw.print(" isUsingCache=\""+ ire.isIsUsingCache() +"\"");
            pw.print(" evaluationTime=\""+ ire.getEvaluationTime() + "\"");
            
            if (((ImageReportElement)re).getEvaluationTime().equals("Group")) {
                pw.print(" evaluationGroup=\"" + ire.getEvaluationGroup() +"\" ");
            }
            
            pw.print(" hyperlinkType=\"" + ire.getHyperlinkType()+"\" ");
            
            if ( CompatibilitySupport.version >= CompatibilitySupport.JR062 )
            {
                pw.print(" hyperlinkTarget=\"" + ire.getHyperlinkTarget() +"\" ");
            }
            
            pw.println(">");
            
            
            writeXMLReportElementElement(re, pw);
            writeBoxElement( re,  pw,  ((ImageReportElement)re).getBox() );
            writeXMLGraphicElement(ire,pw);
            
            if (re instanceof ChartReportElement) {
                pw.print("\t\t\t\t\t<imageExpression class=\"java.awt.Image\"");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.print(">"
                // + getCDATAString( getExpressionString( ire.getImageClass(), ire.getImageExpression() ), 5) +
                + getCDATAString(
                writeChartExpression( (ChartReportElement)re)
                , 5) + "</imageExpression>" );
            }
            else {
                pw.print("\t\t\t\t\t<imageExpression class=\""+ ire.getImageClass() + "\"");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.print(">"
                // + getCDATAString( getExpressionString( ire.getImageClass(), ire.getImageExpression() ), 5) +
                + getCDATAString(  ire.getImageExpression(), 5) + "</imageExpression>" );
            }
            
            
            
            if (ire.getAnchorNameExpression() != null && ire.getAnchorNameExpression().length() > 0) {
                pw.print("\t\t\t\t\t<anchorNameExpression");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"+getCDATAString(ire.getAnchorNameExpression(),5)+"</anchorNameExpression>");
            }
            if (ire.getHyperlinkType() != null && ire.getHyperlinkType().length() > 0) {
                if ( ire.getHyperlinkType().equals("Reference") ||
                ire.getHyperlinkType().equals("RemoteAnchor") ||
                ire.getHyperlinkType().equals("RemotePage")) {
                    pw.print("\t\t\t\t\t<hyperlinkReferenceExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.print(">"+getCDATAString(ire.getHyperlinkReferenceExpression(),5) +"</hyperlinkReferenceExpression>");
                }
                
                if ( ire.getHyperlinkType().equals("LocalAnchor") ||
                ire.getHyperlinkType().equals("RemoteAnchor")) {
                    pw.print("\t\t\t\t\t<hyperlinkAnchorExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.print(">"+getCDATAString(ire.getHyperlinkAnchorExpression(),5)+"</hyperlinkAnchorExpression>");
                }
                
                if ( ire.getHyperlinkType().equals("LocalPage") ||
                ire.getHyperlinkType().equals("RemotePage")) {
                    pw.print("\t\t\t\t\t<hyperlinkPageExpression");
                                        /*
                                        if(this.isUsingMultiLineExpressions()) {
                                                pw.print(" isCode=\"true\" ");
                                        }
                                         */
                    pw.print(">"+getCDATAString(ire.getHyperlinkPageExpression(),5) +"</hyperlinkPageExpression>");
                }
            }
            pw.println("\t\t\t\t</image>");
            
        } else if (re instanceof LineReportElement) {
            LineReportElement lre = (LineReportElement)re;
            pw.println("\t\t\t\t<line direction=\""+ lre.getDirection() +"\">");
            writeXMLReportElementElement(re, pw);
            writeXMLGraphicElement(lre,pw);
            pw.println("\t\t\t\t</line>");
            
        } else if (re instanceof RectangleReportElement) {
            RectangleReportElement rre = (RectangleReportElement)re;
            pw.print("\t\t\t\t<rectangle");
            //if ( CompatibilitySupport.saveRoundedRectangle && rre.radius > 0)
            {
                pw.print(" radius=\""+ rre.getRadius() + "\" ");
            }
            pw.println(">");
            writeXMLReportElementElement(re, pw);
            writeXMLGraphicElement(rre,pw);
            pw.println("\t\t\t\t</rectangle>");
            
        } else if (re instanceof EllipseReportElement ) {
            //if ( CompatibilitySupport.saveEllipse )
            {
                EllipseReportElement ere = (EllipseReportElement)re;
                pw.println("\t\t\t\t<ellipse>");
                writeXMLReportElementElement(ere, pw);
                writeXMLGraphicElement(ere,pw);
                pw.println("\t\t\t\t</ellipse>");
            }
        }
        else if (re instanceof SubReportElement) {
            SubReportElement sre = (SubReportElement)re;
            pw.println("\t\t\t\t<subreport  isUsingCache=\""+ sre.isIsUsingCache()  +"\">");
            writeXMLReportElementElement(re, pw);
            if (sre.getParametersMapExpression() != null &&
            sre.getParametersMapExpression().trim().length() > 0) {
                pw.print("\t\t\t\t\t<parametersMapExpression");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"+getCDATAString(sre.getParametersMapExpression(),5)+"</parametersMapExpression>");
            }

            Enumeration e = sre.getSubreportParameters().elements();
            while (e.hasMoreElements()) {
                JRSubreportParameter je = (JRSubreportParameter)e.nextElement();
                pw.println("\t\t\t\t\t<subreportParameter  name=\""+ je.getName() +"\">");
                pw.print("\t\t\t\t\t\t<subreportParameterExpression");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"+getCDATAString(je.getExpression(),6)+"</subreportParameterExpression>");
                pw.println("\t\t\t\t\t</subreportParameter>");
            }
            if (sre.isUseConnection() && sre.getConnectionExpression().trim().length() > 0 ) {
                pw.print("\t\t\t\t\t<connectionExpression");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"+getCDATAString(sre.getConnectionExpression(),5 )+ "</connectionExpression>");
            }
            else if (!sre.isUseConnection()  && sre.getDataSourceExpression().length() > 0) {
                pw.print("\t\t\t\t\t<dataSourceExpression");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">"+getCDATAString(sre.getDataSourceExpression(),5 )+"</dataSourceExpression>");
            }
            
            if (sre.getSubreportExpression()  != null &&
            sre.getSubreportExpression().trim().length() > 0) {
                pw.print("\t\t\t\t\t<subreportExpression  class=\""+ sre.getSubreportExpressionClass()  +"\"");
                                /*
                                if(this.isUsingMultiLineExpressions()) {
                                        pw.print(" isCode=\"true\" ");
                                }
                                 */
                pw.println(">" +
                getCDATAString(sre.getSubreportExpression(),5) + "</subreportExpression>");
            }
            
            pw.println("\t\t\t\t</subreport>");
        }
    }
    
    void writeBoxElement(ReportElement re, PrintWriter pw, Box box) {
        
        if ( CompatibilitySupport.version >= CompatibilitySupport.JR063 )
        {
            if (box == null) return;
            pw.print("\t\t\t\t\t<box");
            if (box.getTopBorder() != null) pw.print(" topBorder=\"" + box.getTopBorder() + "\"");
            if (box.getTopBorderColor() != null) pw.print(" topBorderColor=\"" +  writeEncodedColor( box.getTopBorderColor() ) + "\"");
            if (box.getTopPadding() > 0) pw.print(" topPadding=\"" + box.getTopPadding() + "\"");
            
            if (box.getLeftBorder() != null) pw.print(" leftBorder=\"" + box.getLeftBorder() + "\"");
            if (box.getLeftBorderColor() != null) pw.print(" leftBorderColor=\"" +  writeEncodedColor( box.getLeftBorderColor() ) + "\"");
            if (box.getLeftPadding() > 0) pw.print(" leftPadding=\"" + box.getLeftPadding() + "\"");
            
            if (box.getRightBorder() != null) pw.print(" rightBorder=\"" + box.getRightBorder() + "\"");
            if (box.getRightBorderColor() != null) pw.print(" rightBorderColor=\"" +  writeEncodedColor( box.getRightBorderColor() ) + "\"");
            if (box.getRightPadding() > 0) pw.print(" rightPadding=\"" + box.getRightPadding() + "\"");
            
            if (box.getBottomBorder() != null) pw.print(" bottomBorder=\"" + box.getBottomBorder() + "\"");
            if (box.getBottomBorderColor() != null) pw.print(" bottomBorderColor=\"" +  writeEncodedColor( box.getBottomBorderColor() ) + "\"");
            if (box.getBottomPadding() > 0) pw.print(" bottomPadding=\"" + box.getBottomPadding() + "\"");
            pw.println("/>");
        }
    }
    
    
    void writeXMLReportElementElement(ReportElement re, PrintWriter pw) {
        pw.println("\t\t\t\t\t<reportElement");
        pw.println("\t\t\t\t\t\tmode=\""+ re.getTransparent() + "\"");
        pw.println("\t\t\t\t\t\tx=\""+ (re.getPosition().x - leftMargin -10)+ "\"");
        pw.println("\t\t\t\t\t\ty=\""+ (re.getPosition().y - 10 - getBandYLocation(re.getBand())) +"\"");
        pw.println("\t\t\t\t\t\twidth=\""+ re.getWidth() + "\"");
        pw.println("\t\t\t\t\t\theight=\""+ re.getHeight() + "\"");
        pw.println("\t\t\t\t\t\tforecolor=\""+ writeEncodedColor(re.getFgcolor()) +"\"");
        pw.println("\t\t\t\t\t\tbackcolor=\""+ writeEncodedColor(re.getBgcolor()) +"\"");
        
        // if =052 compatibility....
        pw.println("\t\t\t\t\t\tkey=\""+ re.getKey() +"\"");
        pw.println("\t\t\t\t\t\tstretchType=\""+ re.getStretchType() +"\"");
        
        
        pw.println("\t\t\t\t\t\tpositionType=\""+ re.getPositionType() +"\"");
        pw.println("\t\t\t\t\t\tisPrintRepeatedValues=\""+ re.isIsPrintRepeatedValues() +"\"");
        pw.println("\t\t\t\t\t\tisRemoveLineWhenBlank=\""+ re.isIsRemoveLineWhenBlank() +"\"");
        pw.println("\t\t\t\t\t\tisPrintInFirstWholeBand=\""+ re.isIsPrintInFirstWholeBand() +"\"");
        
        if (re.getPrintWhenGroupChanges() != null &&  re.getPrintWhenGroupChanges().trim().length()>0)
            pw.println("\t\t\t\t\t\tprintWhenGroupChanges=\""+ re.getPrintWhenGroupChanges() +"\"");
        
        pw.print("\t\t\t\t\t\tisPrintWhenDetailOverflows=\""+ re.isIsPrintWhenDetailOverflows() +"\"");
        
        if (re.getPrintWhenExpression().length()>0) {
            pw.println(">");
            pw.print("\t\t\t\t\t\t\t<printWhenExpression");
                        /*
                        if(this.isUsingMultiLineExpressions()) {
                                pw.print(" isCode=\"true\" ");
                        }
                         */
            pw.println(">"+getCDATAString(re.getPrintWhenExpression(),7) + "</printWhenExpression>");
            pw.println("\t\t\t\t\t\t</reportElement>");
        }
        else{
            pw.println("/>");
        }
        
    }
    
    public String getCDATAString( String string, int tabCount ) {
        //if ( ! Utils.needToBeInsideCDATA( string ) )
        //	return string;
        String CRLF = System.getProperty("line.separator");
        String tab = "";
        for ( int i = 0; i < tabCount; i++ ) {
            tab += "\t";
        }
        return "<![CDATA[" + string + "]]>"; // + CRLF + tab ;
    }
    
    
    void writeXMLGraphicElement(GraphicReportElement re, PrintWriter pw) {
        pw.print("\t\t\t\t\t<graphicElement");
        pw.print(" stretchType=\"" + re.getStretchType() + "\"");
        pw.print(" pen=\""+ re.getGraphicElementPen() + "\"");
        pw.println(" fill=\"" + re.getFill() + "\" />");
    }
    
    void writeXMLTextElementElement(TextReportElement re, PrintWriter pw) {
        java.text.NumberFormat nf = java.text.NumberFormat.getInstance();
        nf.setGroupingUsed(false);
        nf.setMaximumFractionDigits(0);
        
        
        pw.print("\t\t\t\t\t<textElement");
        
        pw.print(" textAlignment=\""+ re.getAlign() +"\"");
        //if ( CompatibilitySupport.saveVerticalAlignemnt )
        {
            pw.print(" verticalAlignment=\""+ re.getVerticalAlign() +"\"");
        }
        
        pw.print(" rotation=\""+ re.getRotate() +"\"");
        
        // From JasperReport 0.5.3
        if (re.isIsStyledText()) {
            pw.print(" isStyledText=\"true\"");
        }
        
        pw.println(" lineSpacing=\""+ re.getLineSpacing() +"\">");
        
        // FONT SECTION. This code saves only difference between
        // the report font (if sepcified)...
        
        pw.print("\t\t\t\t\t\t<font");
        
        IReportFont font = null;
        if (re.getReportFont() != null && re.getReportFont().length()>0) {
            // Search the right font structure...
            for (int fn =0; fn < this.fonts.size(); ++fn) {
                font = (IReportFont)this.fonts.elementAt(fn);
                if (font != null && font.getReportFont().equals(re.getReportFont())) {
                    break;
                }
                else{
                    font = null;
                }
            }
            pw.print(" reportFont=\""+ re.getReportFont() +"\"");
        }
        
        if (font == null || !font.getFontName().equals(re.getFontName() ))
            pw.print(" fontName=\"" + re.getFontName() +"\"");
        
        if (font == null || !font.getPDFFontName().equalsIgnoreCase(re.getPDFFontName()))
            pw.print(" pdfFontName=\"" + re.getPDFFontName() +"\"");
        
        //pw.print(" pdfEncoding=\"Times-Roman\"");
        if (font == null || font.getFontSize() != re.getFontSize())
            pw.print(" size=\"" +  re.getFontSize()  +"\"");
        
        if (font == null || font.isBold() != re.isBold()) {
            pw.print(" isBold=\"" + ((re.isBold()) ? "true" : "false")+"\"");
        }
        
        if (font == null || font.isItalic() != re.isItalic()) {
            pw.print(" isItalic=\"" + ((re.isItalic()) ? "true" : "false")+"\"");
        }
        
        if (font == null || font.isUnderline() != re.isUnderline()){
            pw.print(" isUnderline=\"" + ((re.isUnderline() ) ? "true" : "false")+"\"");
        }
        
        if (font == null || font.isPdfEmbedded() != re.isPdfEmbedded()){
            pw.print(" isPdfEmbedded =\"" + ((re.isPdfEmbedded() ) ? "true" : "false")+"\"");
        }
        
        if (font == null || font.getPdfEncoding() == null || font.getPdfEncoding().length() == 0) {
            if (re.getPdfEncoding() != null && re.getPdfEncoding().length() > 0) {
                pw.print(" pdfEncoding =\"" + re.getPdfEncoding() +"\"");
            }
        }
        if (font == null || font.isStrikeTrought() != re.isStrikeTrought()){
            pw.print(" isStrikeThrough=\"" + ((re.isStrikeTrought() ) ? "true" : "false")+"\" ");
        }
        
        pw.println("/>");
        pw.println("\t\t\t\t\t</textElement>");
    }
    
    public String writeEncodedColor(java.awt.Color c) {
        String nums = "0123456789ABCDEF";
        String s = "#";
        s += nums.charAt( c.getRed()/16 );
        s += nums.charAt( c.getRed()%16 );
        s += nums.charAt( c.getGreen()/16 );
        s += nums.charAt( c.getGreen()%16 );
        s += nums.charAt( c.getBlue()/16 );
        s += nums.charAt( c.getBlue()%16 );
        return s;
    }
    
    /** Getter for property dirty.
     * @return Value of property dirty.
     *
     */
    public boolean isDirty() {
        return (dirty>0);
    }
    
    /** Setter for property dirty.
     * @param dirty New value of property dirty.
     *
     */
    public void setDirty(boolean dirty) {
        this.dirty = (dirty) ? this.dirty + 1 : 0;
    }
    
    public void decrementDirty() {
        if (this.dirty > 0)
            this.dirty--;
    }
    
    public void incrementDirty() {
        this.dirty++;
    }
    
    public int getDirtyOperations() {
        return this.dirty;
    }
    
    private String writeChartExpression(ChartReportElement chartElement) {
        String expression = "";
        
        expression = "(java.awt.Image)it.businesslogic.ireport.chart.DefaultChartFactory.drawChart(new String[]{";
        
        Properties props = chartElement.getProps();
        Iterator keys = props.keySet().iterator();
        int i=0;
        while (keys.hasNext())
        {
            String key = ""+keys.next();
            String val = props.getProperty(key);
            if (i>0) expression +=",";
            val = Misc.string_replace("\\\"", "\"", val );
            expression += "\"" + key + "=" + val +"\"";
            i++;
        }
        expression += "}, (it.businesslogic.ireport.IReportScriptlet)$P{REPORT_SCRIPTLET})";
        
        return expression;
    }
    
    /**
     * Getter for property usingMultiLineExpressions.
     * @return Value of property usingMultiLineExpressions.
     */
    public boolean isUsingMultiLineExpressions() {
        return false; //usingMultiLineExpressions;
    }
    
    /**
     * Setter for property usingMultiLineExpressions.
     * @param usingMultiLineExpressions New value of property usingMultiLineExpressions.
     */
    public void setUsingMultiLineExpressions(boolean usingMultiLineExpressions) {
        this.usingMultiLineExpressions = false; //usingMultiLineExpressions;
    }
    
    /** Getter for property JRproperties.
     * @return Value of property JRproperties.
     *
     */
    public java.util.Vector getJRproperties() {
        return JRproperties;
    }
    
    /** Setter for property JRproperties.
     * @param JRproperties New value of property JRproperties.
     *
     */
    public void setJRproperties(java.util.Vector JRproperties) {
        this.JRproperties = JRproperties;
    }
    
    /** Getter for property scripletCode.
     * @return Value of property scripletCode.
     *
     */
    public it.businesslogic.ireport.ScriptletCode getScripletCode() {
        return scripletCode;
    }
    
    /** Setter for property scripletCode.
     * @param scripletCode New value of property scripletCode.
     *
     */
    public void setScripletCode(it.businesslogic.ireport.ScriptletCode scripletCode) {
        this.scripletCode = scripletCode;
    }
    
    /** Getter for property scriptletHandling.
     * @return Value of property scriptletHandling.
     *
     */
    public int getScriptletHandling() {
        return scriptletHandling;
    }
    
    /** Setter for property scriptletHandling.
     * @param scriptletHandling New value of property scriptletHandling.
     *
     */
    public void setScriptletHandling(int scriptletHandling) {
        this.scriptletHandling = scriptletHandling;
    }
    
    
    public String getScriptletFileName() {
        return this.getScriptletFileName( this.getFilename() );
    }
    
    public String getScriptletFileName(String file) {
        if (file == null) return "Scriptlet.java";
        
        // we assume /xxx/yyY/qqq/myreport.xml as input file name
        if (file.length() > 3) {
            file = Misc.changeFileExtension(file,  "");
            file = file.substring(0, file.length() -1 );
            File f = new File( file );
            String className = f.getName() + "Scriptlet";
            
            className = Misc.string_replace("_",".", className);
            className = Misc.string_replace("_"," ",className);
            if ( Character.isDigit(className.charAt( 0 )  )) {
                className = "_"+ className;
            }
            className += ".java";
            return  f.getPath().substring(0, f.getPath().length() - f.getName().length()) + className;
        }
        
        return "Scriptlet.java";
    }
    
    
    /**
     * Default font specified in xml file.
     * @return
     */
    public IReportFont getDefaultFont() {
        return defaultFont;
    }
    
    public boolean isReadOnly(){
        return readOnly;
    }
    public void checkReadOnlyFlag(){
        checkReadOnlyFlag(getFilename());
    }
    public void checkReadOnlyFlag(String oF){
        if (oF == null) return;
        File f = new File(oF);
        try {
        if (!f.exists()) {
            readOnly = false;
        } else {
            readOnly = !f.canWrite();
        }
        } catch (Exception ex) { }
        readOnly = false;
    }
    
    /**
     * return the band that encloses the parameter originY
     * @param originY
     * @return
     *
     * an originY < 0 will return nothing
     * an originY > designheight will return the Summary band
     */
    public Band getBandByPosition( int originY ){
        Band bname = null;
        for (Iterator i = this.getBands().iterator(); i.hasNext(); ) {
            Band b = (Band) i.next();
            if ( this.getBandYLocation(b) + 10 <= originY) {
                bname = b;
            }
        }
        return bname;
    }

    public Vector getImports() {
        return imports;
    }

    public void setImports(Vector imports) {
        this.imports = imports;
    }

    public String getResourceBundleBaseName() {
        return ResourceBundleBaseName;
    }

    public void setResourceBundleBaseName(String ResourceBundleBaseName) {
        this.ResourceBundleBaseName = ResourceBundleBaseName;
    }

    public boolean isFloatColumnFooter() {
        return floatColumnFooter;
    }

    public void setFloatColumnFooter(boolean floatColumnFooter) {
        this.floatColumnFooter = floatColumnFooter;
    }

    public String getLanguage() {
        return language;
    }

    public void setLanguage(String language) {
        this.language = language;
    }

    /**
     * Registers ReportObjectChangedListener to receive events.
     * @param listener The listener to register.
     */
    public synchronized void addReportObjectChangedListener(it.businesslogic.ireport.gui.event.ReportObjectChangedListener listener) {

        if (listenerList == null ) {
            listenerList = new javax.swing.event.EventListenerList();
        }
        listenerList.add (it.businesslogic.ireport.gui.event.ReportObjectChangedListener.class, listener);
    }

    /**
     * Removes ReportObjectChangedListener from the list of listeners.
     * @param listener The listener to remove.
     */
    public synchronized void removeReportObjectChangedListener(it.businesslogic.ireport.gui.event.ReportObjectChangedListener listener) {

        listenerList.remove (it.businesslogic.ireport.gui.event.ReportObjectChangedListener.class, listener);
    }

    /**
     * Notifies all registered listeners about the event.
     * It is public because a modification can be notified by external sources....
     * 
     * @param event The event to be fired
     */
    public void fireReportObjectChangedListenerValueChanged(it.businesslogic.ireport.gui.event.ReportObjectChangedEvent event) {

        if (listenerList == null) return;
        Object[] listeners = listenerList.getListenerList ();
        for (int i = listeners.length-2; i>=0; i-=2) {
            if (listeners[i]==it.businesslogic.ireport.gui.event.ReportObjectChangedListener.class) {
                ((it.businesslogic.ireport.gui.event.ReportObjectChangedListener)listeners[i+1]).reportObjectChanged (event);
            }
        }
    }

    public java.util.HashMap getProposedValues() {
        return proposedValues;
    }

    public void setProposedValues(java.util.HashMap proposedValues) {
        this.proposedValues = proposedValues;
    }
}
