/*
 * TimeTableModel.java
 *
 * Created on 26. listopad 2000, 17:37
 */

package timetable.gui;

import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;
import java.awt.event.*;
import timetable.data.*;
import timetable.util.*;

/**
 *
 * @author  Administrator
 * @version 
 */
public class TimeTableModel extends AbstractTableModel implements TableCellEditor, TableCellRenderer, ActionListener{
    JTextArea textArea;
    JPopupMenu menu;
    JCheckBoxMenuItem menuPin;
    public int menuRow, menuColumn;
    public static javax.swing.border.MatteBorder BORDER_PIN = new javax.swing.border.MatteBorder(2,2,2,2,java.awt.Color.red);
    public static javax.swing.border.MatteBorder BORDER_PIN_NL = new javax.swing.border.MatteBorder(2,0,2,2,java.awt.Color.red);
    public static javax.swing.border.MatteBorder BORDER_PIN_NR = new javax.swing.border.MatteBorder(2,2,2,0,java.awt.Color.red);
    public static javax.swing.border.MatteBorder BORDER_PIN_NLR = new javax.swing.border.MatteBorder(2,0,2,0,java.awt.Color.red);
    public static Color COLOR_DEFAULT = new Color(255,255,255);
    public static Color COLOR_SELECTED = new Color(130,130,255);
    public static Color COLOR_NULL = new Color(200,200,200);
    public static Color TEXT_NORMAL = new Color(0,0,0);
    public static Color TEXT_PIN = new Color(100,0,50);
    public static Color BG_HARD = new Color(210,150,150);
    public static Color BG_SOFT = new Color(200,200,150);
    public static Color BG_SCH_SOFT = new Color(255,255,200);
    public static Color BORDER_COLOR = new Color(0,0,0);
    public static javax.swing.border.MatteBorder BORDER_NONE = new javax.swing.border.MatteBorder(0,0,1,0,BORDER_COLOR);
    public static javax.swing.border.MatteBorder BORDER_RIGHT = new javax.swing.border.MatteBorder(0,0,1,1,BORDER_COLOR);

    
/*    public int selectedColumn;
    public int selectedRow;*/
    
    public ResourceGroup resources = null;
    private Config config = null;
    private int columns =0;
    private int rows=0;
    private int slotsPerDay =0;
    private TimeTableTable table=null;

    /** Creates new TimeTableModel */
    public TimeTableModel(Config config, ResourceGroup resources) throws TimetableException {
        this.config = config;
        this.resources = resources;
        rows = resources.size();
        config.getInt(Config.NR_DAYS);
        columns = config.getInt(Config.NR_SLOTS);
        slotsPerDay = config.getInt(Config.NR_SLOTS)/config.getInt(Config.NR_DAYS);
        textArea = new JTextArea();
        textArea.setEditable(false);
        textArea.setBackground(COLOR_DEFAULT);
        textArea.setAlignmentX(Component.CENTER_ALIGNMENT);
        textArea.setAlignmentY(Component.CENTER_ALIGNMENT);
        menu = new JPopupMenu();
        menuPin = new JCheckBoxMenuItem(Loc.get("timetable.gui.pin"));
        menuPin.addActionListener(this);
        menu.add(menuPin);
    }
    
    public void setConfig(Config config) throws TimetableException{
        this.config=config;
        rows = resources.size();
        config.getInt(Config.NR_DAYS);
        columns = config.getInt(Config.NR_SLOTS);
        slotsPerDay = config.getInt(Config.NR_SLOTS)/config.getInt(Config.NR_DAYS);
    }

    public void addMenuItem(JMenuItem item) {
      menu.add(item);
    }
    
    public void addMenuSeparator() {
        menu.add(new javax.swing.JPopupMenu.Separator());
    }
    
