/*
 * RectangleReportElement.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 28 febbraio 2003, 19.20
 */
package it.businesslogic.ireport;
import it.businesslogic.ireport.gui.*;
import it.businesslogic.ireport.util.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.awt.font.*;
import java.util.*;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;

public abstract class TextReportElement extends ReportElement 
{

    private String text="";    
	
    private String reportFont="";
    
    private String fontName="";
    
    private String PDFFontName="";
    
    private int fontSize=10;
    
    private String TTFFont="";
    
    private boolean bold=false;
    
    private boolean underline=false;
    
    private boolean italic=false;
    
    private boolean strikeTrought=false;
    
    private String lineSpacing="";
    
    private String align="";
    
    private String verticalAlign="";
    
    private boolean pdfEmbedded=false;
    
    private String pdfEncoding="";
    
    private java.awt.Font font=null;
    
	public TextReportElement(int x, int y, int width, int height)
	{
		super(x,y,width,height);
                //setGraphicElementPen("Thin");
		this.bgcolor = Color.WHITE;
		this.fgcolor = Color.BLACK;
                this.font = new java.awt.Font("Arial",java.awt.Font.PLAIN, 12);
                this.text = "Staic text\nsecond line";
                this.verticalAlign = "Top";
                this.align = "Left";
                this.fontSize =12;
                this.fontName = "SansSerif";
                this.PDFFontName = "Helvetica";
                this.pdfEncoding = "CP1252";
                this.pdfEmbedded = false;
                this.lineSpacing = "Single";
	}
	
		
	public void drawObject(Graphics2D g,double zoom_factor, int x_shift_origin, int y_shift_origin)
	{
                position.x -= 10;
		position.y -= 10;
		x_shift_origin -= 10;
		y_shift_origin -= 10;
		
		this.zoom_factor = zoom_factor;
                
                g.setColor( bgcolor );
                if (!getTransparent().equalsIgnoreCase("Transparent"))
                    g.fillRect( getZoomedDim(position.x)-x_shift_origin,
				getZoomedDim(position.y)-y_shift_origin,
				getZoomedDim(width),
				getZoomedDim(height));
                g.setColor( this.fgcolor );
                
                // Set font to default font....
                //Font oldFont = g.getFont();
                
                if (font == null)
                {
                    int style = 0;
                    if (isBold()) style |= Font.BOLD;
                    if (isItalic()) style |= Font.ITALIC;
                    if (style == 0) style = Font.PLAIN;
                    font = new Font( this.getFontName(), style , getZoomedDim( this.getFontSize() )); 
                }
     
              // We must center the text..

                Rectangle orgClipBounds = g.getClipBounds();
                g.setClip(getZoomedDim(position.x)-x_shift_origin,
				getZoomedDim(position.y)-y_shift_origin,
				getZoomedDim(width),
				getZoomedDim(height));
               
                if (this.getText() != null && this.getText().length() > 0)
                {
                    int zoomedFieldHeight = getZoomedDim(height);
                    String allText = Misc.treatNewLineChars(this.getText());
                    float formatWidth = (float)getZoomedDim(width);
                    float verticalOffset = 0f;
                    
                    
                    FontRenderContext fontRenderContext = g.getFontRenderContext();
                    java.util.Map fontAttributes = font.getAttributes();
                    fontAttributes.put(TextAttribute.SIZE, new Float(getZoomedDim( this.getFontSize() )) );
		    fontAttributes.put(TextAttribute.FAMILY, this.getFontName() );
                    if (this.isBold())
		    {
			fontAttributes.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD);
		    }
		    if (this.isItalic())
		    {
		    	fontAttributes.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE);
		    }
		    if (this.isUnderline())
		    {
		    	fontAttributes.put(TextAttribute.UNDERLINE, TextAttribute.UNDERLINE_ON);
		    }
		    if (this.isStrikeTrought())
                    {
			fontAttributes.put(TextAttribute.STRIKETHROUGH, TextAttribute.STRIKETHROUGH_ON);
		    }                    
                    
                    float lineSpacing = 1f;
                    if (this.getLineSpacing().equals("Single")) lineSpacing = 1f;
                    else if (this.getLineSpacing().equals("1_1_2")) lineSpacing = 1.5f;
                    else if (this.getLineSpacing().equals("Double")) lineSpacing = 2f;
                                        
                    AttributedString atext;
                    AttributedCharacterIterator paragraph;
                    int paragraphStart;
                    int paragraphEnd;
                    LineBreakMeasurer lineMeasurer;
                    TextLayout layout = null;
                
                    
                    String paragr_text = "";
                    boolean isMaxHeightReached = false;
		
