/*
 * Copyright
 *   2007 axYus - www.axyus.com
 *   2005 C.Marchand - christophe.marchand@axyus.com
 *
 * This file is part of XEMELIOS.
 *
 * XEMELIOS is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * XEMELIOS 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 Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with XEMELIOS; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

package fr.gouv.finances.cp.utils.ui;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.StringTokenizer;

import javax.imageio.ImageIO;
import javax.imageio.ImageReader;
import javax.imageio.stream.MemoryCacheImageInputStream;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;

import fr.gouv.finances.cp.utils.StringUtilities;

/**
 * @author chm
 */
public class IhmFactory {
	private Hashtable<String,Font> fonts=null;
	private Hashtable<String,Color> colors=null;

	/**
	 * Constructor for UIFactory.
	 */
	private IhmFactory() {
		super();
		fonts = new Hashtable<String,Font>();
		colors = new Hashtable<String,Color>();
	}
	
	public static IhmFactory newInstance() {
		return new IhmFactory();
	}
	
	/**
	 * Construit un nouveau label.
	 * @param text Le texte du label
	 * @param txtClass Une chaine representant le format du texte.
	 * <p>Le format du texte est le suivant : <tt>[&lt;font-info&gt;[:&lt;text-color&gt;[:&lt;back-color&gt;]]]</tt>
	 * ou <ul><li><tt>&lt;font-info&gt;</tt> est de la forme <tt>[normal[-{italic|bold}[-{italic|bold}]]]</tt></li>
	 * <li><tt>&lt;text-color&gt;</tt> est de la forme <tt>[black|blue|cyan|darkgray|gray|green|lightgray|magenta|orange|pink|red|white|yellow|#xxxxxx]</tt></li>
	 * <li><tt>&lt;back-color&gt;</tt> est de la forme <tt>[black|blue|cyan|darkgray|gray|green|lightgray|magenta|orange|pink|red|white|yellow|#xxxxxx]</tt></li></ul>
	 * @return Le label construit
	 */
	public JLabel newLabel(String text, String txtClass) {
		String fontSpec = null;
		String fontColor = null;
		String backColor = null;
		if(txtClass!=null) {
			StringTokenizer st = new StringTokenizer(txtClass,":");
			fontSpec = st.nextToken();
			if(st.hasMoreTokens()) fontColor=st.nextToken();
			if(st.hasMoreTokens()) backColor=st.nextToken();
		}
		String fontName = "dialog-"+(fontSpec!=null?fontSpec.toLowerCase():"");
		JLabel ret = new JLabel(text);
		if(txtClass==null) return ret;
		Font font = getFont(ret.getFont(),fontName);
		ret.setFont(font);
		if(fontColor!=null) {
			Color col = decodeColor(fontColor);
			if(col!=null) ret.setForeground(col);
		}
		if(backColor!=null) {
			Color col = decodeColor(backColor);
			if(col!=null) ret.setBackground(col);
		}
		return ret;
	}
	public JLabel newLabel(String text) { return newLabel(text,null); }
	
	
	// private implementations
	
	/**
	 * Renvoie la police demandee
	 * @param font Une police basique
	 * @param c la chaine indiquant le type de police demandee.
	 * La forme est <tt>{dialog|&lt;font-familly&gt;}-[normal[-{italic|bold}[-{italic|bold}]]]</tt>
	 * @return La font demandee
	 */
	protected Font getFont(Font font, String c) {
		Font ret = fonts.get(c);
		if(ret==null) {
			ret = font;
			if(c.indexOf("normal")>=0) ret=ret.deriveFont(Font.PLAIN);
			if(c.indexOf("italic")>=0) ret=ret.deriveFont(Font.ITALIC);
			if(c.indexOf("bold")>=0) ret = ret.deriveFont(Font.BOLD);
			fonts.put(c,ret);
		}
		return ret;
	}
	public Color decodeColor(String col) {
		String c = col.toLowerCase();
		Color ret = colors.get(c);
		if(ret==null) {
			if("black".equals(col)) ret = Color.BLACK;
			else if("blue".equals(col)) ret = Color.BLUE;
			else if("cyan".equals(col)) ret = Color.CYAN;
			else if("darkgray".equals(col)) ret = Color.DARK_GRAY;
			else if("gray".equals(col)) ret = Color.GRAY;
			else if("green".equals(col)) ret = Color.GREEN;
			else if("lightgray".equals(col)) ret = Color.LIGHT_GRAY;
			else if("magenta".equals(col)) ret = Color.MAGENTA;
			else if("orange".equals(col)) ret = Color.ORANGE;
			else if("pink".equals(col)) ret = Color.PINK;
			else if("red".equals(col)) ret = Color.RED;
			else if("white".equals(col)) ret = Color.WHITE;
			else if("yellow".equals(col)) ret = Color.YELLOW;
			else if(col.startsWith("#")) {
				if(col.length()==7) {
					String s = col.toUpperCase();
					int r=Integer.parseInt(s.substring(1,2));
					int g=Integer.parseInt(s.substring(3,4));
					int b=Integer.parseInt(s.substring(5,6));
					ret = new Color(r,g,b);
				}
			}
			if(ret!=null) colors.put(col,ret);
		}
		return ret;
	}
	public JButton newButton(String text) {
		JButton ret = new JButton(text);
		addInfoMgr(ret);
		return ret;
	}
	public JButton newButton(Icon icon) {
		JButton ret = new JButton(icon);
		addInfoMgr(ret);
		return ret;
	}
	public JButton newButton(String text, Icon icon) {
		JButton ret = new JButton(text,icon);
		addInfoMgr(ret);
		return ret;
	}
	public JButton newButton(Action action) {
		JButton ret = new JButton(action);
		addInfoMgr(ret);
		return ret;
	}
	protected void addInfoMgr(JButton button) {
		button.setBorderPainted(false);
		button.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseEntered(MouseEvent e) {
				((JButton)e.getSource()).setBorderPainted(true);
				((JButton)e.getSource()).setOpaque(true);
			}
			@Override
			public void mouseExited(MouseEvent e) {
				((JButton)e.getSource()).setBorderPainted(false);
				((JButton)e.getSource()).setOpaque(false);
			}
		});
	}
	public static ImageIcon getIconFromResource(String resName) {
		Iterator it = ImageIO.getImageReadersBySuffix(StringUtilities.getFileNameSuffix(resName));
		if(it.hasNext()) {
			ImageReader ir = (ImageReader)it.next();
			InputStream is = IhmFactory.class.getClassLoader().getResourceAsStream(resName);
			try {
				MemoryCacheImageInputStream fiis = new MemoryCacheImageInputStream(is);
				ir.setInput(fiis);
				BufferedImage bi = ir.read(0);
				fiis.close();
				ImageIcon icon = new ImageIcon(bi);
				return icon;
			} catch(IOException ioEx) {
				return null;
			}
		}
		return null;
	}
}