    public void setTable(TimeTableTable _table) {
        this.table=_table;
        table.addMouseListener(new java.awt.event.MouseAdapter() {
                    public void mouseClicked(java.awt.event.MouseEvent e) {
                        table.updateUI();
                        java.awt.Point p = new java.awt.Point(e.getX(),e.getY());
                        if ((e.getModifiers()&e.BUTTON3_MASK)>0 && isCellEditable(table.rowAtPoint(p),table.columnAtPoint(p))) {                           
                            menuRow=table.rowAtPoint(p);
                            menuColumn=table.columnAtPoint(p);
                            menuPin.setSelected(getPinAt(menuRow,menuColumn));
                            menu.show(table,e.getX(),e.getY());
                        };
/*                        if (table.getSelectedColumn()<0 && table.getSelectedRow()<0) return ;
                        if ((e.getModifiers()&e.BUTTON3_MASK)>0 && isCellEditable(table.getSelectedRow(),table.getSelectedColumn())) {
                            menuPin.setSelected(getPinAt(table.getSelectedRow(),table.getSelectedColumn()));
                            menu.show(table,e.getX(),e.getY());
                        };*/
                    }
                });
    }
    
    public Activity getSelectedActivity() {
        int r = table.getSelectedRow();
        int c = table.getSelectedColumn();
        if (r<0 || c<=0) return null;
        return resources.get(r).getActivityAt(c-1);
    }
    
    public void setResources(ResourceGroup resources) {
        this.resources=resources;
        rows = resources.size();
    }
       
    public String getColumnName(int column) {
        try {
          return (column==0?Loc.get("timetable.resource"):config.dayOfWeek(column-1)+" "+((column-1)%slotsPerDay+1));
        } catch (TimetableException e) {
            System.err.println("Error: "+e);
            e.printStackTrace();
        }
        return "Unknown";
    }

    public int getRowCount() {
        return rows;
    }
    
    public int getColumnCount() {
         return columns+1;
    }
    
    public Activity getActivityAt(int row, int column) {
        if (resources==null) return null;
        if (column==0) return null;
        return resources.get(row).getActivityAt(column-1);
    }
    
    public Object getValueAt(int row, int column) {
        if (resources==null) return null;
        if (column==0) return resources.get(row).shortCut;
        if (resources.get(row).getActivityAt(column-1)!=null) {
            Resource res = resources.get(row);
            Activity a = res.getActivityAt(column-1);
            if (a.start!=column-1) return "";
            java.lang.StringBuffer r=new java.lang.StringBuffer();
//            if (getPinAt(row,column)) r.append(">");
            r.append(a.shortCut);
//            if (getPinAt(row,column)) r.append("<");
            for (int i=0;i<a.selectedResources.size();i++)
                if (a.selectedResources.isGroup(i)) {
                    boolean isIn = false;
                    for (int k=0;k<a.selectedResources.getResources(i).size() && !isIn;k++)
                        if (a.selectedResources.getResources(i).get(k)==res) isIn=true;
                    if (!isIn) r.append("\n").append(a.selectedResources.getResources(i).toString());
                } else {
                    if (a.selectedResources.getResource(i)!=res) 
                        r.append("\n").append(a.selectedResources.getResource(i).shortCut);
                };
            return r.toString();
        } else return null;
    }
    
    public boolean getPinAt(int row, int column) {
        if (resources==null || column==0) return false;
        if (resources.get(row).getActivityAt(column-1)!=null) {
            return !resources.get(row).getActivityAt(column-1).canReschedule;
        } else return false;
    }
    
    public void setPinAt(int row, int column, boolean pin) {
        if (resources==null || column==0) return;
        if (resources.get(row).getActivityAt(column-1)!=null) {
            resources.get(row).getActivityAt(column-1).canReschedule=!pin;
        } else return;
    }
       
    public boolean isCellEditable(int row, int column) {
        if (resources==null || column==0) return false;
        return (resources.get(row).getActivityAt(column-1)!=null);
    }
      
    public Class getColumnClass(int c) { return String.class; }

    public Component getTableCellEditorComponent(JTable table, Object value,
						 boolean isSelected,
						 int row, int column) {return null;}
    