                    StringTokenizer tkzer = new StringTokenizer(allText, "\n");
                
                    float drawPosY = 0;
                    float drawPosX = 0;
                
                    while(tkzer.hasMoreTokens() && !isMaxHeightReached) 
                    {
			paragr_text = tkzer.nextToken();
			
			atext = new AttributedString(paragr_text, fontAttributes);
			paragraph = atext.getIterator();
			paragraphStart = paragraph.getBeginIndex();
			paragraphEnd = paragraph.getEndIndex();
			lineMeasurer = new LineBreakMeasurer(paragraph, fontRenderContext);
			lineMeasurer.setPosition(paragraphStart);
	
			layout = null;
			while (lineMeasurer.getPosition() < paragraphEnd && !isMaxHeightReached)
			{
				layout = lineMeasurer.nextLayout(formatWidth);
	
				drawPosY += layout.getLeading() + lineSpacing * layout.getAscent();
	
				if (drawPosY + layout.getDescent() <= zoomedFieldHeight+1)
				{
				    drawPosY += layout.getDescent();
				}
				else
				{
				    drawPosY -= layout.getLeading() + lineSpacing * layout.getAscent();
                        	    isMaxHeightReached = false;
				}
			}
                    }
                    
                    float textHeight = drawPosY;
                    if (this.getVerticalAlign().equals("Top")) verticalOffset = 0f;
                    else if (this.getVerticalAlign().equals("Middle")) verticalOffset = ((float)zoomedFieldHeight- textHeight) / 2f;
                    else if (this.getVerticalAlign().equals("Bottom")) verticalOffset = (float)zoomedFieldHeight - (float)textHeight;
                    
                    
                    drawPosY = 0;
                    drawPosX = 0;
	
                    paragr_text = "";
                    isMaxHeightReached = false;
		
                    tkzer = new StringTokenizer(allText, "\n");
		
