/*
 * DNDActivityEngine.java
 *
 * Created on 25. únor 2001, 8:48
 */

package timetable.gui;

/**
 *
 * @author  Administrator
 * @version 
 */
import timetable.data.*;
import timetable.solver.*;
import timetable.school.gui.*;

public class DNDActivityEngine implements DNDTableEngine {
    private Activity dActivity = null;
    private javax.swing.JTable dSource = null;
    private Solver solver=null;
    private Problem problem=null;

    /** Creates new DNDActivityEngine */
    public DNDActivityEngine(Problem problem,Solver solver) {
        this.problem=problem;
        this.solver=solver;
    }
    
    public boolean canDrag(int row,int column,javax.swing.JTable source) {
        if (source.getModel() instanceof TimeTableModel) {
            boolean ret = ((TimeTableModel)source.getModel()).getActivityAt(row,column)!=null;
//            System.out.println("canDrag(row="+row+",column="+column+")="+ret);
            return ret;
        }
        if (source instanceof DNDDataTable) {
            boolean ret = row>=0;
//            System.out.println("canDrag(row="+row+",column="+column+")="+ret);
            return ret;
        }
//        System.out.println("canDrag(row="+row+",column="+column+")=false (source.getModel()!=TimeTableModel)");
        return false;
    }
    
    public boolean canDrag(int slot, Activity a, Resource r) {
        return (a!=null);
    }    
    
    public void drag(int row,int column,javax.swing.JTable source) {
//        System.out.println("drag(row="+row+",column="+column+")");
        if (source.getModel() instanceof TimeTableModel) {
            dActivity=((TimeTableModel)source.getModel()).getActivityAt(row,column);
//            System.out.println("  dActivity="+dActivity.shortCut);
        }
        if (source instanceof DNDDataTable) {
            dActivity=((ActivityModelInterface)source.getModel()).getActivities().get(row);
        }
        dSource = source;
        fireDNDListenerDrag(source,row,column);
    }
    
    public void drag(int slot, Activity a, Object source) {
//        System.out.println("drag(slot="+slot+")");
        dActivity=a;
//        System.out.println("  dActivity="+dActivity.shortCut);
        dSource = null;
        fireDNDListenerDrag(source,slot);
    }

    public boolean canDrop(int row,int column,javax.swing.JTable target) {
        if (target.getModel() instanceof TimeTableModel) {
            TimeTableModel m = (TimeTableModel)target.getModel();
            if (m.resources==null || column==0) {
//                System.out.println("canDrop(row="+row+",column="+column+")=false (m.resources==null || column==0)");
                return false;
            }
            try {
              boolean ret=dActivity.resources.contains(m.resources.get(row))>=0 && m.resources.get(row).canBeFreeAt(column-1,dActivity.length) && dActivity.canScheduleAt(column-1,problem.dependences);
//              System.out.println("canDrop(row="+row+",column="+column+")="+ret);
              return ret;
            } catch (Exception e) { 
                System.err.println("canDrop(row="+row+",column="+column+")=false (exception "+e.getMessage()+")");
                return false;
            };
        } else if (target instanceof DNDDataTable) {
//              System.out.println("canDrop(row="+row+",column="+column+")=true");
              return true;
        } else {
//            System.out.println("canDrop(row="+row+",column="+column+")=false (target.getModel!=TimeTableModel)");
            return false;
        }
    }
    
    public boolean canDrop(int slot, Activity a, Resource r) {
            try {
              boolean ret=dActivity.resources.contains(r)>=0 && r.canBeFreeAt(slot,dActivity.length) && dActivity.canScheduleAt(slot,problem.dependences);
//              System.out.println("canDrop(slot="+slot+")="+ret);
              return ret;
            } catch (Exception e) { 
                System.err.println("canDrop(slot="+slot+")=false (exception "+e.getMessage()+")");
                return false;
            }
    }
    
