/*
 * Created on Apr 1, 2004
 *
 */
package LumiSoft.UI.Controls.Grid.Editors;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.*;
import javax.swing.event.EventListenerList;

import LumiSoft.UI.Controls.*;
import LumiSoft.UI.Controls.Paint;
import LumiSoft.UI.Controls.Grid.*;

/**
 * This base class for grid editors, all gird editors must derrive from this class.
 * 
 */
public abstract class WBaseEditor extends JPanel
{	
	protected WGridTableView m_pGridView = null;
	private EventListenerList m_pValueChangedLister = null;
	private Object         m_Value = null;
	private Dimension      m_Size  = new Dimension(0,0);
	
	/**
	 * Default contructor.
	 *
	 */
	public WBaseEditor()
	{
		this.setFocusable(false);
		
		m_pValueChangedLister = new EventListenerList();
	}
	
	
	public void paintComponent(Graphics g)
	{
		if(m_Size != this.getSize()){
			m_Size = this.getSize();
			
			SizeChanged();			
		}
		
		super.paintComponent(g);
	}
	
	protected void SizeChanged()
	{		
	}
	
	
	/**
	 * Paints default editor. This is called foreach visible cell what isn't active editor.
	 * @param g Graphics where to draw.
	 * @param value Cell value.
	 * @param cellBounds Cell bounds.
	 * @param evenrow Specifies if row is even row (2,4,6...).
	 * @param selected Specifies if cell is selected.
	 * @param column Cell owner column.
	 */
	public void PaintDefault(Graphics2D g,Object value,Rectangle cellBounds,boolean evenrow,boolean selected,WGridColumn column)
	{
		ViewStyle viewStyle = column.getColumns().getView().getGrid().getViewStyle();
		
		if(value != null && value.getClass() == java.util.Date.class){
			java.text.DateFormat f = new java.text.SimpleDateFormat("dd.MM.yyyy");//java.text.SimpleDateFormat.getDateInstance(java.text.SimpleDateFormat.SHORT);
			value = f.format(value);
		}
		else if(value != null && value.getClass() == Boolean.class){
			Rectangle checkRect = new Rectangle(cellBounds.x + (int)(cellBounds.getWidth() - 12) / 2,cellBounds.y + (int)(cellBounds.getHeight() - 13) / 2,12,12);
									
			// Fill checkrect
			g.setColor(Color.WHITE);
			g.fill(checkRect);
			
			if(((Boolean)value).booleanValue()){
				// Draw check (Lines from up to down).
				g.setColor(Color.BLACK);
				g.drawLine(checkRect.x + 3,checkRect.y + 5,checkRect.x + 3,checkRect.y + 5 + 2);
				g.drawLine(checkRect.x + 4,checkRect.y + 6,checkRect.x + 4,checkRect.y + 6 + 2);
				g.drawLine(checkRect.x + 5,checkRect.y + 7,checkRect.x + 5,checkRect.y + 7 + 2);
				g.drawLine(checkRect.x + 6,checkRect.y + 6,checkRect.x + 6,checkRect.y + 6 + 2);
				g.drawLine(checkRect.x + 7,checkRect.y + 5,checkRect.x + 7,checkRect.y + 5 + 2);
				g.drawLine(checkRect.x + 8,checkRect.y + 4,checkRect.x + 8,checkRect.y + 4 + 2);
				g.drawLine(checkRect.x + 9,checkRect.y + 3,checkRect.x + 9,checkRect.y + 3 + 2);
			}
			
			// Draw rect around check
			g.setColor(viewStyle.GetBorderColor(false));
			g.draw(checkRect);
			
			value = null; // Force not to draw text 
		}	
		else if(column.getCellTextFormat().length() > 0){	
			// Decimal places formating
			if(column.getCellTextFormat().startsWith("f")){
				if(value == null || value.toString().length() == 0){
					value = new Double(0);
				}
				
				int decimalPlaces = 0;
				try{
					decimalPlaces = Integer.parseInt(column.getCellTextFormat().substring(1));
					
					java.text.DecimalFormat format = new java.text.DecimalFormat();
					format.setMinimumFractionDigits(decimalPlaces);
					format.setMaximumFractionDigits(decimalPlaces);
					format.setGroupingUsed(false);
					
					value = format.format(Double.parseDouble(value.toString()));
				}
				catch(Exception x){
			//		x.printStackTrace();					
				}
			}
		}
		
		if(selected){
			g.setColor(viewStyle.getGridRowSelectedTextColor());
		}
		else{
			if(value != null && value.getClass() == java.math.BigDecimal.class && ((java.math.BigDecimal)value).floatValue() < 0){
				g.setColor(Color.RED);
			}
			else if(evenrow){
				g.setColor(viewStyle.getGridEvenRowTextColor());
			}
			else{
				g.setColor(viewStyle.getGridRowTextColor());
			}
		}
		if(value != null){
			Paint.DrawText(g,this.getFont(),value.toString(),cellBounds,column.getCellsTextAlign());
		}
	}
	
