/*
 * Created on 19.12.2003
 *
 */

package LumiSoft.UI.Controls;

import java.awt.*;
import java.awt.font.*;
import java.awt.font.TextLayout;
import java.awt.geom.*;
import java.awt.image.*;
import javax.swing.*;
import java.text.*;
import java.util.*;

/**
 * Paint helper methods.
 */
public class Paint 
{
	/** 
	 * Calculates drawing area height.
	 * @param g Graphics object to use for drawing.
	 * @param font Font to use.
	 * @param text Text to draw.
	 * @param width Maximum line width.
	 */
	public static int CalcTextHeight(Graphics2D g,Font font,String text,int width)
	{
		return CalculateTextH(g,font,text,width);
	/*	int retVal = 0;
		
		Font gFont = g.getFont();
		g.setFont(font);		
						
		if(text.length() > 0){
			TextLayout[] lineInfos = GetTextLineInfo(g,font,text,width);
			for(int i=0;i<lineInfos.length;i++){
				TextLayout layout = lineInfos[i];
				
				// Move y-coordinate text height + line spacing
				retVal += layout.getAscent() + layout.getDescent() + layout.getLeading();
			}
		}
		else{
			retVal = g.getFontMetrics().getHeight();
		}	
		retVal++;
			
		// Retore graphics font
		g.setFont(gFont);
			
		return retVal;*/
	}
	
	/**
	 * Calculates text width.
	 * @param g Graphics object to use for drawing.
	 * @param font Font to use.
	 * @param text Text to draw.
	 */
	public static int CalcTextWidth(Graphics2D g,Font font,String text)
	{
		int retVal = 0;
		
		Font gFont = g.getFont();
		g.setFont(font);

		retVal = g.getFontMetrics().stringWidth(text);
	//	TextLayout layout = new TextLayout(text,font,g.getFontRenderContext());
	//	retVal = (int)layout.getBounds().getWidth();

		// Retore graphics font
		g.setFont(gFont);
		
		return retVal;
	}
	
	/** 
	 * Draws text to specified rectangle with specified alingment.
 	 * @param g Graphics object to use for drawing.
	 * @param font Font to use.
	 * @param text Text to draw.
	 * @param rect Drawing rectangle.
	 * @param hzAlign Horizontal alignment.
	 */
	public static void DrawText(Graphics2D g,Font font,String text,Rectangle rect,int hzAlign)
	{	
		if(text.length() == 0){
			return;			
		}
		
	//	g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		
		Dr(g,font,text,rect,hzAlign);
		
	/*	Font gFont = g.getFont();
		g.setFont(font);
	
		
		TextLayout[] lineInfos = GetTextLineInfo(g,font,text,rect.width);
		
		int textHeight = 0;
		for(int i=0;i<lineInfos.length;i++){
			textHeight += lineInfos[i].getAscent() + lineInfos[i].getDescent() + lineInfos[i].getLeading();
		}
		
		float drawY = (float)(rect.getY());
		if(textHeight < rect.height){
			drawY += (rect.height - textHeight) / 2;
		}
		else{
			drawY += (rect.height - lineInfos[0].getAscent() - lineInfos[0].getDescent()) / 2;
		}
		
		for(int i=0;i<lineInfos.length;i++){
			TextLayout layout = lineInfos[i];
			
			// Move y-coordinate by the ascent of the layout.
			drawY += layout.getAscent();
			
			// We exceeded maximum allowed draw rect, don't draw any more.
			if(drawY > rect.getMaxY()){
				break;
			}
			
			Rectangle2D tBounds = layout.getBounds();					
			switch(hzAlign)
			{
				case HorizontalAlignment.Center:
					layout.draw(g,(float)rect.getX() + (float)(rect.width - tBounds.getWidth()) / 2 ,drawY);
					break;
					
				case HorizontalAlignment.Left:
					layout.draw(g,(int)rect.getX(),drawY);
					break;
									
				case HorizontalAlignment.Right:
					layout.draw(g,(float)rect.getX() + (float)(rect.width - tBounds.getWidth()),drawY);
					break;
			}
				
			// Move y-coordinate in preparation for next layout.
			drawY += layout.getDescent() + layout.getLeading();
		}
		
	//	g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
		
		// Retore graphics font
		g.setFont(gFont);*/
	}
	
