/*
 *  iReport  --  Visual designer for generating JasperReports Documents
 *  Copyright (C) 2002  Giulio Toffoli gt@businesslogic.it
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *  Giulio Toffoli
 *  Via T.Aspetti, 233
 *  35100 Padova ITALY
 *  gt@businesslogic.it
 */
package com.businesslogic.ireport;

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

public class Report
{
	Point pagesize;
	String reportFormat; // The name of a preset size
	String reportName;
	Vector elements;
	public Vector bands;
	public Vector groups;
	public String filename=null;
	public String query="";
	public String encoding="";
	
	public ReportForm reportForm=null;
	
	public int columnCount=1;
	public String printOrder="Vertical";  //(Vertical | Horizontal)
	public String orientation="Portrait"; //(Portrait | Landscape)
	public String whenNoDataType="NoPages";
	public int columnWidth=555;
	public int columnSpacing=0;
	public int leftMargin=20;
	public int rightMargin=20;
	public int topMargin=30;
	public int bottomMargin=30;
	public boolean isTitleNewPage=false; // (true | false) "false"
	public boolean isSummaryNewPage=false; // (true | false) "false"
	
	public String scriptletClass = "";
	
	public long loadTime=0;

	public Vector fields = null;
	public Vector parameters = null;
	public Vector variables = null;
	public Vector fonts = null;
	//scriptletClass NMTOKEN #IMPLIED
	
	public Point getPagesize(){	return pagesize; }

	public void setPagesize(Point newsize){ pagesize = newsize;}
	
	public String getReportFormat(){	return reportFormat;	}
	public void setReportFormat(String newreportFormat){ reportFormat = newreportFormat;}
	
	public String getReportName(){	return reportName;	}
	public void setReportName(String newreportName){ reportName = newreportName;}
	
	public Vector getElements(){	return elements;	}
	public void setElements(Vector newElements){ elements = newElements;}
	
	
	String separators=" ~!@%^&*()-+=|/[]:;<> ,	.?";
	int parentesi_opened=0;
	int pos=0;
	
	
	public Report(String name, Point psize, String format)
	{
		this.pagesize=psize;
		this.reportName = name;
		this.reportFormat = format;
		elements = new Vector();
		bands = new Vector();
		groups = new Vector();
		
		fields = new Vector();
		parameters = new Vector();
		variables = new Vector(); 
		fonts= new Vector(); 
		query="";
		
		

		
		
		// Add basic variables...
		variables.addElement(new JRVariable( "PAGE_NUMBER", true ));
		variables.addElement(new JRVariable("REPORT_COUNT", true));
		variables.addElement(new JRVariable("COLUMN_COUNT", true));
	
		Band title = new Band("title",50);
		Band pageHeader = new Band("pageHeader",50);
		Band columnHeader = new Band("columnHeader",30);
		Band detail = new Band("detail",50);
		Band columnFooter = new Band("columnFooter",30);
		Band pageFooter = new Band("pageFooter",50);
		Band summary = new Band("summary",50);
		
		bands.addElement(title);
		bands.addElement(pageHeader);
		bands.addElement(columnHeader);
		bands.addElement(detail);
		bands.addElement(columnFooter);
		bands.addElement(pageFooter);
		bands.addElement(summary);
	}
	
