package net.sourceforge.ganttproject.gui.taskproperties;

import java.math.BigDecimal;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;

import net.sourceforge.ganttproject.gui.options.model.DefaultStringOption;
import net.sourceforge.ganttproject.gui.options.model.GPOption;
import net.sourceforge.ganttproject.gui.options.model.ValidationException;
import net.sourceforge.ganttproject.gui.options.model.WritableStateHint;
import net.sourceforge.ganttproject.gui.taskproperties.TaskScheduleFields.StartDateOption;
import net.sourceforge.ganttproject.task.Task;
import net.sourceforge.ganttproject.task.TaskMutator;
import net.sourceforge.ganttproject.task.TaskPrice;

public abstract class TaskCostFields {
	final GPOption cost = new costOption();
	final GPOption calcCost = new calcCostOption();
	protected boolean isAuto = false;
	
	protected abstract Task getTask();
	protected abstract TaskMutator getMutator();
	protected abstract void apply();
	
	class costOption extends DefaultStringOption {
	 	
		public costOption()
		{
			super("taskProperties.main.manualcost");
			addHint(WritableStateHint.class, new WritableStateHint() {
                public boolean isWritable() {
                	System.err.println("Man is writable ?");
                    return !isAuto;
                }

                public void setWritable(boolean isWritable) {
                	isAuto = !isWritable;
                	System.err.println("Man is writable à " + isWritable);
                	costOption.this.setWritable(isWritable);
                	if (!isWritable)
                		onManualLocked();
                }

				public IStatus trySetWritable(boolean isWritable) {
                    return false==isWritable ? Status.OK_STATUS : Status.CANCEL_STATUS;
                }
            });
		}
		
		@Override
		public void setValue(String value) {
			try {
				new BigDecimal(value);
				myValue = value;
			}
			catch(NumberFormatException e) {
				throw new ValidationException("", e);
			}
			super.setValue(value);
		}
		
		private String myValue = "0";

		@Override
		public String getValue()
		{
			return getTask().getPrice().getPrice().toPlainString();
		}
		
		@Override
		public void commit() {
			super.commit();
            if (getValue()!=null) {
            	TaskPrice p = new TaskPrice(getTask());
            	p.setPrice(new BigDecimal(Integer.parseInt((myValue))));
                getMutator().setCost(p);
            }
		}      
    }

	class calcCostOption extends DefaultStringOption
	{
		public calcCostOption()
		{
			super("taskProperties.main.calculatedcost");
			addHint(WritableStateHint.class, new WritableStateHint() {
                public boolean isWritable() {
                	System.err.println("Auto is writable ?");
                    return isAuto;
                }

                public void setWritable(boolean isWritable) {
                	isAuto = isWritable;
                	calcCostOption.this.setWritable(isWritable);
                	System.err.println("Auto is writable à " + isWritable);
                    if (!isWritable)
                        onCalcLocked();
                    else
                    	calcCostOption.this.setWritable(false);
                }

				public IStatus trySetWritable(boolean isWritable) {
                    return false==isWritable ? Status.OK_STATUS : Status.CANCEL_STATUS;
                }
            });
		}
		
		@Override
		public String getValue()
		{
			return getTask().getPrice().getPrice().toPlainString();
		}    
    }
	
	private void onManualLocked()
	{
		calcCost.setWritable(true);
		cost.setWritable(false);
		apply();
	}
	
	private void onCalcLocked()
	{
    	cost.setWritable(true);
    	apply();
	}
	
	public TaskCostFields()
	{
        calcCost.setWritable(false);
	}	
}