	/** 
	 * Draws triangle to specified rectangle with specified direction.
	 * @param g Graphics object to use for drawing.
	 * @param rect Triangle bounding rectangle.
	 * @param direction Triangle top direction.
	 */
	public static void DrawTriangle(Graphics2D g,Rectangle rect,int direction)
	{
		int x = rect.x;
		int y = rect.y;
		
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
		
		switch(direction)
		{
			case Direction.Up:
				g.fillPolygon(new int[]{x,x + (rect.width / 2),x + rect.width},new int[]{y + rect.height,y,y + rect.height},3);
				break;
				
			case Direction.Down:
				g.fillPolygon(new int[]{x,x + (rect.width / 2),x + rect.width},new int[]{y,y + rect.height,y},3);
				break;
				
			case Direction.Left:
				g.fillPolygon(new int[]{x,x + rect.width,x + rect.width},new int[]{y + (rect.height / 2),y,y + rect.height},3);
				break;
				
			case Direction.Right:
				g.fillPolygon(new int[]{x,x + rect.width,x},new int[]{y,y + (rect.height / 2),y + rect.height},3);				
				break;
		}
		
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_OFF);
	}
	
	
	
	public static Image CreateGrayedImage(Component component,Image image)
	{		
		if(image.getWidth(component) < 0 || image.getHeight(component) < 0){
			return new BufferedImage(1,1,BufferedImage.TYPE_INT_ARGB);
		}
		
		// Create a BufferedImage to use in order to snapshot the UI
        Image snapshot = new BufferedImage(image.getWidth(component),image.getHeight(component),BufferedImage.TYPE_INT_ARGB);
          
        // fetch the Graphics from the image
        Graphics g = snapshot.getGraphics();
        //       
        g.drawImage(image,0,0,component);
        
        // dispose the graphics to free resources
        g.dispose();
        
        // use GrayFilter to grey out the image
        snapshot = GrayFilter.createDisabledImage(snapshot);
        
		return snapshot;
	}
	
	private static void Dr(Graphics2D g,Font font,String text,Rectangle rect,int hzAlign)
	{
		Font gFont = g.getFont();
		g.setFont(font);
		
		FontMetrics fontMetrics = g.getFontMetrics();
		
		int textHeight = CalculateTextH(g,font,text,rect.width);
		float drawY = (float)(rect.getY());
		if(textHeight < rect.height){
			drawY += (rect.height - textHeight) / 2;
		}
		else{
			drawY += (rect.height - fontMetrics.getAscent() - fontMetrics.getDescent()) / 2;
		}
		
		String[] lines = GetLines(g,font,text,rect);
		for(String line : lines){
			// Move y-coordinate by the ascent of the layout.
			drawY += fontMetrics.getAscent();
			
			// We exceeded maximum allowed draw rect, don't draw any more.
			if(drawY > rect.getMaxY()){
				break;
			}
						
			int lineTextWidth = fontMetrics.stringWidth(line);
			switch(hzAlign)
			{
				case HorizontalAlignment.Center:
					g.drawString(line,(float)rect.getX() + (float)(rect.width - lineTextWidth) / 2 ,drawY);
					break;
					
				case HorizontalAlignment.Left:
					g.drawString(line,(int)rect.getX(),drawY);
					break;
									
				case HorizontalAlignment.Right:
					g.drawString(line,(float)rect.getX() + (float)(rect.width - lineTextWidth),drawY);
					break;
			}
				
			// Move y-coordinate in preparation for next layout.
			drawY += fontMetrics.getDescent() + fontMetrics.getLeading();
		}
		
		// Retore graphics font
		g.setFont(gFont);
	}
	
	private static String[] GetLines(Graphics2D g,Font font,String text,Rectangle rect)
	{
		ArrayList<String> lines = new ArrayList<String>();
		StringBuffer currentLineChars = new StringBuffer();
		int currenLineWidth = 0;
		FontMetrics fontMetrics = g.getFontMetrics();
		char[] chars = text.toCharArray();
		for(char c : chars){
			if(c == '\n'){				
				lines.add(currentLineChars.toString());
				currenLineWidth = 0;
				currentLineChars = new StringBuffer();
			}
			else{
				int charWidth = fontMetrics.charWidth(c);
				if((currenLineWidth + charWidth) < rect.width){
					currenLineWidth += charWidth;
					currentLineChars.append(c);
				}
				// this char won't fit in current row, need to add new row
				else{
					String currentLine = currentLineChars.toString();
					// There is <SP> in line, split from there
					if(currentLine.indexOf(' ') > -1){
						lines.add(currentLine.substring(0,currentLine.lastIndexOf(' ')));
						String remainingLine = currentLine.substring(currentLine.lastIndexOf(' '));
						
						currenLineWidth = fontMetrics.stringWidth(remainingLine) + charWidth;
						currentLineChars = new StringBuffer();
						currentLineChars.append(remainingLine);
						currentLineChars.append(c);
					}
					else{
						lines.add(currentLineChars.toString());
						currenLineWidth = charWidth;
						currentLineChars = new StringBuffer();
						currentLineChars.append(c);
					}
				}
			}
		}
		
		// add last line
		if(currenLineWidth > 0){
			lines.add(currentLineChars.toString());
		}
		
		String[] retVal = new String[lines.size()];
		lines.toArray(retVal);
		
		return retVal;
	}
	
	private static int CalculateTextH(Graphics2D g,Font font,String text,int width)
	{					
		return GetLines(g,font,text,new Rectangle(0,0,width,99999999)).length * g.getFontMetrics().getHeight();
	}
	
	/*
	private static TextLayout[] GetTextLineInfo(Graphics2D g,Font font,String text,int width)
	{
		text = text.replace("\r","");
		String[] lines = text.split("\n");
		
		ArrayList<TextLayout> retVal = new ArrayList<TextLayout>();
		
		for(int i=0;i<lines.length;i++){
			TextLayout textLayout = new TextLayout(lines[i],font,g.getFontRenderContext());
			if(textLayout.getBounds().getWidth() > width){
				Hashtable map = new Hashtable();
				map.put((Object)TextAttribute.SIZE,new Float(font.getSize()));
				AttributedString aStr = new AttributedString(lines[i],map);
				
				LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(aStr.getIterator(),g.getFontRenderContext());
				while(lineMeasurer.getPosition() < lines[i].length()){
					retVal.add(lineMeasurer.nextLayout(width));
				}
			}
			else{
				retVal.add(textLayout);
			}
		}
		
		TextLayout[] x = new TextLayout[retVal.size()];
		retVal.toArray(x);
		return x;
	}*/
}