	public Report(Document xmldoc, String filename)
	{
		this.filename = filename;
		
		if (filename != 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();
		}
		
		fields = new Vector();
		parameters = new Vector();
		variables = new Vector();
		fonts= new Vector(); 
		query="";
		
		// Add basic variables...
		variables.addElement(new JRVariable("PAGE_NUMBER", true));
		variables.addElement(new JRVariable("REPORT_COUNT", true));
		variables.addElement(new JRVariable("COLUMN_COUNT", true));
		
		this.pagesize= new Point(0,0);
		Element jasperReport = xmldoc.getRoot();
		this.reportName = ""+jasperReport.getAttribute("name");
		this.reportFormat = "Custom";
		this.pagesize = new Point(595,842);
		
		if (jasperReport.getAttribute("pageWidth") != null)
		{
			pagesize.x = Integer.parseInt( ""+jasperReport.getAttribute("pageWidth")); 
		}
		if (jasperReport.getAttribute("pageHeight") != null)
		{
			pagesize.y = Integer.parseInt( ""+jasperReport.getAttribute("pageHeight")); 
		}
		
		this.orientation = "Portrait";
		if (jasperReport.getAttribute("orientation") != null)
		{
			orientation = ""+jasperReport.getAttribute("orientation"); 
		}
		
		this.printOrder = "Vertical";
		if (jasperReport.getAttribute("printOrder") != null)
			printOrder = ""+jasperReport.getAttribute("printOrder"); 
		
		this.whenNoDataType = "NoPages";
		if (jasperReport.getAttribute("whenNoDataType") != null)
			whenNoDataType = ""+jasperReport.getAttribute("whenNoDataType");
		
		this.scriptletClass = "";
		if (jasperReport.getAttribute("scriptletClass") != null)
			scriptletClass = ""+jasperReport.getAttribute("scriptletClass");
		
		this.isTitleNewPage = false;
		if (jasperReport.getAttribute("isTitleNewPage") != null)
			isTitleNewPage = (""+jasperReport.getAttribute("isTitleNewPage")).equalsIgnoreCase("true");;
										
		this.isSummaryNewPage = false;
		if (jasperReport.getAttribute("isSummaryNewPage") != null)
			isSummaryNewPage = (""+jasperReport.getAttribute("isSummaryNewPage")).equalsIgnoreCase("true");;
				
			
		if (jasperReport.getAttribute("leftMargin") != null)
		{
			leftMargin  = Integer.parseInt( ""+jasperReport.getAttribute("leftMargin")); 
		}
		
		if (jasperReport.getAttribute("rightMargin") != null)
		{
			rightMargin = Integer.parseInt( ""+jasperReport.getAttribute("rightMargin")); 
		}
		
		if (jasperReport.getAttribute("topMargin") != null)
		{
			topMargin = Integer.parseInt( ""+jasperReport.getAttribute("topMargin")); 
		}
		if (jasperReport.getAttribute("bottomMargin") != null)
		{
			bottomMargin = Integer.parseInt( ""+jasperReport.getAttribute("bottomMargin")); 
		}
		if (jasperReport.getAttribute("columnCount") != null)
		{
			columnCount = Integer.parseInt( ""+jasperReport.getAttribute("columnCount")); 
		}
		if (jasperReport.getAttribute("columnWidth") != null)
		{
			columnWidth = Integer.parseInt( ""+jasperReport.getAttribute("columnWidth")); 
		}
		if (jasperReport.getAttribute("columnSpacing") != null)
		{
			columnSpacing = Integer.parseInt( ""+jasperReport.getAttribute("columnSpacing")); 
		}
		
		elements = new Vector();
		bands = new Vector();
		groups = new Vector();
		Band title = new Band("title",0);
		Band pageHeader = new Band("pageHeader",0);
		Band columnHeader = new Band("columnHeader",0);
		Band detail = new Band("detail",0);
		Band columnFooter = new Band("columnFooter",0);
		Band pageFooter = new Band("pageFooter",0);
		Band summary = new Band("summary",0);
		

		//bands.addElement(summary);

		
		ElementCollection ec = jasperReport.getChildren();
		for (int i=0; i<ec.getLength(); ++i)
		{
			Element child = (Element)ec.getChild(i);
			if (child.getTagName().getName().equalsIgnoreCase("parameter"))
			{
				String p_name = ""+child.getAttribute("name");
				String p_class = ""+child.getAttribute("class");
				
				boolean isForPrompting = true;
				if (child.getAttribute("isForPrompting")!=null)
					isForPrompting = (""+child.getAttribute("isForPrompting")).equalsIgnoreCase("true");
				
				JRParameter param = new JRParameter(p_name,p_class,isForPrompting);
				
				// Search for subchild... parameterDescription...
				if (child.getChildren().getLength() > 0)
				{
					ElementCollection sub_ec = child.getChildren();
					for (int k=0; k<sub_ec.getLength(); ++k)
					{
						Element sub_child = (Element)sub_ec.getChild(k);
						if (sub_child.getTagName().getName().equalsIgnoreCase("parameterDescription"))
						{
							param.description = sub_child.getText().trim();
						}
						else if (sub_child.getTagName().getName().equalsIgnoreCase("defaultValueExpression"))
						{
							param.defaultValueExpression = sub_child.getText().trim();
						}
					}
				}
				
				parameters.addElement( param);
			}
			else if (child.getTagName().getName().equalsIgnoreCase("reportFont"))
			{
				IFont font = new IFont();
				if (child.getAttribute("name") != null)
					font.name = ""+child.getAttribute("name");
				if (child.getAttribute("fontName") != null)
					font.fontName = ""+child.getAttribute("fontName");
				if (child.getAttribute("pdfFontName") != null)
					font.pdfFontName = ""+child.getAttribute("pdfFontName");
				if (child.getAttribute("size") != null)
					font.size = Integer.valueOf(""+child.getAttribute("size")).intValue();
				if (child.getAttribute("isBold") != null)
					font.isBold = (new String(""+child.getAttribute("isBold"))).equalsIgnoreCase("true");
				if (child.getAttribute("isItalic") != null)
					font.isItalic = (new String(""+child.getAttribute("isItalic"))).equalsIgnoreCase("true");
				if (child.getAttribute("isUnderline") != null)
					font.isUnderline = (new String(""+child.getAttribute("isUnderline"))).equalsIgnoreCase("true");
				if (child.getAttribute("isStrikeThrough") != null)
					font.isStrikeThrough = (new String(""+child.getAttribute("isStrikeThrough"))).equalsIgnoreCase("true");
				if (child.getAttribute("isDefault") != null)
					font.isDefault = (new String(""+child.getAttribute("isDefault"))).equalsIgnoreCase("true");
				
				if (child.getAttribute("isPdfEmbedded") != null)
					font.isPdfEmbedded = (new String(""+child.getAttribute("isPdfEmbedded"))).equalsIgnoreCase("true");
				
				if (child.getAttribute("pdfEncoding") != null)
					font.pdfEncoding = ""+child.getAttribute("pdfEncoding");
				this.fonts.addElement(font);

			}
			else if (child.getTagName().getName().equalsIgnoreCase("queryString"))
			{
					query = child.getText().trim();
			}
			else if (child.getTagName().getName().equalsIgnoreCase("field"))
			{
				String f_name = ""+child.getAttribute("name");
				String f_class = ""+child.getAttribute("class");
				
				JRField field = new JRField(f_name,f_class);
				
				// Search for subchild... parameterDescription...
				if (child.getChildren().getLength() > 0)
				{
					ElementCollection sub_ec = child.getChildren();
					for (int k=0; k<sub_ec.getLength(); ++k)
					{
						Element sub_child = (Element)sub_ec.getChild(k);
						if (sub_child.getTagName().getName().equalsIgnoreCase("fieldDescription"))
						{
							field.description = sub_child.getText().trim();
						}
					}
				}
				fields.addElement( field);
			}
			else if (child.getTagName().getName().equalsIgnoreCase("variable"))
			{
				String v_name = ""+child.getAttribute("name");
				String v_class = ""+child.getAttribute("class");
				JRVariable jvar =  new JRVariable(v_name,false);
				jvar.classType = v_class;
				if (child.getAttribute("resetType")!= null)
					jvar.resetType = ""+child.getAttribute("resetType");
				else jvar.resetType = "Report";
				if (child.getAttribute("resetGroup")!= null)
					jvar.resetGroup = ""+child.getAttribute("resetGroup");
				else jvar.resetGroup = "";
				if (child.getAttribute("calculation")!= null)
					jvar.calculation = ""+child.getAttribute("calculation");
				else jvar.calculation = "Nothing";
				jvar.expression = "";
				// Get childs...
				ElementCollection sub_ec = child.getChildren();
				for (int k=0; k<sub_ec.getLength(); ++k)
				{
					Element sub_child = (Element)sub_ec.getChild(k);
					if (sub_child.getTagName().getName().equalsIgnoreCase("variableExpression"))
					{
						jvar.expression = sub_child.getText().trim();
					}
					else if (sub_child.getTagName().getName().equalsIgnoreCase("initialValueExpression"))
					{
						jvar.initialValueExpression = sub_child.getText().trim();
					}
				}
				variables.addElement(jvar);
			}
			else if (child.getTagName().getName().equalsIgnoreCase("group"))
			{
				Group grp = new Group(""+child.getAttribute("name"));
				if (child.getAttribute("isStartNewColumn") != null)
					grp.isStartNewColumn  = (""+child.getAttribute("isStartNewColumn")).equals("true");			
				if (child.getAttribute("isStartNewPage") != null)
					grp.isStartNewPage  = (""+child.getAttribute("isStartNewPage")).equals("true");
				if (child.getAttribute("isResetPageNumber") != null)
					grp.isResetPageNumber  = (""+child.getAttribute("isResetPageNumber")).equals("true");
				if (child.getAttribute("isReprintHeaderOnEachPage") != null)
					grp.isReprintHeaderOnEachPage  = (""+child.getAttribute("isReprintHeaderOnEachPage")).equals("true");
				if (child.getAttribute("minHeightToStartNewPage") != null)
					grp.minHeightToStartNewPage =  Integer.parseInt( ""+child.getAttribute("minHeightToStartNewPage"));
				
				groups.addElement(grp);
				
				
				ElementCollection sub_ec = child.getChildren();
				for (int k=0; k<sub_ec.getLength(); ++k)
				{
					Element sub_child = (Element)sub_ec.getChild(k);
					if (sub_child.getTagName().getName().equalsIgnoreCase("groupExpression"))
					{
						grp.groupExpression = sub_child.getText().trim();
					}
					else if (sub_child.getTagName().getName().equalsIgnoreCase("groupHeader"))
					{
						Element band = sub_child.getChild(1);
						if (band.getAttribute("height") != null)
							grp.groupHeader.height  =  Integer.parseInt( ""+band.getAttribute("height"));
						readBandElements(band,grp.groupHeader);
					}
					else if (sub_child.getTagName().getName().equalsIgnoreCase("groupFooter"))
					{
						Element band = sub_child.getChild(1);
						if (band.getAttribute("height") != null)
							grp.groupFooter.height  =  Integer.parseInt( ""+band.getAttribute("height"));
						readBandElements(band,grp.groupFooter);
					}
				}
				
			}
			else if (child.getTagName().getName().equalsIgnoreCase("title"))
			{
				title = new Band("title",50);
				Element band = child.getChild(1);
				if (band.getAttribute("height") != null)
					title.height =  Integer.parseInt( ""+band.getAttribute("height"));
				readBandElements(band,title);
			}
			else if (child.getTagName().getName().equalsIgnoreCase("pageHeader"))
			{
				pageHeader = new Band("pageHeader",50);
				Element band = child.getChild(1);
				if (band.getAttribute("height") != null)
					pageHeader.height =  Integer.parseInt( ""+band.getAttribute("height"));
				readBandElements(band,pageHeader);
			}
			else if (child.getTagName().getName().equalsIgnoreCase("columnHeader"))
			{
				columnHeader = new Band("columnHeader",0);
				Element band = child.getChild(1);
				if (band.getAttribute("height") != null)
					columnHeader.height =  Integer.parseInt( ""+band.getAttribute("height"));
				readBandElements(band,columnHeader);
			}
			else if (child.getTagName().getName().equalsIgnoreCase("detail"))
			{
				detail = new Band("detail",100);
				Element band = child.getChild(1);
				if (band.getAttribute("height") != null)
					detail.height =  Integer.parseInt( ""+band.getAttribute("height"));
				readBandElements(band,detail);
			}
			else if (child.getTagName().getName().equalsIgnoreCase("columnFooter"))
			{
				columnFooter = new Band("columnFooter",0);
				Element band = child.getChild(1);
				if (band.getAttribute("height") != null)
					columnFooter.height =  Integer.parseInt( ""+band.getAttribute("height"));
				readBandElements(band,columnFooter);
			}
			else if (child.getTagName().getName().equalsIgnoreCase("pageFooter"))
			{
				pageFooter = new Band("pageFooter",50);
				Element band = child.getChild(1);
				if (band.getAttribute("height") != null)
					pageFooter.height =  Integer.parseInt(""+band.getAttribute("height"));
				readBandElements(band,pageFooter);
			}
			
			else if (child.getTagName().getName().equalsIgnoreCase("summary"))
			{
				summary = new Band("summary",0);
				Element band = child.getChild(1);
				if (band.getAttribute("height") != null)
					summary.height =  Integer.parseInt( ""+band.getAttribute("height"));
				readBandElements(band,summary);
			}
			
		}
		bands.addElement(title);
		bands.addElement(pageHeader);
		bands.addElement(columnHeader);
		bands.addElement(detail);
		bands.addElement(columnFooter);
		bands.addElement(pageFooter);
		bands.addElement(summary);
		
		for (int i=0; i< groups.size(); i++)
		{
			Group grp = (Group)groups.elementAt(i);
			addGroup(grp);
		}
		String bandsstr="";
		for (int i=0; i< bands.size(); i++)
		{
			Band b = (Band)bands.elementAt(i);
			bandsstr += i+" "+b.name + " "+ b.height + "\n\r";
		}
		//MessageBox.show(bands.size()+ "\n\r"+bandsstr);

		
		// Translate coords to iReport coord system...
		Enumeration enum = elements.elements();
		while (enum.hasMoreElements())
		{
			ReportElement re = (ReportElement)enum.nextElement();
			re.trasform(new Point(this.leftMargin+10, this.getBandYLocation(re.band)+10), TransformationType.TRANSFORMATION_MOVE); 
		}
	}
	
