/*
 * GDefaultCalendarEventSelectionModel.java
 * 
 * Tide project - Timeline and Schedule. 
 * Reusable GUI components 
 * 
 * To Do:
 * - feature3
 * - feature4
 * Done:
 * - feature1,2 nimmari 15.11.1999
 * - feature5   nimmari  1.12.1999
 */

package fi.helsinki.cs.gist.schedule;

import fi.helsinki.cs.gist.schedule.GDateUtils;

import java.util.Vector;
import java.util.Calendar;
import java.util.Date;
import java.util.Enumeration;
import javax.swing.event.EventListenerList;

/**
 * GDefaultCalendarEventSelectionModel
 *
 */

public class GDefaultCalendarEventSelectionModel 
  implements GCalendarEventSelectionModel {
    
    protected Vector selectedEvents = new Vector();
    protected Vector selectionDays = new Vector();

    protected EventListenerList listenerList = null; 
    protected GCalendarEventSelectionModelEvent modelEvent = null;


    public GDefaultCalendarEventSelectionModel() {
      this.listenerList = new EventListenerList();
      this.modelEvent = new GCalendarEventSelectionModelEvent(this);
    }
    

    ///////////////////
    // Public methods
    ///////////////////
    
    public Vector getSelectedEvents(){
      return selectedEvents;
    }

    public Vector getSelectionDays() {
      return selectionDays;
    }
    

    public void addSelectedEvent(GCalendarEvent aCalendarEvent) {
     System.out.println("adding selection");
      if(! selectedEvents.contains(aCalendarEvent) ) {
	selectedEvents.add(aCalendarEvent);
      }
      Date start = aCalendarEvent.getStartTime();
      Date end = aCalendarEvent.getEndTime();
      addDay(start);
      if( GDateUtils.compareDays(start,end) != 0) {
	addDay(end);
      }
      fireCalendarEventSelectionModelChanged();
    }
      
    
    public void setSelectedEvent(GCalendarEvent aCalendarEvent){
     System.out.println("setting selection");
	selectedEvents.clear();
	selectionDays.clear();

	selectedEvents.add(aCalendarEvent);
	Date start = aCalendarEvent.getStartTime();
	Date end = aCalendarEvent.getEndTime();
	addDay(start);
	if( GDateUtils.compareDays(start,end) != 0) {
	  addDay(end);
	}

	System.out.println("selectEvents #" + selectedEvents.size() );
	System.out.println("selectionDays #" + selectionDays.size() );
	fireCalendarEventSelectionModelChanged();

      
    }
    
    public void removeSelectedEvent(GCalendarEvent aCalendarEvent) {
      boolean didContain = selectedEvents.remove(aCalendarEvent);
      if(didContain) {
	selectionDays.clear();
	for(Enumeration e=selectedEvents.elements(); e.hasMoreElements(); ) {
	  GCalendarEvent selEve = (GCalendarEvent) e.nextElement();
	  
	  Date start = selEve.getStartTime();
	  Date end = selEve.getEndTime();
	  addDay(start);
	  if( GDateUtils.compareDays(start,end) != 0) {
	    addDay(end);
	  }
	}
	fireCalendarEventSelectionModelChanged();
      }
    }

    public boolean contains(GCalendarEvent calEvent) {
      return selectedEvents.contains(calEvent);
    }


    ////////////////////////
    // Implementation
    /////////////////////////


    protected void addDay(Date day) {
      for(Enumeration e=selectionDays.elements(); e.hasMoreElements(); ) {
 	Date selectionDay = (Date) e.nextElement();
	if( GDateUtils.compareDays(selectionDay, day) == 0) {
	  return;
	}
      }

      selectionDays.addElement(day);
    }
      
      
    //////////////////////////
    // Listener handling
    //////////////////////////

    
    public void addCalendarEventSelectionModelListener(GCalendarEventSelectionModelListener l){
      listenerList.add(GCalendarEventSelectionModelListener.class, l);
    }
    
    public void removeCalendarEventSelectionModelListener(GCalendarEventSelectionModelListener l) {
      listenerList.remove(GCalendarEventSelectionModelListener.class, l);
    }
    
    protected void fireCalendarEventSelectionModelChanged() {
      System.out.println("FIRING");

      // Guaranteed to return a non-null array
      Object[] listeners = listenerList.getListenerList();
      System.out.println("Listener count"+listeners.length);
      // Process the listeners last to first, notifying
      // those that are interested in this event
      for (int i = listeners.length-2; i>=0; i-=2) {
	if (listeners[i]==GCalendarEventSelectionModelListener.class) {
	  // Lazily create the event:
	  if (modelEvent == null)
	    modelEvent = new GCalendarEventSelectionModelEvent(this);
	  ((GCalendarEventSelectionModelListener)
	   listeners[i+1]).calendarEventSelectionModelChanged(modelEvent);
	}
      }
    }
    
}
