/*******************************************************************************
 * This file is part of GECAMed.
 * 
 * GECAMed is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License (L-GPL) as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * GECAMed 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 (L-GPL)
 * along with GECAMed.  If not, see <http://www.gnu.org/licenses/>.
 * 
 * GECAMed is Copyrighted by the Centre de Recherche Public Henri Tudor (http://www.tudor.lu)
 * (c) CRP Henri Tudor, Luxembourg, 2008
 *******************************************************************************/
package lu.tudor.santec.gecamed.billing.gui.admin;

import java.util.Date;
import java.util.HashMap;
import java.util.Vector;

import javax.swing.tree.TreePath;

import lu.tudor.santec.gecamed.billing.ejb.entity.beans.KeyValue;
import lu.tudor.santec.gecamed.billing.ejb.entity.beans.Rate;
import lu.tudor.santec.i18n.Translatrix;

import org.jdesktop.swingx.treetable.DefaultTreeTableModel;
import org.jdesktop.swingx.treetable.TreeTableNode;

//***************************************************************************
//* Class Definition and Members                                            *
//***************************************************************************

public class RateTreeTableModel extends DefaultTreeTableModel
	{
 	public static final Date c_Epoch = new Date (0);
 	
//---------------------------------------------------------------------------
//***************************************************************************
//* Constants	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

    public static final String c_TOCHeader		 		= "RateTreeTableModel.TOCHeader";
    public static final String c_LabelHeader		 	= "RateTreeTableModel.LabelHeader";
    public static final String c_CATHeader 				= "RateTreeTableModel.CATHeader";
    public static final String c_CACHeader 				= "RateTreeTableModel.CACHeader";
    public static final String c_APCMHeader 			= "RateTreeTableModel.APCMHeader";
    public static final String c_ACMHeader 				= "RateTreeTableModel.ACMHeader";
    public static final String c_ApplicabilityHeader  	= "RateTreeTableModel.ApplicabilityHeader";
    public static final String c_CoefficientHeader 		= "RateTreeTableModel.CoefficientHeader";
    public static final String c_AmountHeader 			= "RateTreeTableModel.AmountHeader";
    
    public static final int		c_TOCColumn				= 0;
    public static final int		c_LabelColumn			= 1;
    public static final int		c_CATColumn				= 2;
    public static final int		c_CACColumn				= 3;
    public static final int		c_APCMColumn			= 4;
    public static final int		c_ACMColumn				= 5;   
    public static final int		c_CoefficientColumn		= 6;
    public static final int		c_ApplicabilityColumn	= 7;
    public static final int		c_AmountColumn			= 8;
          
    static final public String c_TableHeaders [] = { 	c_TOCHeader,
    													c_LabelHeader,
    													c_CATHeader,
    													c_CACHeader,
    													c_APCMHeader,
    													c_ACMHeader,
    													c_CoefficientHeader,
    													c_ApplicabilityHeader,
    													c_AmountHeader   };

	private HashMap<Integer, Vector<KeyValue>> keyValueHash;

	private Date m_Today;
 	
//---------------------------------------------------------------------------
//***************************************************************************
//* Constructor	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

public  RateTreeTableModel ()
	{
	super(new RateTreeNode ());
	m_Today = new Date ();
	}
    
//---------------------------------------------------------------------------
//***************************************************************************
//* Primitives	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

private String formatTOCEntry (RateTreeNode p_Node)
	{
	if (p_Node == null) return "";
		
	if (p_Node.getRateIndex() != null)
		{      
		return p_Node.getRateIndex().getTitle();
		}
	
	else return "Root";	
	}
    

//---------------------------------------------------------------------------
//***************************************************************************
//* Class Body	                                                            *
//***************************************************************************
//---------------------------------------------------------------------------

public String getColumnName (int p_Column)
    {
    if ((p_Column >=0) && (p_Column < c_TableHeaders.length))
		{
		return (Translatrix.getTranslationString(c_TableHeaders[p_Column]));
		}
    else return ("");
    }

//---------------------------------------------------------------------------

public int getColumnCount ()
    {
    return (c_TableHeaders.length);
    }

//---------------------------------------------------------------------------

public int getRowCount ()
    {
    return (1);
    }

//---------------------------------------------------------------------------

public int getHierarchicalColumn()
	{
	return c_TOCColumn;
	}

//---------------------------------------------------------------------------

public Object getValueAt (Object p_Node, int p_Column)
	{
	Rate l_Rate;
	
	if (p_Node instanceof RateTreeNode)
		{
		l_Rate = ((RateTreeNode)p_Node).getRate();
		if (l_Rate != null)
			{
			switch (p_Column)
				{
				case c_TOCColumn:			return (l_Rate.getCode()  != null) ? l_Rate.getCode()  : "";
				case c_LabelColumn: 		return (l_Rate.getLabel() != null) ? l_Rate.getLabel() : "";       
				case c_CATColumn: 			return (l_Rate.getCAT() != null)   ? l_Rate.getCAT()   : Boolean.FALSE;
				case c_CACColumn: 			return (l_Rate.getCAC() != null)   ? l_Rate.getCAC()   : Boolean.FALSE;
				case c_APCMColumn: 			return (l_Rate.getAPCM() != null)  ? l_Rate.getAPCM()  : Boolean.FALSE;
				case c_ACMColumn: 			return (l_Rate.getACM() != null)   ? l_Rate.getACM()   : Boolean.FALSE;
				case c_ApplicabilityColumn: return (l_Rate.getApplicability() != null)  ? l_Rate.getApplicability()   : c_Epoch;
				case c_CoefficientColumn:	return (l_Rate.getCoefficient() != null) ? l_Rate.getCoefficient()  : Double.valueOf(0d);
				case c_AmountColumn: 		return monetizeRate(l_Rate);
				}
			}
		else
			{
			switch (p_Column)
				{
				case c_TOCColumn:		return this.formatTOCEntry ((RateTreeNode)p_Node);
				default:				return "";
				}
			}
		}

	return "";		
	}

private Double monetizeRate(Rate p_Rate) {
	try {
		Vector<KeyValue> l_keyVals = keyValueHash.get(p_Rate.getKeyType());
		for (KeyValue keyValue : l_keyVals) {
			if (m_Today.after(keyValue.getApplicability())) {
				return p_Rate.monetize(keyValue);
			}
		}
	} catch (Exception e) {
	}
	return Double.valueOf(0d);
}

//---------------------------------------------------------------------------

public Class<?> getColumnClass (int p_Column)
	{
	RateTreeNode	l_Node;
	
	l_Node = new RateTreeNode ();
	return this.getValueAt(l_Node, p_Column).getClass();	
	}

//---------------------------------------------------------------------------

public boolean isCellEditable (Object p_Node, int p_Column)
	{
	return false;
	}

//---------------------------------------------------------------------------

public int getChildCount (Object p_Node)
	{
	RateTreeNode l_Node;	
		
	if (p_Node instanceof RateTreeNode)
		{
		l_Node = (RateTreeNode) p_Node;
		return l_Node.getChildCount();
		}
	else return 0;
	}

//---------------------------------------------------------------------------

public Object getChild (Object p_Node, int p_Index)
	{
	RateTreeNode l_Node;	
		
	if (p_Node instanceof RateTreeNode)
		{
		l_Node = (RateTreeNode) p_Node;
		return l_Node.getChildAt(p_Index);
		}
	else return null;
	}

//---------------------------------------------------------------------------

public int getIndexOfChild (Object p_Parent, Object p_Child)
	{
	RateTreeNode l_Parent;	
	RateTreeNode l_Child;	
	
	if (	(p_Parent instanceof RateTreeNode)
		 && (p_Child instanceof RateTreeNode))
		{
		l_Parent = (RateTreeNode) p_Parent;
		l_Child  = (RateTreeNode) p_Child;
		return l_Parent.getIndex (l_Child);
		}
	else return 0;
	}

//---------------------------------------------------------------------------

public boolean isLeaf (Object p_Node)
	{
	RateTreeNode l_Node;	
		
	if (p_Node instanceof RateTreeNode)
		{
		l_Node = (RateTreeNode) p_Node;
		return l_Node.isLeaf();
		}
	else return false;
	}

//---------------------------------------------------------------------------

public TreeTableNode getRoot()
	{	
	return super.getRoot();
	}

//---------------------------------------------------------------------------

public void setRoot (RateTreeNode p_RootNode)
	{
	RateTreeNode l_Root	= (RateTreeNode) super.getRoot();
//	if (l_Root != null) l_Root.removeAllChildren();
	
	super.setRoot(p_RootNode);
	}

//---------------------------------------------------------------------------

public void nodeChanged (RateTreeNode node)
	{
	TreeTableNode	parent		= node.getParent();
	TreePath		parentPath	= new TreePath(getPathToRoot(parent));
	int				index		= parent.getIndex(node);
	
	modelSupport.fireChildChanged(parentPath, index, node);
	}

public void setKeyValues(HashMap<Integer, Vector<KeyValue>> keyValues) {
	this.keyValueHash = keyValues;
}

//---------------------------------------------------------------------------
//***************************************************************************
//* End of Class                                                            *
//***************************************************************************
//---------------------------------------------------------------------------
	}