                    while(tkzer.hasMoreTokens() && !isMaxHeightReached) 
                    {
			paragr_text = tkzer.nextToken();
			
			atext = new AttributedString(paragr_text, fontAttributes);
			paragraph = atext.getIterator();
			paragraphStart = paragraph.getBeginIndex();
			paragraphEnd = paragraph.getEndIndex();
			lineMeasurer = new LineBreakMeasurer(paragraph, fontRenderContext);
			lineMeasurer.setPosition(paragraphStart);
	
			layout = null;
			while (lineMeasurer.getPosition() < paragraphEnd && !isMaxHeightReached)
			{
				layout = lineMeasurer.nextLayout(formatWidth);
	
				drawPosY += layout.getLeading() + lineSpacing * layout.getAscent();
	
				if (drawPosY + layout.getDescent() <= zoomedFieldHeight+1)
				{
				    if (this.getAlign().equals("Justify"))
				    {
					 if (layout.isLeftToRight())
                                         {
					    drawPosX = 0;
					 }
					 else
					 {
					    drawPosX = formatWidth - layout.getAdvance();
					 }
					 if (lineMeasurer.getPosition() < paragraphEnd)
					 {
					    layout = layout.getJustifiedLayout(formatWidth);
                                         }
                                    }
                                    else if (this.getAlign().equals("Right"))
                                    {
				          if (layout.isLeftToRight())
					  {
					    drawPosX = formatWidth - layout.getAdvance();
					  }
					  else
					  {
					    drawPosX = formatWidth;
					  }
				    }
                                    else if (this.getAlign().equals("Center"))
                                    {
					drawPosX = (formatWidth - layout.getAdvance()) / 2;
				    }
                                    else //if (this.getAlign().equals("Left"))
                                    {
					if (layout.isLeftToRight())
					{
					    drawPosX = 0;
					}
					else
					{
					    drawPosX = formatWidth - layout.getAdvance();
					}
				    }
				    
                                    layout.draw(
						g,
						drawPosX + getZoomedDim(position.x)-x_shift_origin,
                                                drawPosY + getZoomedDim(position.y)-y_shift_origin 
                                                + verticalOffset
						);
				    drawPosY += layout.getDescent();
				}
				else
				{
				    drawPosY -= layout.getLeading() + lineSpacing * layout.getAscent();
                                    isMaxHeightReached = true;
				}
			}
		}
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    
                    /*
                    int txt_width = g.getFontMetrics().stringWidth( this.getText() )/2;
                    int txt_height = g.getFontMetrics().getHeight();

                    StringTokenizer st = new StringTokenizer(getText(),"\n");
                    while( st.hasMoreElements())
                    {
                     String line = st.nextToken();
                      float formatWidth = (float) this.getWidth();
                     g.drawString(line, 
                        (float)(getZoomedDim(position.x)-x_shift_origin),
                        getZoomedDim(position.y)-y_shift_origin +  verticalOffset); //, zoomed_width, getZoomedDim(band.getHeight()
                
                        verticalOffset += g.getFontMetrics().getHeight();
                    }
                    */
                //g.drawLine(0, getZoomedDim(y)+10-vertical_scroll -  txt_height - getZoomedDim(band.getHeight()/2),  700,getZoomedDim(y)+10-vertical_scroll -  txt_height - getZoomedDim(band.getHeight()/2)); 
		//g.drawLine(0, getZoomedDim(y)+10-vertical_scroll +  txt_height - getZoomedDim(band.getHeight()/2),  700,getZoomedDim(y)+10-vertical_scroll +  txt_height - getZoomedDim(band.getHeight()/2)); 
                
                }
                //g.setClip(null);
                g.setClip(orgClipBounds);
		position.x += 10;
		position.y += 10;
		x_shift_origin += 10;
		y_shift_origin += 10;
                
                drawBorder( g, zoom_factor,  x_shift_origin,y_shift_origin);
                //drawGraphicsElement(g,this.getGraphicElementPen(), zoom_factor,  x_shift_origin,y_shift_origin, 0);
	}		
        
        /** Getter for property align.
         * @return Value of property align.
         *
         */
        public java.lang.String getAlign() {
            return align;
        }
        
        /** Setter for property align.
         * @param align New value of property align.
         *
         */
        public void setAlign(java.lang.String align) {
            this.align = align;
        }
        
        /** Getter for property bold.
         * @return Value of property bold.
         *
         */
        public boolean isBold() {
            return bold;
        }
        
        /** Setter for property bold.
         * @param bold New value of property bold.
         *
         */
        public void setBold(boolean bold) {
            this.bold = bold;
        }
        
        /** Getter for property font.
         * @return Value of property font.
         *
         */
        public java.awt.Font getFont() {
            return font;
        }
        
        /** Setter for property font.
         * @param font New value of property font.
         *
         */
        public void setFont(java.awt.Font font) {
            this.font = font;
        }
        
        /** Getter for property fontName.
         * @return Value of property fontName.
         *
         */
        public java.lang.String getFontName() {
            return fontName;
        }
        
        /** Setter for property fontName.
         * @param fontName New value of property fontName.
         *
         */
        public void setFontName(java.lang.String fontName) {
            this.fontName = fontName;
        }
        
        /** Getter for property fontSize.
         * @return Value of property fontSize.
         *
         */
        public int getFontSize() {
            return fontSize;
        }
        
        /** Setter for property fontSize.
         * @param fontSize New value of property fontSize.
         *
         */
        public void setFontSize(int fontSize) {
            this.fontSize = fontSize;
        }
        
        /** Getter for property italic.
         * @return Value of property italic.
         *
         */
        public boolean isItalic() {
            return italic;
        }
        
        /** Setter for property italic.
         * @param italic New value of property italic.
         *
         */
        public void setItalic(boolean italic) {
            this.italic = italic;
        }
        
        /** Getter for property lineSpacing.
         * @return Value of property lineSpacing.
         *
         */
        public java.lang.String getLineSpacing() {
            return lineSpacing;
        }
        
        /** Setter for property lineSpacing.
         * @param lineSpacing New value of property lineSpacing.
         *
         */
        public void setLineSpacing(java.lang.String lineSpacing) {
            this.lineSpacing = lineSpacing;
        }
        
        /** Getter for property pdfEmbedded.
         * @return Value of property pdfEmbedded.
         *
         */
        public boolean isPdfEmbedded() {
            return pdfEmbedded;
        }
        
        /** Setter for property pdfEmbedded.
         * @param pdfEmbedded New value of property pdfEmbedded.
         *
         */
        public void setPdfEmbedded(boolean pdfEmbedded) {
            this.pdfEmbedded = pdfEmbedded;
        }
        
        /** Getter for property pdfEncoding.
         * @return Value of property pdfEncoding.
         *
         */
        public java.lang.String getPdfEncoding() {
            return pdfEncoding;
        }
        
        /** Setter for property pdfEncoding.
         * @param pdfEncoding New value of property pdfEncoding.
         *
         */
        public void setPdfEncoding(java.lang.String pdfEncoding) {
            this.pdfEncoding = pdfEncoding;
        }
        
        /** Getter for property PDFFontName.
         * @return Value of property PDFFontName.
         *
         */
        public java.lang.String getPDFFontName() {
            return PDFFontName;
        }
        
        /** Setter for property PDFFontName.
         * @param PDFFontName New value of property PDFFontName.
         *
         */
        public void setPDFFontName(java.lang.String PDFFontName) {
            this.PDFFontName = PDFFontName;
        }
        
        /** Getter for property reportFont.
         * @return Value of property reportFont.
         *
         */
        public java.lang.String getReportFont() {
            return reportFont;
        }
        
        /** Setter for property reportFont.
         * @param reportFont New value of property reportFont.
         *
         */
        public void setReportFont(java.lang.String reportFont) {
            this.reportFont = reportFont;
        }
        
        /** Getter for property strikeTrought.
         * @return Value of property strikeTrought.
         *
         */
        public boolean isStrikeTrought() {
            return strikeTrought;
        }
        
        /** Setter for property strikeTrought.
         * @param strikeTrought New value of property strikeTrought.
         *
         */
        public void setStrikeTrought(boolean strikeTrought) {
            this.strikeTrought = strikeTrought;
        }
        
        /** Getter for property text.
         * @return Value of property text.
         *
         */
        public java.lang.String getText() {
            return text;
        }
        
        /** Setter for property text.
         * @param text New value of property text.
         *
         */
        public void setText(java.lang.String text) {
            this.text = text;
        }
        
        /** Getter for property TTFFont.
         * @return Value of property TTFFont.
         *
         */
        public java.lang.String getTTFFont() {
            return TTFFont;
        }
        
        /** Setter for property TTFFont.
         * @param TTFFont New value of property TTFFont.
         *
         */
        public void setTTFFont(java.lang.String TTFFont) {
            this.TTFFont = TTFFont;
        }
        
        /** Getter for property underline.
         * @return Value of property underline.
         *
         */
        public boolean isUnderline() {
            return underline;
        }
        
        /** Setter for property underline.
         * @param underline New value of property underline.
         *
         */
        public void setUnderline(boolean underline) {
            this.underline = underline;
        }
        
        /** Getter for property verticalAlign.
         * @return Value of property verticalAlign.
         *
         */
        public java.lang.String getVerticalAlign() {
            return verticalAlign;
        }
        
        /** Setter for property verticalAlign.
         * @param verticalAlign New value of property verticalAlign.
         *
         */
        public void setVerticalAlign(java.lang.String verticalAlign) {
            this.verticalAlign = verticalAlign;
        }
        
        public int getTextHeight(java.awt.FontMetrics fm)
        {
            // 
            return fm.getAscent() + (this.getLineCount()-1)*(fm.getHeight());
        }
        
        public int getLineCount()
        {
            // For any \n, return a line...
            String text = this.getText();
            text = text.replace('\r', ' ');
            int line=1;
            while (text.indexOf('\n')>0)
            {
                line++;
                text = text.substring( text.indexOf('\n') + 1);
            }
            return line;
        }
        
        public void copyBaseReportElement(ReportElement destination, ReportElement source)
        {
                super.copyBaseReportElement(destination, source);
                
                if (destination instanceof TextReportElement &&
                    source instanceof TextReportElement )
                {
                    ((TextReportElement)destination).setAlign(new String(  ((TextReportElement)source).getAlign() ));
                    ((TextReportElement)destination).setReportFont(((TextReportElement)source).getReportFont());
                    ((TextReportElement)destination).setFontName(new String(  ((TextReportElement)source).getFontName() ));
                    ((TextReportElement)destination).setPDFFontName(new String(  ((TextReportElement)source).getPDFFontName() ));
                    ((TextReportElement)destination).setFontSize( ((TextReportElement)source).getFontSize() );
                    ((TextReportElement)destination).setTTFFont(new String(  ((TextReportElement)source).getTTFFont() ));
                    ((TextReportElement)destination).setBold( ((TextReportElement)source).isBold() );
                    ((TextReportElement)destination).setItalic( ((TextReportElement)source).isItalic() );
                    ((TextReportElement)destination).setUnderline(  ((TextReportElement)source).isUnderline() );
                    ((TextReportElement)destination).setStrikeTrought(  ((TextReportElement)source).isStrikeTrought() );
                    ((TextReportElement)destination).setLineSpacing(new String(  ((TextReportElement)source).getLineSpacing() ));
                    ((TextReportElement)destination).setVerticalAlign (new String(  ((TextReportElement)source).getVerticalAlign() ));
                    ((TextReportElement)destination).setPdfEmbedded( ((TextReportElement)source).isPdfEmbedded());
                    ((TextReportElement)destination).setPdfEncoding(new String(  ((TextReportElement)source).getPdfEncoding() ));
                    ((TextReportElement)destination).setText(new String(  ((TextReportElement)source).getText() ));
                }
        }
}