	/**
	 * Calculates height needed for this editor.
	 * @param g
	 * @param value
	 * @param column
	 * @return
	 */
	public int CalculateHeight(Graphics2D g,Object value,WGridColumn column)
	{
	/*	if(value != null && value.getClass() == java.util.Date.class){
			java.text.DateFormat f = java.text.SimpleDateFormat.getDateInstance(java.text.SimpleDateFormat.SHORT);
			value = f.format(value);
		}
		else if(value != null && column.getCellTextFormat().length() > 0){
			// Decimal places formating
			if(column.getCellTextFormat().startsWith("f")){
				int decimalPlaces = 0;
				try{
					decimalPlaces = Integer.parseInt(column.getCellTextFormat().substring(1));
					
					java.text.DecimalFormat format = new java.text.DecimalFormat();
					format.setMinimumFractionDigits(decimalPlaces);
					format.setMaximumFractionDigits(decimalPlaces);
					format.setGroupingUsed(false);
					
					value = format.format(Double.parseDouble(value.toString()));
				}
				catch(Exception x){
			//		x.printStackTrace();					
				}
			}
		}
						
		return Paint.CalcTextHeight(g,this.getFont(),value.toString(),column.getBounds().width);
		*/
		return 19;
	}
	
	private boolean m_StartingEdit = false;	
	/**
	 * 
	 * @param view
	 * @param value
	 */
	public void StartEdit(WGridTableView view,Object value)
	{
		m_StartingEdit = true;
		
		m_pGridView = view;
		this.setValue(value);
		this.SelectAll();
		this.repaint();
		
		m_StartingEdit = false;
	}
	
	
	/**
	 * Selects editor value if editor supports it.
	 *
	 */
	public void SelectAll()
	{		
	}
	
	/**
	 * Restores EditValue with orginal value setted by setValue.
	 *
	 */
	public void Undo()
	{
		if(getIsModified()){
			setEditValue(m_Value);
		}
		else{
			m_pGridView.UndoRow();
		}
	}
	
	
	/**
	 * Gets value.
	 * @return
	 */
	public Object getValue()
	{
		return m_Value;
	}
	/**
	 * Sets value.
	 * @param value
	 */
	public void setValue(Object value)
	{	
		m_Value = value;
		setEditValue(value);
	}
	
	/**
	 * Gets value what is currently visible in editor.
	 * @return
	 */
	public Object getEditValue()
	{
		return m_Value;
	}
	/**
	 * Sets value what is currently visible in editor.
	 * @param value
	 */
	public void setEditValue(Object value)
	{
		
	}
	
	/**
	 * Gets if value is modified.
	 * @return
	 */
	public boolean getIsModified()
	{	
		if(getValue() == null && getEditValue() == null){
			return false;
		}
		else if(getValue() == null && getEditValue() != null){
			return true;
		}
		else if(getValue().equals(getEditValue())){
			return false;
		}
		else{
			return true;
		}
	}
	
	
	/**
	 * Adds the specified action listener to receive action events.
	 * @param l the action listener
	 */ 
	public void addValueChangedListener(ActionListener l) 
	{
		m_pValueChangedLister.add(ActionListener.class,l);
	}

	/**
	 * Removes the specified action listener so it no longer receives action events.
	 * @param l the action listener
	 */ 
	public void removeValueChangedListener(ActionListener l) 
	{
		m_pValueChangedLister.remove(ActionListener.class,l);
	}
	
	/**
	 * Raises value changed event.
	 *
	 */
	protected void RaiseValueChanged()
	{	
		if(m_StartingEdit){
			return;
		}
	//	if(!getIsModified()){
	//		return;
	//	}		
		
		Object[] listeners = m_pValueChangedLister.getListenerList();
		// loop through each listener and pass on the event if needed		
		for(int i=0;i < listeners.length;i++){
			if(listeners[i] == ActionListener.class){
				// pass the event to the listeners event dispatch method
				((ActionListener)listeners[i + 1]).actionPerformed(new ActionEvent(this,ActionEvent.ACTION_PERFORMED,""));
			}            
		}
		
		if(m_pGridView != null){
			m_pGridView.RepaintActiveRow();
		}
	}
}