	public void readBandElements(Element band_element,Band band)
	{
		// See all elements...		
		ElementCollection ec = band_element.getChildren();
		for (int i=0; i<ec.getLength(); ++i)
		{
			Element element = (Element)ec.getChild(i);
			if (element.getTagName().getName().equalsIgnoreCase("statictext"))
			{
				StaticTextReportElement re = new StaticTextReportElement(0,0,0,0,new Brush(Color.AQUA));
				re.band = band;
				
				// Element properties...
				ElementCollection sub_ec = element.getChildren();
				for (int k=0; k<sub_ec.getLength(); ++k)
				{
					Element sub_element = (Element)sub_ec.getChild(k);
					if (sub_element.getTagName().getName().equalsIgnoreCase("reportElement"))
					{
						readXMLReportElement(sub_element,re);
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("textElement"))
					{
						readXMLTextElement(sub_element,re);
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("text"))
					{
						re.text = sub_element.getText().trim();
					}
				}
				
				re.setPosition(re.position);
				re.trasform(new Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE); 
				elements.addElement(re);
			}
			else if (element.getTagName().getName().equalsIgnoreCase("image"))
			{
				ImageReportElement re = new ImageReportElement(0,0,0,0,new Brush(Color.AQUA));
				re.band = band;
				
				if (element.getAttribute("scaleImage") != null)
					re.scaleImage =  ""+element.getAttribute("scaleImage");
				
				if (element.getAttribute("evaluationTime") != null)
					re.evaluationTime =  ""+element.getAttribute("evaluationTime");
				
				if (element.getAttribute("evaluationGroup") != null)
					re.evaluationGroup  =  ""+element.getAttribute("evaluationGroup");
				
				if (element.getAttribute("hyperlinkType") != null)
					re.hyperlinkType  =  ""+element.getAttribute("hyperlinkType");
				
				// Element properties...
				ElementCollection sub_ec = element.getChildren();
				for (int k=0; k<sub_ec.getLength(); ++k)
				{
					Element sub_element = (Element)sub_ec.getChild(k);
					if (sub_element.getTagName().getName().equalsIgnoreCase("reportElement"))
					{
						readXMLReportElement(sub_element,re);
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("graphicElement"))
					{
						if (sub_element.getAttribute("pen") != null)
						{
								re.graphicElementPen = ""+sub_element.getAttribute("pen");
						}
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("imageExpression"))
					{
						re.imageExpression = sub_element.getText();
						if (re.imageExpression.length()>2 &&
							re.imageExpression.charAt(0)=='\"')
							re.imageExpression = re.imageExpression.substring(1);
						
						if (re.imageExpression.length()>1 &&
							re.imageExpression.charAt(re.imageExpression.length()-1)=='\"')
							re.imageExpression = re.imageExpression.substring(0,re.imageExpression.length()-1);
						
						try {
							if (re.imageClass.equalsIgnoreCase("java.lang.String"))
							{
								Bitmap bmp = new Bitmap(re.imageExpression);
								if (bmp != null)
								{
											re.img  =  bmp;		
								}
							}
						} catch (Exception ex) {}
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("anchorNameExpression"))
					{
						re.anchorNameExpression = sub_element.getText().trim();
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("hyperlinkAnchorExpression"))
					{
						re.hyperlinkAnchorExpression  = sub_element.getText().trim();
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("hyperlinkPageExpression"))
					{
						re.hyperlinkPageExpression = sub_element.getText().trim();
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("hyperlinkReferenceExpression"))
					{
						re.hyperlinkReferenceExpression  = sub_element.getText().trim();
					}
					
				}
				
				re.setPosition(re.position);
				re.trasform(new Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE); 
				elements.addElement(re);
			}
			else if (element.getTagName().getName().equalsIgnoreCase("rectangle"))
			{
				RectangleReportElement re = new RectangleReportElement(0,0,0,0,new Brush(Color.DARKGRAY));
				re.band = band;

				// Element properties...
				ElementCollection sub_ec = element.getChildren();
				for (int k=0; k<sub_ec.getLength(); ++k)
				{
					Element sub_element = (Element)sub_ec.getChild(k);
					if (sub_element.getTagName().getName().equalsIgnoreCase("reportElement"))
					{
						readXMLReportElement(sub_element,re);
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("graphicElement"))
					{
						if (sub_element.getAttribute("pen") != null)
						{
								re.graphicElementPen = ""+sub_element.getAttribute("pen");
						}
					}
				}
				
				re.setPosition(re.position);
				re.trasform(new Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE); 
				elements.addElement(re);
			}
			else if (element.getTagName().getName().equalsIgnoreCase("line"))
			{
				LineReportElement re = new LineReportElement(0,0,0,0,new Brush(Color.DARKGRAY));
				re.band = band;
				
				if (element.getAttribute("direction") != null)
					re.direction =  ""+element.getAttribute("direction");

				// Element properties...
				ElementCollection sub_ec = element.getChildren();
				for (int k=0; k<sub_ec.getLength(); ++k)
				{
					Element sub_element = (Element)sub_ec.getChild(k);
					if (sub_element.getTagName().getName().equalsIgnoreCase("reportElement"))
					{
						readXMLReportElement(sub_element,re); 
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("graphicElement"))
					{
						if (sub_element.getAttribute("pen") != null)
							re.graphicElementPen = ""+sub_element.getAttribute("pen");
						if (sub_element.getAttribute("stretchType") != null)
							re.stretchType = ""+sub_element.getAttribute("stretchType");
						if (sub_element.getAttribute("fill") != null)
							re.fill = ""+sub_element.getAttribute("fill");
						
					}
				}
				
				re.setPosition(re.position);
				re.trasform(new Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE); 
				elements.addElement(re);
			}
			else if (element.getTagName().getName().equalsIgnoreCase("textField"))
			{
				TextFieldReportElement re = new TextFieldReportElement(0,0,0,0,new Brush(Color.AQUA));
				re.band = band;
				
				if (element.getAttribute("evaluationTime") != null)
					re.evaluationTime =  ""+element.getAttribute("evaluationTime");
				
				if (element.getAttribute("evaluationGroup") != null)
					re.evaluationGroup  =  ""+element.getAttribute("evaluationGroup");
				
				if (element.getAttribute("isStretchWithOverflow") != null)
					re.isStretchWithOverflow  =  (new String(""+element.getAttribute("isStretchWithOverflow")).equals("true"));
				
				if (element.getAttribute("isBlankWhenNull") != null)
					re.isBlankWhenNull  =  (new String(""+element.getAttribute("isBlankWhenNull")).equals("true"));
				
				if (element.getAttribute("pattern") != null)
					re.pattern  =  ""+element.getAttribute("pattern");
				
				if (element.getAttribute("hyperlinkType") != null)
					re.hyperlinkType  =  ""+element.getAttribute("hyperlinkType");
				
				// Element properties...
				ElementCollection sub_ec = element.getChildren();
				for (int k=0; k<sub_ec.getLength(); ++k)
				{
					Element sub_element = (Element)sub_ec.getChild(k);
					if (sub_element.getTagName().getName().equalsIgnoreCase("reportElement"))
					{
						readXMLReportElement(sub_element,re);
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("textElement"))
					{
						readXMLTextElement(sub_element,re);
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("textFieldExpression"))
					{
						re.text = sub_element.getText().trim();
						if (sub_element.getAttribute("class") != null)
						{
								re.fieldClass = ""+sub_element.getAttribute("class");
						}
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("anchorNameExpression"))
					{
						re.anchorNameExpression = sub_element.getText().trim();
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("hyperlinkAnchorExpression"))
					{
						re.hyperlinkAnchorExpression  = sub_element.getText().trim();
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("hyperlinkPageExpression"))
					{
						re.hyperlinkPageExpression = sub_element.getText().trim();
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("hyperlinkReferenceExpression"))
					{
						re.hyperlinkReferenceExpression  = sub_element.getText().trim();
					}
				}
				
				
				re.setPosition(re.position);
				re.trasform(new Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE); 
				elements.addElement(re);
			}
			else if (element.getTagName().getName().equalsIgnoreCase("elementGroup"))
			{
				readBandElements(element,band);
			}
			else if (element.getTagName().getName().equalsIgnoreCase("subreport"))
			{
				SubReportElement re = new SubReportElement(0,0,0,0,new Brush(Color.AQUA));
				re.band = band;
				
				if (element.getAttribute("isUsingCache") != null)
					re.isUsingCache =  (""+element.getAttribute("isUsingCache")).equals("true");
				
				// Element properties...
				
				ElementCollection sub_ec = element.getChildren();
				for (int k=0; k<sub_ec.getLength(); ++k)
				{
					Element sub_element = (Element)sub_ec.getChild(k);
					if (sub_element.getTagName().getName().equalsIgnoreCase("reportElement"))
					{
						readXMLReportElement(sub_element,re);
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("parametersMapExpression"))
					{
						re.parametersMapExpression  = sub_element.getText().trim();
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("subreportParameter"))
					{
						String name = "";
						if (sub_element.getAttribute("name") != null)
						{
								name = ""+sub_element.getAttribute("name");
						} 
						// Find expression in childs......
						String expression = "";
						ElementCollection sub_ec2 = sub_element.getChildren();
						for (int p=1; p<=sub_ec2.getLength(); ++p)
						{
							Element sub_element2 = (Element)sub_element.getChild(p);
							if (sub_element2 != null && sub_element2.getTagName() != null &&
								sub_element2.getTagName().getName().equalsIgnoreCase("subreportParameterExpression"))
							{
								expression = sub_element2.getText().trim();
								break;
							}
						}
						re.subreportParameters.addElement(new JRParameter(name, expression));
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("connectionExpression"))
					{
						
						re.connectionExpression  = sub_element.getText().trim();
						re.useConnection = true;
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("dataSourceExpression"))
					{
						re.dataSourceExpression  = sub_element.getText().trim();
						re.useConnection = false;
					}
					else if (sub_element.getTagName().getName().equalsIgnoreCase("subreportExpression"))
					{
						re.subreportExpression  = sub_element.getText().trim();
						if (sub_element.getAttribute("class") != null)
						{
								re.subreportExpressionClass = ""+sub_element.getAttribute("class");
						}
					}
				}
				
				re.setPosition(re.position);
				re.trasform(new Point(0,0),TransformationType.TRANSFORMATION_RESIZE_SE); 
				elements.addElement(re);
			}
		}
	}
	