    public void cancelCellEditing() {}
    
    public boolean stopCellEditing() {return true;}
    
    public java.lang.Object getCellEditorValue() {return textArea.getText(); }
    
    public boolean shouldSelectCell(final java.util.EventObject p1) { 
        return true; 
    }
       
    public boolean isCellEditable(final java.util.EventObject anEvent) {
        return false;
/*	    if (anEvent instanceof MouseEvent) { 
                if (((MouseEvent)anEvent).getClickCount() >= 2) {
                    menu.show(((MouseEvent)anEvent).getComponent(),((MouseEvent)anEvent).getX(),((MouseEvent)anEvent).getY());
                }
	    }
	    return false;*/
    }
        
    public java.awt.Component getTableCellRendererComponent(JTable table, Object value,
						 boolean isSelected,boolean hasFocus,
						 int row, int column) {
        textArea.setText((value != null) ? value.toString() : "");
        textArea.setBorder(BORDER_RIGHT);
        if (column==0) {
            textArea.setBackground(COLOR_SELECTED);
            return textArea;
        }
        if (resources==null) return null;
        Resource r = resources.get(row);
        Activity a = r.getActivityAt(column-1);
        int soft=0;
        textArea.setToolTipText(null);
        if (a!=null) {
                    for (int i=0;i<a.length;i++) {
                        int s=a.start+i;
                        if (a.getPreference().isSOFT(s)) soft++;
                        for (int j=0;j<a.selectedResources.size();j++)
                            if (a.selectedResources.isGroup(j)) 
                                for (int k=0;k<a.selectedResources.getResources(j).size();k++) {
                                    if (a.selectedResources.getResources(j).get(k)!=null && a.selectedResources.getResources(j).get(k).getPreference().isSOFT(s)) soft++;
                                }
                            else
                                if (a.selectedResources.getResource(j)!=null && a.selectedResources.getResource(j).getPreference().isSOFT(s)) soft++;
                    };
                    textArea.setToolTipText(a.name);
        }
        if (value==null) {
            if (r.getPreference().isHARD(column-1)) textArea.setBackground(BG_HARD);  
            else if (r.getPreference().isSOFT(column-1)) textArea.setBackground(BG_SOFT);    
            else textArea.setBackground(COLOR_NULL);          
        } else {             
            if (hasFocus || a==getSelectedActivity()) textArea.setBackground(COLOR_SELECTED);            
            else if (soft>0) textArea.setBackground(new Color(255,255,timetable.util.Math.max2(0,255-30*soft)));
            else textArea.setBackground(COLOR_DEFAULT); 
            if (a!=null) {
                if (a.start+a.length==column) textArea.setBorder(BORDER_RIGHT);
                else textArea.setBorder(BORDER_NONE);
            }
        }
        if (this.getPinAt(row,column)) {
            if (a!=null) {
                if (a.length==1) textArea.setBorder(BORDER_PIN); 
                else if (a.start+1!=column && a.start+a.length==column) textArea.setBorder(BORDER_PIN_NL); 
                else if (a.start+1==column && a.start+a.length!=column) textArea.setBorder(BORDER_PIN_NR); 
                else textArea.setBorder(BORDER_PIN_NLR); 
            }
        }//setForeground(TEXT_PIN);
        //else textArea.setForeground(TEXT_NORMAL); 
        if (hasFocus) menuPin.setSelected(this.getPinAt(row,column));
        return textArea;
    }
    
    public void addCellEditorListener(final javax.swing.event.CellEditorListener p1) { }
    
    public void removeCellEditorListener(final javax.swing.event.CellEditorListener p1) { }
    
    public void actionPerformed(final java.awt.event.ActionEvent p1) {
        if (p1.getSource()==this.menuPin) {
            Activity a = resources.get(menuRow).getActivityAt(menuColumn-1);
            a.canReschedule=!a.canReschedule;
            this.table.updateUI();
       };
    }   
            
}
