/*
 * ECatalog is a database front-end, with two main features:
 * 1. Use of preferences
 *  A preference-based approach, where the user is allowed to define the importance of each criterion.
 *  Then the items are ranked accordingly to his criteria.
 * 2. Trade-off analysis
 *  A cooperative database approach, where the system "argues" with the user about his criteria.
 *  When there are no matching items, the system explains the minimal conflicting set and
 *  give some possible strong and weak relaxations about his criteria.
 * This package also containts the software and the set-up details used for our User Study,
 * comparing the use or not of the two previous features mentioned above.
 *
 * Copyright (C) 2006 David Portabella Clotet, Artificial Intelligence Laboratory, EPFL
 * 
 * This file is part of ecatalog-1.0.zip
 * 
 * ECatalog is free software and a free user study set-up;
 * 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.
 * 
 * ECatalog 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 ECatalog; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 * 
 * @version 1.0
 * @author David Portabella
 * To contact the author:
 * email: david@portabella.name and david.portabella@epfl.ch
 * 
 * More information about ECatalog:
 *  http://sourceforge.net/projects/ecatalog/
 *  http://icwww.epfl.ch/~portabel/ecatalogs/
 */

package utils;

/*
 * Créé le 1 févr. 2006
 *
 *	Autor:		Patrick Dos Santos
 *	Datum:		01.02.2006
 *
 * TODO Pour changer le modèle de ce fichier généré, allez à :
 * Fenêtre - Préférences - Java - Style de code - Modèles de code
 */
import javax.swing.*;
import javax.swing.plaf.*;
import java.awt.*;
import javax.swing.plaf.basic.BasicToolTipUI;


public class JMultiLineToolTip extends JToolTip{
		String tipText;
		JComponent component;
		private double ratio = 0;
		private Insets insets;
		private int maxWidth=0;
		
		public Insets getInsets() {
			return insets;
		}

		public void setInsets(Insets insets) {
		}

			//Constructor with margins for the JtextArea of the Customized ToolTip
		public JMultiLineToolTip(double ratio, int maxWidth,int top, int left, int bottom, int right) {
			setMaxWidth(maxWidth);
			setRatio(ratio);
			insets=new Insets(top,left,bottom,right);
		    updateUI();
		}
		
		//Constructor without margins
		public JMultiLineToolTip(double ratio, int maxWidth) {
			setMaxWidth(maxWidth);
			setRatio(ratio);
			insets=null;
		    updateUI();
		}
		
		public void updateUI() {
			setUI(MultiLineToolTipUI.createUI(this));
		}
	
		public void setRatio(double ratio){
			this.ratio = ratio;
		}
		
		public double getRatio(){
			return ratio;
		}

		public int getMaxWidth() {
			return maxWidth;
		}

		public void setMaxWidth(int maxWidth) {
			this.maxWidth = maxWidth;
		}
	}



	class MultiLineToolTipUI extends BasicToolTipUI {
		static MultiLineToolTipUI sharedInstance = new MultiLineToolTipUI();
		Font smallFont=new Font(" TimesRoman ",Font.PLAIN,12); 			     
		static JToolTip tip;
		protected CellRendererPane rendererPane;
		
		private static JTextArea textArea ;
		
		public static ComponentUI createUI(JComponent c) {
		    return sharedInstance;
		}
		
		public MultiLineToolTipUI() {
		    super();
		}
		
		public void installUI(JComponent c) {
		    super.installUI(c);
			tip = (JToolTip)c;
		    rendererPane = new CellRendererPane();
		    c.add(rendererPane);
		}
		
		public void uninstallUI(JComponent c) {
			super.uninstallUI(c);
			
		    c.remove(rendererPane);
		    rendererPane = null;
		}
		
		public void paint(Graphics g, JComponent c) {
		    Dimension size = c.getSize();
		    textArea.setBackground(c.getBackground());
			rendererPane.paintComponent(g, textArea, c, 1, 1,
						    size.width - 1, size.height - 1, true);
		}
		
		public Dimension getPreferredSize(JComponent c) {
			String tipText = ((JToolTip)c).getTipText();
			if (tipText == null)
				return new Dimension(0,0);
			
			
			textArea = new JTextArea(tipText);
			textArea.setFont(smallFont);

			//FontMetrics is needed here (N.B : smallFont has been initialized)
			//The information recolted here is the height and the width of a text rendered in one line only.
			//The heighttemp variable contains the approximate height of a rendered line.
	        FontMetrics fm = textArea.getFontMetrics(smallFont);
	        int widthtemp = fm.stringWidth(tipText);
	        int heightemp = fm.getHeight();

	        
	        double ratio=((JMultiLineToolTip)c).getRatio();
			Dimension d = textArea.getPreferredSize();
			while(d.width>ratio*d.height){
				d.height+=heightemp;
				d.width=(widthtemp*heightemp)/d.height;
			}
	        //It corrects the given results a little bit...
			d.height+=Math.abs(d.width-d.height)/10;
			d.width+=ratio*Math.abs(d.width-d.height)/10;
			
			//Test if the width is higher than the maximum value
			if (d.width>((JMultiLineToolTip)c).getMaxWidth()){
				d.width=((JMultiLineToolTip)c).getMaxWidth();
			}

			textArea.setLineWrap(true);
			textArea.setSize(d.width,1);
			d.width=(int)textArea.getPreferredSize().width;
			d.height=(int)textArea.getPreferredSize().height;

	        //Inset
			if(((JMultiLineToolTip)c).getInsets()!=null){
			textArea.setMargin(((JMultiLineToolTip)c).getInsets());
			d.height+=((JMultiLineToolTip)c).getInsets().bottom+((JMultiLineToolTip)c).getInsets().top;
			d.width+=ratio*(((JMultiLineToolTip)c).getInsets().right+((JMultiLineToolTip)c).getInsets().left);
			}

			
			rendererPane.removeAll();
			rendererPane.add(textArea );
			textArea.setWrapStyleWord(true);
			if(d.width==0 || d.height==0 ){
				return new Dimension(0,0);
			}
			
			else{
			return d;
			}
		}
		
		public Dimension getMinimumSize(JComponent c) {
		    return getPreferredSize(c);
		}
		
		public Dimension getMaximumSize(JComponent c) {
		    return getPreferredSize(c);
		}
	}