	public void readXMLReportElement(Element xmlReportElement, ReportElement re)
	{
		if (xmlReportElement.getAttribute("x") != null)
			re.position.x = Integer.parseInt(""+xmlReportElement.getAttribute("x"));
		if (xmlReportElement.getAttribute("y") != null)
			re.position.y = Integer.parseInt(""+xmlReportElement.getAttribute("y"));
		if (xmlReportElement.getAttribute("width") != null)
			re.width = Integer.parseInt(""+xmlReportElement.getAttribute("width"));
		if (xmlReportElement.getAttribute("height") != null)
			re.height = Integer.parseInt(""+xmlReportElement.getAttribute("height"));
		
		
		if (xmlReportElement.getAttribute("isPrintRepeatedValues") != null)
			re.isPrintRepeatedValues = (""+xmlReportElement.getAttribute("isPrintRepeatedValues")).equalsIgnoreCase("true");
			
		if (xmlReportElement.getAttribute("positionType") != null)
			re.positionType  = ""+xmlReportElement.getAttribute("positionType");
		else
			re.positionType = "FixRelativeToTop";
		
		if (xmlReportElement.getAttribute("isPrintRepeatedValues") != null)
			re.isPrintRepeatedValues  = (""+xmlReportElement.getAttribute("isPrintRepeatedValues")).equalsIgnoreCase("true");
		
		if (xmlReportElement.getAttribute("isRemoveLineWhenBlank") != null)
			re.isRemoveLineWhenBlank  = (""+xmlReportElement.getAttribute("isRemoveLineWhenBlank")).equalsIgnoreCase("true");
		
		if (xmlReportElement.getAttribute("isPrintInFirstWholeBand") != null)
			re.isPrintInFirstWholeBand  = (""+xmlReportElement.getAttribute("isPrintInFirstWholeBand")).equalsIgnoreCase("true");
		
		if (xmlReportElement.getAttribute("isPrintWhenDetailOverflows") != null)
			re.isPrintWhenDetailOverflows  = (""+xmlReportElement.getAttribute("isPrintWhenDetailOverflows")).equalsIgnoreCase("true");
		
		if (xmlReportElement.getAttribute("printWhenGroupChanges") != null)
			re.printWhenGroupChanges  = ""+xmlReportElement.getAttribute("printWhenGroupChanges");
		
		
		if (xmlReportElement.getAttribute("forecolor") != null)
		{
			String color = ""+xmlReportElement.getAttribute("forecolor");
			if (color.length() == 7)
			{
				re.fgcolor = new Color( Integer.parseInt(color.substring(1,3),16),
										Integer.parseInt(color.substring(3,5),16),
										Integer.parseInt(color.substring(5,7),16));
			}
		}
		if (xmlReportElement.getAttribute("backcolor") != null)
		{
			String color = ""+xmlReportElement.getAttribute("backcolor");
			if (color.length() == 7)
			{
				re.bgcolor = new Color( Integer.parseInt(color.substring(1,3),16),
				Integer.parseInt(color.substring(3,5),16),
				Integer.parseInt(color.substring(5,7),16));
			}
		}
		if (xmlReportElement.getAttribute("mode") != null)
		{
			re.mode = ""+xmlReportElement.getAttribute("mode");
		}
		
		String expression = "";
		ElementCollection sub_ec2 = xmlReportElement.getChildren();
		for (int p=1; p<=sub_ec2.getLength(); ++p)
		{
				Element sub_element2 = (Element)xmlReportElement.getChild(p);
				if (sub_element2 != null && sub_element2.getTagName() != null &&
				sub_element2.getTagName().getName().equalsIgnoreCase("printWhenExpression"))
				{
						expression = sub_element2.getText().trim();
					break;
				}
		}
		re.printWhenExpression = expression;
	}
	
