package net.sourceforge.ganttproject.datafilter.task;

import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import javax.xml.transform.sax.TransformerHandler;

import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;

import net.sourceforge.ganttproject.datafilter.FilteringEvent;
import net.sourceforge.ganttproject.datafilter.FilteringEventListener;
import net.sourceforge.ganttproject.datafilter.TaskGroup;
import net.sourceforge.ganttproject.io.GPSaver;
import net.sourceforge.ganttproject.io.SaverBase;
import net.sourceforge.ganttproject.language.GanttLanguage;
import net.sourceforge.ganttproject.parser.GenericOptionTagHandler;
import net.sourceforge.ganttproject.parser.TagHandler;
import net.sourceforge.ganttproject.task.event.TaskDependencyEvent;
import net.sourceforge.ganttproject.task.event.TaskHierarchyEvent;
import net.sourceforge.ganttproject.task.event.TaskPropertyEvent;
import net.sourceforge.ganttproject.task.event.TaskScheduleEvent;

/**
 * This class includes common functions for all filter classes that implements FilteredTasks.
 * 
 * Created 12.2007
 * 
 * @author Joanna Muras 
 */
public abstract class FilteredTasksBase implements FilteredTasks {

    /** Filter listeners list */
    private final List<FilteringEventListener> myListenerList = new ArrayList<FilteringEventListener>();
    private final String myID;
    
    protected FilteredTasksBase(String id) {
        myID = id;
    }

    public String getName() {
        return i18n("datafilter."+myID);
    }
    
    public String getDescription() {
        return i18n("datafilter."+myID+".description");
    }
    
    public GPSaver getSaver() {
        return new SaverImpl();
    }
    
    public TagHandler getLoader() {
       return new GenericOptionTagHandler(getSettings()); 
    }
    protected String i18n(String key) {
        return GanttLanguage.getInstance().getText(key);
    }

    /**
     * Return array of task groups
     */
    public abstract TaskGroup[] getTaskGroups();

    /**
     * This methods allows classes to register for FilteringEvent
     */
    public void addFilteringEventListener(FilteringEventListener listener) {
        myListenerList.add(listener);
    }

    /**
     * This methods allows classes to unregister for FilteringEvent
     */ 
    public void removeFilteringEventListener(FilteringEventListener listener) {
        myListenerList.remove(listener);
    }

    protected void fireFilteringEvent(FilteringEvent e) {
        for (FilteringEventListener listener : myListenerList) { 
            listener.filterChanged(e);
        }
    }

    public void dependencyAdded(TaskDependencyEvent e) {}

    public void dependencyRemoved(TaskDependencyEvent e) {}

    public void taskAdded(TaskHierarchyEvent e) {
        /* Update table with task groups and repaint filterTree */
        fireFilteringEvent(new FilteringEvent(this, getTaskGroups()));
    }

    public void taskMoved(TaskHierarchyEvent e) {}

    public void taskProgressChanged(TaskPropertyEvent e) {
        /* Update table with task groups and repaint filterTree */
        fireFilteringEvent(new FilteringEvent(this, getTaskGroups()));
    }

    public void taskPropertiesChanged(TaskPropertyEvent e) {
        /* Update table with task groups and repaint filterTree */
        fireFilteringEvent(new FilteringEvent(this, getTaskGroups()));
    }

    public void taskRemoved(TaskHierarchyEvent e) {
        /* Update table with task groups and repaint filterTree */
        fireFilteringEvent(new FilteringEvent(this, getTaskGroups()));
    }

    public void taskScheduleChanged(TaskScheduleEvent e) {}
    
    public void optionsChanged() {
        /* Update table with task groups and repaint filterTree */
        fireFilteringEvent(new FilteringEvent(this, getTaskGroups()));
    }

    private class SaverImpl extends SaverBase implements GPSaver {
        public void save(OutputStream output) throws IOException {
            throw new UnsupportedOperationException();
        }

        public void save(TransformerHandler handler) throws IOException {
            AttributesImpl attrs = new AttributesImpl();
            addAttribute("id", myID, attrs);
            try {
                startElement("view", attrs, handler);
                saveOptions(getSettings(), handler);
                endElement("view", handler);
            } catch (SAXException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    }
}