    public void drop(int row,int column,javax.swing.JTable target) {
//        System.out.println("drop(row="+row+",column="+column+")");
        if (dSource==null) {
            dActivity.remove(dActivity);
        }
//        if (!canDrop(row,column,target)) return;
        else if (dSource.getModel() instanceof TimeTableModel && target.getModel() instanceof TimeTableModel) {
            TimeTableModel m = (TimeTableModel)target.getModel();
            Resource resource = m.resources.get(row);
            ActivityResources selectedResources=(ActivityResources)dActivity.selectedResources.clone();
            int start = dActivity.start;
//            System.out.println("  new resource="+resource.shortCut);
            dActivity.remove(dActivity);
//            System.out.println("  activity removed");
            boolean ret=false;
            try {
//              problem.config.set("DEBUG",1);
              ret=solver.schedule(dActivity,column-1,resource);
              if (!ret) {
                  dActivity.schedule(start,selectedResources);
              }
//              problem.config.set("DEBUG",0);
            } catch (Exception e) {
                System.err.println("  exception "+e.getMessage());
            }
//            System.out.println("  scheduled at "+dActivity.start+", return status="+ret);
//            System.out.println("  new resources="+dActivity.selectedResources.toString());
        } else if (dSource.getModel() instanceof TimeTableModel && target instanceof DNDDataTable) {
            dActivity.remove(dActivity);
        } else if (dSource instanceof DNDDataTable && target.getModel() instanceof TimeTableModel) {
            TimeTableModel m = (TimeTableModel)target.getModel();
            Resource resource = m.resources.get(row);
//            System.out.println("  new resource="+resource.shortCut);
            boolean ret=false;
            try {
//              problem.config.set("DEBUG",1);
              ret=solver.schedule(dActivity,column-1,resource);
//              problem.config.set("DEBUG",0);
            } catch (Exception e) {
                System.err.println("  exception "+e.getMessage());
            }
//            System.out.println("  scheduled at "+dActivity.start+", return status="+ret);
//            System.out.println("  new resources="+dActivity.selectedResources.toString());
        }; //else {System.out.println("  nothing to do");};
        fireDNDListenerDrop(target,row,column);
    }
    
    public void drop(int slot, Resource r, Object source) {
        if (dActivity.isScheduled()) {
            ActivityResources selectedResources=(ActivityResources)dActivity.selectedResources.clone();
            int start = dActivity.start;
//            System.out.println("  new resource="+r.shortCut);
            dActivity.remove(dActivity);
//            System.out.println("  activity removed");
            boolean ret=false;
            try {
              ret=solver.schedule(dActivity,slot,r);
              if (!ret) {
                  dActivity.schedule(start,selectedResources);
              }
            } catch (Exception e) {
                System.err.println("  exception "+e.getMessage());
            }
//            System.out.println("  scheduled at "+dActivity.start+", return status="+ret);
//            System.out.println("  new resources="+dActivity.selectedResources.toString());
        } else {
//            System.out.println("  new resource="+r.shortCut);
            try {
              solver.schedule(dActivity,slot,r);
            } catch (Exception e) {
                System.err.println("  exception "+e.getMessage());
            }
        }        
        fireDNDListenerDrop(source,slot);
    }
        
    public void done() {
//        System.out.println("done()");
        dActivity = null;
    }
    
    protected java.util.Vector listenerList = new java.util.Vector();
    
    public void addDNDListener(DNDListener l) {
        listenerList.add(l);
    }
    
    public void removeDNDListener(DNDListener l) {
        listenerList.remove(l);
    }
    
    protected void fireDNDListenerDrop(Object source, int slot) {
        DNDEvent dndEvent = null;
        for (int i = listenerList.size()-1; i>=0; i--) {
             if (dndEvent == null)
                 dndEvent = new DNDEvent(source,slot);
             ((DNDListener)listenerList.get(i)).drop(dndEvent);
        }
    }

    protected void fireDNDListenerDrag(Object source, int slot) {
        DNDEvent dndEvent = null;
        for (int i = listenerList.size()-1; i>=0; i--) {
             if (dndEvent == null)
                 dndEvent = new DNDEvent(source,slot);
             ((DNDListener)listenerList.get(i)).drag(dndEvent);
        }
    }    

    protected void fireDNDListenerDrop(Object source, int row, int column) {
        DNDEvent dndEvent = null;
        for (int i = listenerList.size()-1; i>=0; i--) {
             if (dndEvent == null)
                 dndEvent = new DNDEvent(source,row,column);
             ((DNDListener)listenerList.get(i)).drop(dndEvent);
        }
    }

    protected void fireDNDListenerDrag(Object source, int row, int column) {
        DNDEvent dndEvent = null;
        for (int i = listenerList.size()-1; i>=0; i--) {
             if (dndEvent == null)
                 dndEvent = new DNDEvent(source,row,column);
             ((DNDListener)listenerList.get(i)).drag(dndEvent);
        }
    }    
}