	public void readXMLTextElement(Element xmlReportElement, TextReportElement re)
	{
		if (xmlReportElement.getAttribute("textAlignment") != null)
			re.align = ""+xmlReportElement.getAttribute("textAlignment");
		if (xmlReportElement.getAttribute("lineSpacing") != null)
			re.lineSpacing = ""+xmlReportElement.getAttribute("lineSpacing");
		// Check for Font sub_element...
		ElementCollection sub_ec = xmlReportElement.getChildren();
		for (int k=0; k<sub_ec.getLength(); ++k)
		{
			Element sub_element = (Element)sub_ec.getChild(k);
			if (sub_element.getTagName().getName().equalsIgnoreCase("font"))
			{
				String name = "Helvetica";
				double    size = 6;
				boolean bold = false;
				boolean italic = false;
				boolean underline = false;
				boolean strike = false;
				
				FontFile ff = new FontFile();
				
				if (sub_element.getAttribute("fontName") != null)
					re.fontName = ""+sub_element.getAttribute("fontName");

				if (sub_element.getAttribute("pdfFontName") != null)
				{
					re.pdfFontName = ""+sub_element.getAttribute("pdfFontName");
					if (!re.pdfFontName.equalsIgnoreCase("Helvetica") &&
						!re.pdfFontName.equalsIgnoreCase("Helvetica-Bold") &&
						!re.pdfFontName.equalsIgnoreCase("Helvetica-BoldOblique") &&
						!re.pdfFontName.equalsIgnoreCase("Helvetica-Oblique") &&
						!re.pdfFontName.equalsIgnoreCase("Courier") &&
						!re.pdfFontName.equalsIgnoreCase("Courier-Bold") &&
						!re.pdfFontName.equalsIgnoreCase("Courier-BoldOblique") &&
						!re.pdfFontName.equalsIgnoreCase("Courier-Oblique") &&
						!re.pdfFontName.equalsIgnoreCase("Symbol") &&
						!re.pdfFontName.equalsIgnoreCase("Times-Roman") &&
						!re.pdfFontName.equalsIgnoreCase("Times-Bold") &&
						!re.pdfFontName.equalsIgnoreCase("Times-BoldItalic") &&
						!re.pdfFontName.equalsIgnoreCase("Times-Italic") &&
						!re.pdfFontName.equalsIgnoreCase("ZapfDingbats") &&
						!re.pdfFontName.equalsIgnoreCase("STSong-Light") &&
						!re.pdfFontName.equalsIgnoreCase("MHei-Medium") &&
						!re.pdfFontName.equalsIgnoreCase("MSung-Light") &&
						!re.pdfFontName.equalsIgnoreCase("HeiseiKakuGo-W5") &&
						!re.pdfFontName.equalsIgnoreCase("HeiseiMin-W3") &&
						!re.pdfFontName.equalsIgnoreCase("HYGoThic-Medium") &&
						!re.pdfFontName.equalsIgnoreCase("HYSMyeongJo-Medium"))
					{
							re.fontName  = re.pdfFontName;
							re.pdfFontName = "External TTF font";
					}
				}
				
				
				if (sub_element.getAttribute("size") != null)
					re.size = Integer.valueOf(""+sub_element.getAttribute("size")).intValue();
				if (sub_element.getAttribute("isBold") != null)
					re.bold = (new String(""+sub_element.getAttribute("isBold"))).equalsIgnoreCase("true");
				if (sub_element.getAttribute("isItalic") != null)
					re.italic = (new String(""+sub_element.getAttribute("isItalic"))).equalsIgnoreCase("true");
				if (sub_element.getAttribute("isUnderline") != null)
					re.underline = (new String(""+sub_element.getAttribute("isUnderline"))).equalsIgnoreCase("true");
				if (sub_element.getAttribute("isStrikeThrough") != null)
					re.stroke = (new String(""+sub_element.getAttribute("isStrikeThrough"))).equalsIgnoreCase("true");
				
				if (sub_element.getAttribute("isPdfEmbedded") != null)
					re.isPdfEmbedded = (new String(""+sub_element.getAttribute("isPdfEmbedded"))).equalsIgnoreCase("true");
				
				if (sub_element.getAttribute("pdfEncoding") != null)
					re.pdfEncoding = ""+sub_element.getAttribute("pdfEncoding");
				
				if (sub_element.getAttribute("reportFont") != null)
					re.reportFont = ""+sub_element.getAttribute("reportFont");
		
				//Font f = new Font(name,(float)size*(float)0.85, FontSize.POINTS, ((bold)? FontWeight.BOLD : FontWeight.NORMAL) ,italic,underline,strike); 
				re.font = null;
				//if (f!=null)
				//	re.font = f;
			}
		}
	}
	
	
	public int getDesignHeight()
	{
		int y=0;
		y  += topMargin;
		y  += bottomMargin;
		
		Enumeration enum = bands.elements();
		while (enum.hasMoreElements())
		{
			y += ((Band)enum.nextElement()).height; 
		}
		
		return y;
	}
	
	public int getBandYLocation(Band b)
	{
		int y=0;
		y  += topMargin;
		
		Enumeration enum = bands.elements();
		while (enum.hasMoreElements())
		{
			
			Band band = (Band)enum.nextElement(); 
			if (band != b) y += band.height;
			else return y;
		}
		
		return y;
	}
	
	
	public void saveXMLFile()
	{
		try {
			
			//this.setCursor(Cursor.WAIT );
			java.io.PrintWriter pw = new java.io.PrintWriter( new java.io.FileOutputStream( filename ));
			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.reportName  +"\"");
			pw.println("\t\t columnCount=\""+ columnCount  +"\"");
			pw.println("\t\t printOrder=\""+ printOrder +"\"");
			pw.println("\t\t orientation=\""+ orientation +"\"");
			pw.println("\t\t pageWidth=\""+ this.pagesize.x +"\"");
			pw.println("\t\t pageHeight=\""+ this.pagesize.y +"\"");
			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 (scriptletClass != null && scriptletClass.length()>0)
				pw.println("\t\t scriptletClass=\""+ scriptletClass +"\"");
			pw.println("\t\t isTitleNewPage=\""+ this.isTitleNewPage  +"\"");
			pw.println("\t\t isSummaryNewPage=\""+ this.isSummaryNewPage +"\">");

			// Fonts...
			Enumeration enum = fonts.elements();
			while (enum.hasMoreElements())
			{
				IFont font = (IFont)enum.nextElement();
				pw.print("\t<reportFont name=\""+ font.name + "\" ");
				pw.print("isDefault=\""+ font.isDefault + "\" ");
				pw.print("fontName=\""+ font.fontName + "\" ");
				pw.print("size=\""+ font.size + "\" ");
				pw.print("isBold=\""+ font.isBold + "\" ");
				pw.print("isItalic=\""+ font.isItalic + "\" ");
				pw.print("isUnderline=\""+ font.isUnderline + "\" ");
				pw.print("isStrikeThrough=\""+ font.isStrikeThrough + "\" ");
				pw.print("pdfFontName=\""+ font.pdfFontName + "\" ");
				pw.print("pdfEncoding=\""+ font.pdfEncoding + "\" ");
				pw.println("isPdfEmbedded=\""+ font.isPdfEmbedded + "\"/>");			
			}
			// Parameters
			enum = parameters.elements();
			while (enum.hasMoreElements())
			{
				JRParameter p = (JRParameter)enum.nextElement();
				pw.print("\t<parameter name=\""+ p.name +"\" ");
				if (p.classType == null ) p.classType = "java.lang.String";
				pw.print("isForPrompting=\""+ p.isForPrompting +"\" ");
				pw.print("class=\""+ p.classType +"\"");
				
				if (p.defaultValueExpression.trim().length()> 0 ||
					p.description.trim().length()>0)
				{
					pw.println(">");
					if (p.defaultValueExpression.trim().length()> 0)
						pw.println("\t\t<defaultValueExpression><![CDATA["+ p.defaultValueExpression +"]]></defaultValueExpression>");
					if (p.description.trim().length()> 0)
						pw.println("\t\t<parameterDescription><![CDATA["+ p.description +"]]></parameterDescription>");
					pw.println("\t</parameter>");
				}
				else
					pw.println("/>");
				
			}
			// QueryString
			if (query != null && query.trim().length() >0 ) 
			{			
				pw.println("\t<queryString><![CDATA[");
				pw.println(query); 
				pw.println("\t]]></queryString>");
			}
			// fileds...
			enum = fields.elements();
			while (enum.hasMoreElements())
			{
				JRField f = (JRField)enum.nextElement();
				pw.print("\t<field name=\""+ f.name +"\" ");
				if (f.classType == null ) f.classType = "java.lang.String";
				pw.print("class=\""+ f.classType +"\"");
				
				if (f.description.trim().length()>0)
				{
					pw.println(">");
					if (f.description.trim().length()> 0)
						pw.println("\t\t<fieldDescription><![CDATA["+ f.description +"]]></fieldDescription>");
					pw.println("\t</field>");
				}
				else
					pw.println("/>");
			}
			// variables...
			enum = variables.elements();
			while (enum.hasMoreElements())
			{
				JRVariable f = (JRVariable)enum.nextElement();
				if (f.builtin) continue;
				pw.print("\t<variable name=\""+ f.name +"\" ");
				if (f.classType == null ) f.classType = "java.lang.String";
				pw.print("class=\""+ f.classType +"\" ");
				pw.print("resetType=\""+ f.resetType +"\" ");
				if (f.resetGroup.length() >0 ) pw.print("resetGroup=\""+ f.resetGroup +"\" ");
				pw.println("calculation=\""+ f.calculation  +"\">");
				if (f.expression.length()>0)
				{
					pw.print("\t\t<variableExpression>");
					pw.print(f.expression);
					pw.println("</variableExpression>");
				}
				if (f.initialValueExpression.length()>0)
				{
					pw.print("\t\t<initialValueExpression>");
					pw.print(f.initialValueExpression);
					pw.println("\t\t</initialValueExpression>");
				}
				pw.println("\t</variable>");
			}
			
			
			// groups...
			writeXMLGroups(pw);
			
			writeXMLSection("title", pw);
			writeXMLSection("pageHeader", pw);
			writeXMLSection("columnHeader", pw);
			writeXMLSection("detail", pw);
			writeXMLSection("columnFooter", pw);
			writeXMLSection("pageFooter", pw);
			writeXMLSection("summary", pw);
			
			pw.println("</jasperReport>");
			pw.close();
			
			if (filename != 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));
			MessageBox.show(ex.getMessage()+" "+s);
		}
		//this.setCursor(Cursor.DEFAULT);
	}
	
	void writeXMLSection(String section,java.io.PrintWriter pw)
	{
		// Find band...
		Band band = null;
		Enumeration enum = bands.elements();
		while (enum.hasMoreElements())
		{
			band = (Band)enum.nextElement();
			if (band.name.equalsIgnoreCase(section))
				break;
		}
		if (band == null) 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.name  +"\"");
			pw.print(" isStartNewColumn=\""+grp.isStartNewColumn +"\"");
			pw.print(" isStartNewPage=\""+grp.isStartNewPage +"\"");
			pw.print(" isResetPageNumber=\""+grp.isResetPageNumber +"\"");
			pw.print(" isReprintHeaderOnEachPage=\""+grp.isReprintHeaderOnEachPage +"\"");
			pw.print(" minHeightToStartNewPage=\""+grp.minHeightToStartNewPage +"\"");
			pw.println(" >");
			pw.println("\t\t\t<groupExpression>");
			pw.println("\t\t\t"+grp.groupExpression);
			pw.println("\t\t\t</groupExpression>");
			pw.println("\t\t\t<groupHeader>");
			writeXMLBand(grp.groupHeader, pw);
			pw.println("\t\t\t</groupHeader>");
			pw.println("\t\t\t<groupFooter>");
			writeXMLBand(grp.groupFooter, pw);
			pw.println("\t\t\t</groupFooter>");
			pw.println("\t\t</group>");
		}
	}
		
	void writeXMLBand(Band band,java.io.PrintWriter pw)
	{
		pw.println("\t\t\t<band height=\""+ band.height + "\">");
		Enumeration enum = elements.elements();
		while (enum.hasMoreElements())
		{
			ReportElement re = (ReportElement)enum.nextElement();
			if (re.band == band)
			{
				writeXMLReportElement(re,pw);
			}
		}
		pw.println("\t\t\t</band>");
	}
	
	void writeXMLReportElement(ReportElement re, java.io.PrintWriter pw)
	{
		if (re instanceof StaticTextReportElement)
		{
			pw.println("\t\t\t\t<staticText>");
			writeXMLReportElementElement(re, pw);
			writeXMLTextElementElement((TextReportElement)re, pw);
			pw.println("\t\t\t\t<text><![CDATA["+((StaticTextReportElement)re).text+"]]></text>");
			pw.println("\t\t\t\t</staticText>");
		}
		else if (re instanceof TextFieldReportElement)
		{
			pw.print("\t\t\t\t<textField");
			pw.print(" isStretchWithOverflow=\""+ ((TextFieldReportElement)re).isStretchWithOverflow +"\"");
			pw.print(" pattern=\"" + ((TextFieldReportElement)re).pattern + "\"");
			pw.print(" isBlankWhenNull=\"" + ((TextFieldReportElement)re).isBlankWhenNull +"\"");
			pw.print(" evaluationTime=\""+ ((TextFieldReportElement)re).evaluationTime +"\"");
			if (((TextFieldReportElement)re).evaluationTime.equals("Group"))
			{
				pw.print(" evaluationGroup=\"" + ((TextFieldReportElement)re).evaluationGroup +"\" ");
			}
			pw.print(" hyperlinkType=\"" + ((TextFieldReportElement)re).hyperlinkType +"\" ");
			pw.print(">");
			
			writeXMLReportElementElement(re, pw);
			writeXMLTextElementElement((TextReportElement)re, pw);
			pw.print("\t\t\t\t<textFieldExpression ");
			if (((TextFieldReportElement)re).fieldClass.length() > 0) pw.print("  class=\""+ ((TextFieldReportElement)re).fieldClass+"\"");
			pw.println(">"+((TextFieldReportElement)re).text+"</textFieldExpression>");
			if (((TextFieldReportElement)re).anchorNameExpression != null && ((TextFieldReportElement)re).anchorNameExpression.length() > 0)
			{
				pw.println("\t\t\t\t\t<anchorNameExpression><![CDATA["+((TextFieldReportElement)re).anchorNameExpression+"]]></anchorNameExpression>");
			}
			if (((TextFieldReportElement)re).hyperlinkType != null && ((TextFieldReportElement)re).hyperlinkType.length() > 0)
			{
				if ( ((TextFieldReportElement)re).hyperlinkType.equals("Reference") ||
					 ((TextFieldReportElement)re).hyperlinkType.equals("RemoteAnchor") ||
					 ((TextFieldReportElement)re).hyperlinkType.equals("RemotePage"))
					pw.println("\t\t\t\t\t<hyperlinkReferenceExpression><![CDATA["+((TextFieldReportElement)re).hyperlinkReferenceExpression +"]]></hyperlinkReferenceExpression>");
				
				if ( ((TextFieldReportElement)re).hyperlinkType.equals("LocalAnchor") || 
					 ((TextFieldReportElement)re).hyperlinkType.equals("RemoteAnchor"))
					pw.println("\t\t\t\t\t<hyperlinkAnchorExpression><![CDATA["+((TextFieldReportElement)re).hyperlinkAnchorExpression +"]]></hyperlinkAnchorExpression>");
				
				if ( ((TextFieldReportElement)re).hyperlinkType.equals("LocalPage") || 
					 ((TextFieldReportElement)re).hyperlinkType.equals("RemotePage"))
					pw.println("\t\t\t\t\t<hyperlinkPageExpression><![CDATA["+((TextFieldReportElement)re).hyperlinkPageExpression +"]]></hyperlinkPageExpression>");
			}
			
			pw.println("\t\t\t\t</textField>");
		}	
		else if (re instanceof ImageReportElement)
		{
			pw.print("\t\t\t\t<image ");
			pw.print(" scaleImage=\""+ ((ImageReportElement)re).scaleImage  +"\"");
			pw.print(" isUsingCache=\""+ ((ImageReportElement)re).isUsingCache +"\"");
			pw.print(" evaluationTime=\""+ ((ImageReportElement)re).evaluationTime + "\"");
			
			if (((ImageReportElement)re).evaluationTime.equals("Group"))
			{
				pw.print(" evaluationGroup=\"" + ((ImageReportElement)re).evaluationGroup +"\" ");
			}
			pw.print(" hyperlinkType=\"" + ((ImageReportElement)re).hyperlinkType +"\">");
			
			writeXMLReportElementElement(re, pw);
			writeXMLGraphicElement((GraphicReportElement)re,pw);
			pw.print("\t\t\t\t\t<imageExpression class=\""+ ((ImageReportElement)re).imageClass + "\">");
			if (((ImageReportElement)re).imageClass.equals("java.lang.String"))
			{
				pw.print("\"");
			}
			pw.print(((ImageReportElement)re).imageExpression);
			if (((ImageReportElement)re).imageClass.equals("java.lang.String"))
			{
				pw.print("\"");
			}
			pw.println("</imageExpression>");
			if (((ImageReportElement)re).anchorNameExpression != null && ((ImageReportElement)re).anchorNameExpression.length() > 0)
			{
				pw.println("\t\t\t\t\t<anchorNameExpression><![CDATA["+((ImageReportElement)re).anchorNameExpression+"]]></anchorNameExpression>");
			}
			if (((ImageReportElement)re).hyperlinkType != null && ((ImageReportElement)re).hyperlinkType.length() > 0)
			{
				if ( ((ImageReportElement)re).hyperlinkType.equals("Reference") ||
					 ((ImageReportElement)re).hyperlinkType.equals("RemoteAnchor") ||
					 ((ImageReportElement)re).hyperlinkType.equals("RemotePage"))
					pw.println("\t\t\t\t\t<hyperlinkReferenceExpression><![CDATA["+((ImageReportElement)re).hyperlinkReferenceExpression +"]]></hyperlinkReferenceExpression>");
				
				if ( ((ImageReportElement)re).hyperlinkType.equals("LocalAnchor") || 
					 ((ImageReportElement)re).hyperlinkType.equals("RemoteAnchor"))
					pw.println("\t\t\t\t\t<hyperlinkAnchorExpression><![CDATA["+((ImageReportElement)re).hyperlinkAnchorExpression +"]]></hyperlinkAnchorExpression>");
				
				if ( ((ImageReportElement)re).hyperlinkType.equals("LocalPage") || 
					 ((ImageReportElement)re).hyperlinkType.equals("RemotePage"))
					pw.println("\t\t\t\t\t<hyperlinkPageExpression><![CDATA["+((ImageReportElement)re).hyperlinkPageExpression +"]]></hyperlinkPageExpression>");
			}
			pw.println("\t\t\t\t</image>");
		}
		else if (re instanceof LineReportElement)
		{
			pw.println("\t\t\t\t<line direction=\""+ ((LineReportElement)re).direction +"\">");
			writeXMLReportElementElement(re, pw);
			writeXMLGraphicElement((GraphicReportElement)re,pw);
			
			pw.println("\t\t\t\t</line>");
		}
		else if (re instanceof RectangleReportElement)
		{
			pw.println("\t\t\t\t<rectangle>");
			writeXMLReportElementElement(re, pw);
			writeXMLGraphicElement((GraphicReportElement)re,pw);
			pw.println("\t\t\t\t</rectangle>");
		}
		else if (re instanceof SubReportElement)
		{
			SubReportElement sre = (SubReportElement)re;
			pw.println("\t\t\t\t<subreport  isUsingCache=\""+ ((SubReportElement)re).isUsingCache  +"\">");
			writeXMLReportElementElement(re, pw);
			if (sre.parametersMapExpression != null &&
				sre.parametersMapExpression.trim().length() > 0)
			{
				pw.println("\t\t\t\t\t<parametersMapExpression  isUsingCache=\""+ ((SubReportElement)re).isUsingCache  +"\">");
				pw.println("\t\t\t\t\t\t" + sre.parametersMapExpression );
				pw.println("\t\t\t\t\t</parametersMapExpression>");
			}
			Enumeration enum = sre.subreportParameters.elements();
			while (enum.hasMoreElements())
			{
				JRParameter je = (JRParameter)enum.nextElement();
				pw.println("\t\t\t\t\t<subreportParameter  name=\""+ je.name +"\">");
				pw.println("\t\t\t\t\t\t<subreportParameterExpression>");
				pw.println("\t\t\t\t\t\t\t" + je.classType  );
				pw.println("\t\t\t\t\t\t</subreportParameterExpression>");
				pw.println("\t\t\t\t\t</subreportParameter>");
			}
			if (sre.useConnection && sre.connectionExpression.trim().length() > 0 )
			{
				pw.println("\t\t\t\t\t<connectionExpression>");
				pw.println("\t\t\t\t\t\t" + sre.connectionExpression );
				pw.println("\t\t\t\t\t</connectionExpression>");
			}
			else if (!sre.useConnection  && sre.dataSourceExpression.length() > 0)
			{
				pw.println("\t\t\t\t\t<dataSourceExpression>");
				pw.println("\t\t\t\t\t\t" + sre.dataSourceExpression );
				pw.println("\t\t\t\t\t</dataSourceExpression>");
			}
			
			if (sre.subreportExpression  != null &&
				sre.subreportExpression.trim().length() > 0)
			{
				pw.println("\t\t\t\t\t<subreportExpression  class=\""+ sre.subreportExpressionClass  +"\">");
				pw.println("\t\t\t\t\t\t" + sre.subreportExpression );
				pw.println("\t\t\t\t\t</subreportExpression>");
			}
			
			pw.println("\t\t\t\t</subreport>");
		}
	}
	
	void writeXMLReportElementElement(ReportElement re,java.io.PrintWriter pw)
	{
		pw.println("\t\t\t\t\t<reportElement");
		pw.println("\t\t\t\t\t\tmode=\""+ re.mode + "\"");
		pw.println("\t\t\t\t\t\tx=\""+ (re.position.x - leftMargin -10)+ "\"");
		pw.println("\t\t\t\t\t\ty=\""+ (re.position.y - 10 - getBandYLocation(re.band)) +"\"");
		pw.println("\t\t\t\t\t\twidth=\""+ re.width + "\"");
		pw.println("\t\t\t\t\t\theight=\""+ re.height + "\"");
		pw.println("\t\t\t\t\t\tforecolor=\""+ writeEncodedColor(re.fgcolor) +"\"");
		pw.println("\t\t\t\t\t\tbackcolor=\""+ writeEncodedColor(re.bgcolor) +"\"");
		
		
		pw.println("\t\t\t\t\t\tpositionType=\""+ re.positionType +"\"");
		pw.println("\t\t\t\t\t\tisPrintRepeatedValues=\""+ re.isPrintRepeatedValues +"\"");
		pw.println("\t\t\t\t\t\tisRemoveLineWhenBlank=\""+ re.isRemoveLineWhenBlank +"\"");
		pw.println("\t\t\t\t\t\tisPrintInFirstWholeBand=\""+ re.isPrintInFirstWholeBand +"\"");
		
		if (re.printWhenGroupChanges!= null &&  re.printWhenGroupChanges.trim().length()>0)
		pw.println("\t\t\t\t\t\tprintWhenGroupChanges=\""+ re.printWhenGroupChanges +"\"");

		pw.print("\t\t\t\t\t\tisPrintWhenDetailOverflows=\""+ re.isPrintWhenDetailOverflows +"\"");
		
		if (re.printWhenExpression.length()>0)
		{
			pw.println(">");
			pw.println("\t\t\t\t\t\t\t<printWhenExpression>");
			pw.println("\t\t\t\t\t\t\t"+re.printWhenExpression);
			pw.println("\t\t\t\t\t\t\t</printWhenExpression>");
			pw.println("\t\t\t\t\t\t</reportElement>");
		}	
		else
			pw.println("/>");
		
		
		
	
	
	
	
	}
	
	public String writeEncodedColor(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;
	}
	
	void writeXMLGraphicElement(GraphicReportElement re,java.io.PrintWriter pw)
	{
		pw.print("\t\t\t\t\t<graphicElement");
		pw.print(" stretchType=\"" + re.stretchType + "\"");
		pw.print(" pen=\""+ re.graphicElementPen + "\"");
		pw.println(" fill=\"" + re.fill + "\" />");
	}
	
	void writeXMLTextElementElement(TextReportElement re,java.io.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.align +"\"");
		pw.println(" lineSpacing=\""+ re.lineSpacing +"\">");
		pw.print("\t\t\t\t\t\t<font");
		pw.print(" fontName=\"" + re.fontName +"\"");
	
		if (re.reportFont != null && re.reportFont.length()>0)
			pw.print(" reportFont=\""+ re.reportFont +"\"");	
		
		if (re.pdfFontName.equals("External TTF font"))
			pw.print(" pdfFontName=\"" + re.fontName +"\"");
		else
			pw.print(" pdfFontName=\"" + re.pdfFontName +"\"");
		//pw.print(" pdfEncoding=\"Times-Roman\"");
	    pw.print(" size=\"" +  re.size  +"\"");
		pw.print(" isBold=\"" + ((re.bold) ? "true" : "false")+"\"");
		pw.print(" isItalic=\"" + ((re.italic) ? "true" : "false")+"\"");
		pw.print(" isUnderline=\"" + ((re.underline) ? "true" : "false")+"\"");
		pw.print(" isPdfEmbedded =\"" + ((re.isPdfEmbedded) ? "true" : "false")+"\"");
		if (re.pdfEncoding != null && re.pdfEncoding.length() > 0) 
		pw.print(" pdfEncoding =\"" + re.pdfEncoding +"\"");
		pw.println(" isStrikeThrough=\"" + ((re.stroke) ? "true" : "false")+"\" />");
		pw.println("\t\t\t\t\t</textElement>");
	}
	
	public void addGroup(Group grp)
	{
		if (!groups.contains(grp)) groups.addElement(grp);
		String bandsstr = "";
		for (int i=0; i< bands.size(); i++)
		{
			Band b = (Band)bands.elementAt(i);
			if (b.name.equals("detail"))
			{
				bands.insertElementAt(grp.groupHeader,i);
				bands.insertElementAt(grp.groupFooter,i+2);
				break;
			}
				
		}
	}
	
	public Group getGroupByName(String name)
	{
		for (int i=0; i< groups.size(); i++)
		{
			Group grp = (Group)groups.elementAt(i);
			if (grp.name.equals(name))
				return grp;
		}
		return null;
	}
	
	public Band getBandByName(String name)
	{
		for (int i=0; i< bands.size(); i++)
		{
			Band band = (Band)groups.elementAt(i);
			if (band.name.equals(name))
				return band;
		}
		return null;
	}
	
	
	
	public String nextToken(String s)
	{
		if (pos >= s.length()) return null;
		
		char c = s.charAt(pos);
		
		if (c=='(') parentesi_opened++;
		if (c==')')
		{
			pos++;
			if (parentesi_opened>0)
			{
				parentesi_opened--;
				return ")";
			}
			else
			{
				return "\\cf2\\ul\\b )\\cf1\\ulnone\\b0 ";
			}
		}
		if (separators.indexOf(c) >= 0) 
		{
			pos++;
			return ""+c;
		}
		if (c == '{')
		{
			pos++;
			return "\\{";
		}
		if (c == '}')
		{
			pos++;
			return "\\}";
		}
		if (c == '\\')
		{
			pos++;
			return "\\\\";
		}
		if (c=='\"') // begin a string...
		{
			if (s.length() <= pos+1) { pos++; return "\\cf6 \"\\cf1 "; }
			if (s.substring(pos+1).indexOf('\"') >=0)
			{
				String str = s.substring(pos,pos+2+s.substring(pos+1).indexOf('\"'));
				pos += str.length();
				str = string_replace("\\{","{",str);
				str = string_replace("\\}","}",str);
				str = string_replace("\\\\","\\",str);
				return "\\cf6 "+ str +"\\cf1 ";
			}
			else
			{
				String str = s.substring(pos);
				pos = s.length(); 
				str = string_replace("\\{","{",str);
				str = string_replace("\\\\","\\",str);
				str = string_replace("\\}","}",str);
				return "\\cf6 "+ str + "\\cf1 "; 
			}
		}
		if (c=='\n') 
		{
			pos++;
			return "\\par\n\r";
		}
		if (c=='\t') 
		{
			pos++;
			return "\\tab";
		}
		if (c=='$' && s.substring(pos).length() >=5)
		{
			// IS A PARAMETER?
			if (s.substring(pos).startsWith("$P{"))
			{
				Enumeration enum = this.parameters.elements();
				while (enum.hasMoreElements())
				{
					String field = ((JRParameter)enum.nextElement()).name;
					if ((s.substring(pos).length() >= field.length()+4)
						&& s.substring(pos,pos+field.length()+4).equals("$P{"+field+"}"))
					{
						pos += field.length()+4;
						return "\\cf2\\b $P\\{"+field+"\\}\\cf1\\b0 ";
					}
				}
			}
			else if (s.substring(pos).startsWith("$F{"))
			{
				Enumeration enum = this.fields.elements();
				while (enum.hasMoreElements())
				{
					String field = ((JRField)enum.nextElement()).name;
					if ((s.substring(pos).length() >= field.length()+4)
						&& s.substring(pos,pos+field.length()+4).equals("$F{"+field+"}"))
					{
						pos += field.length()+4;
						return "\\cf4\\b $F\\{"+field+"\\}\\cf1\\b0 ";
					}
				}
			}
			else if (s.substring(pos).startsWith("$V{"))
			{
				Enumeration enum = this.variables.elements();
				while (enum.hasMoreElements())
				{
					String field = ((JRVariable)enum.nextElement()).name;
					if ((s.substring(pos).length() >= field.length()+4)
						&& s.substring(pos,pos+field.length()+4).equals("$V{"+field+"}"))
					{
						pos += field.length()+4;
						return "\\cf5\\b $V\\{"+field+"\\}\\cf1\\b0 ";
					}
				}
			}
		}
		if (s.substring(pos).length() >=2)
		{
			if (s.substring(pos).startsWith("if") && (s.substring(pos).length() == 2 ||
				separators.indexOf( s.charAt(pos+2) ) >= 0))
			{
				pos += 2;
				return "\\cf3\\b if\\cf1\\b0 ";
			}
		}
		if (s.substring(pos).length() >=3)
		{
			if (s.substring(pos).startsWith("new") && (s.substring(pos).length() == 3 ||
				separators.indexOf( s.charAt(pos+3) ) >= 0))
			{
				pos += 3;
				return "\\cf3\\b new\\cf1\\b0 ";
			}
		}
		if (c>='0' && c <= '9')
		{
			// Syntax for number...
			int x= 1;
			String separators2 = separators+"\"\\\'{},?:";
			while (s.length()>pos+x && separators2.indexOf( s.charAt(pos+x) )<0) x++;
			String str = s.substring(pos,pos+x);
			str = string_replace("\\{","{",str);
			str = string_replace("\\}","}",str);
			pos = pos+x;
			return "\\cf8 "+ str +"\\cf1 ";
			
		}
		
		
		pos++;
		return s.substring(pos-1,pos);
	}
	
	public void initTokenizer(){ 
		pos=0;
		parentesi_opened=0;
	}
	
	public String formatExpression(String s)
	{
		
		if ( ((MainForm)this.reportForm.getMDIParent()).ireportProperties.getProperty("SYNTAX_HIGHLIGHTING")!=null &&
			 ((MainForm)this.reportForm.getMDIParent()).ireportProperties.getProperty("SYNTAX_HIGHLIGHTING").equalsIgnoreCase("false"))
		{
			((MainForm)this.reportForm.getMDIParent()).richEdit1.setText(s);
			return ((MainForm)this.reportForm.getMDIParent()).richEdit1.getRTF();
		}		
		String text = "{\\rtf1\\ansi\\ansicpg1252\\deff0\\deflang1040{\\fonttbl{\\f0\\fmodern\\fprq1\\fcharset0 Courier New;}{\\f1\\fswiss\\fcharset0 Arial;}}"
					  +"{\\colortbl ;\\red0\\green0\\blue0;\\red255\\green0\\blue0;\\red0\\green0\\blue255;\\red128\\green0\\blue128;\\red0\\green128\\blue0;\\red0\\green128\\blue128;\\red128\\green128\\blue128;\\red255\\green114\\blue0;}\n"
					  +"\\viewkind4\\uc1\\pard\\cf1\\f0\\fs18 ";

		initTokenizer();
		String token = nextToken(s);
		while (token != null)
		{
			text+=token;
			token = nextToken(s);
		}
		
		
		text +="\\cf0\\f1\\par\n}";
		return text;
	}
	
	public static String string_replace(String s1, String s2, String s3)
	{
	   String string="";
	   string = "";

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

	   }

	   string += s3.substring(pos_i);

	   return string;
	}
}
