package net.sf.memoranda.ui;

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.SystemColor;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;

import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JToolBar;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.border.Border;

import jiconfont.icons.GoogleMaterialDesignIcons;
import jiconfont.swing.IconFontSwing;
import net.sf.memoranda.CurrentProject;
import net.sf.memoranda.CurrentNote;
import net.sf.memoranda.NoteListener;
import net.sf.memoranda.EventNotificationListener;
import net.sf.memoranda.EventsScheduler;
import net.sf.memoranda.History;
import net.sf.memoranda.HistoryItem;
import net.sf.memoranda.HistoryListener;
import net.sf.memoranda.Note;
import net.sf.memoranda.NoteList;
import net.sf.memoranda.Project;
import net.sf.memoranda.ProjectListener;
import net.sf.memoranda.ResourcesList;
import net.sf.memoranda.Task;
import net.sf.memoranda.TaskList;
import net.sf.memoranda.date.CalendarDate;
import net.sf.memoranda.date.CurrentDate;
import net.sf.memoranda.date.DateListener;
import net.sf.memoranda.util.ColorMap;
import net.sf.memoranda.util.Configuration;
import net.sf.memoranda.ui.dayview.DayViewPanel;
import net.sf.memoranda.util.CurrentStorage;
import net.sf.memoranda.util.Local;
import net.sf.memoranda.util.Palette;
import net.sf.memoranda.util.Util;
/**
 * 
 * Copyright (c) 2003 Memoranda Team. http://memoranda.sf.net
 */
/**
 * This class joins all the panels of memoranda's app and builds the overall gui.
 */
/*$Id: DailyItemsPanel.java,v 1.22 2005/02/13 03:06:10 rawsushi Exp $*/
public class DailyItemsPanel extends JPanel {
    BorderLayout borderLayout1 = new BorderLayout();
    JSplitPane splitPane = new JSplitPane();
    JPanel controlPanel = new JPanel(); /* Contains the calendar */
    JPanel mainPanel = new JPanel();
    BorderLayout borderLayout2 = new BorderLayout();
    JPanel statusPanel = new JPanel();
    BorderLayout borderLayout3 = new BorderLayout();
    JPanel editorsPanel = new JPanel();
    CardLayout cardLayout1 = new CardLayout();
    public EditorPanel editorPanel = new EditorPanel(this);
    JLabel currentDateLabel = new JLabel();
    BorderLayout borderLayout4 = new BorderLayout();
    TaskPanel tasksPanel = new TaskPanel(this);
    EventsPanel eventsPanel = new EventsPanel(this);
    Icon collIcon = IconFontSwing.buildIcon(GoogleMaterialDesignIcons.FIRST_PAGE, 24, ColorMap.ICON);
    Icon expIcon = IconFontSwing.buildIcon(GoogleMaterialDesignIcons.LAST_PAGE, 24, ColorMap.ICON);
    DayViewPanel dayViewPanel = new DayViewPanel(this);
    Icon bookmarkIcon = IconFontSwing.buildIcon(GoogleMaterialDesignIcons.STAR, 8, ColorMap.ICON);
    boolean expanded = true;

    Note currentNote;
      CalendarDate currentDate;

    boolean calendarIgnoreChange = false;
    boolean dateChangedByCalendar = false;
    boolean changedByHistory = false;
    JPanel cmainPanel = new JPanel();
    JNCalendarPanel calendar = new JNCalendarPanel();
    JToolBar toggleToolBar = new JToolBar();
    BorderLayout borderLayout5 = new BorderLayout();
    Border border1;
    JButton toggleButton = new JButton();
    WorkPanel parentPanel = null;
    
    boolean addedToHistory = false;
    JPanel indicatorsPanel = new JPanel();
    JButton alarmB = new JButton();
    FlowLayout flowLayout1 = new FlowLayout();
    JButton taskB = new JButton();
    JPanel mainTabsPanel = new JPanel();
    NotesControlPanel notesControlPane = new NotesControlPanel();
    CardLayout cardLayout2 = new CardLayout();
        
    JTabbedPane tasksTabbedPane = new JTabbedPane();
    JTabbedPane eventsTabbedPane = new JTabbedPane();
    JTabbedPane agendaTabbedPane = new JTabbedPane();
    Border border2;

    String CurrentPanel;
    
    Cursor waitCursor = new Cursor(Cursor.WAIT_CURSOR);
    
    public DailyItemsPanel(WorkPanel _parentPanel) {
        try {
            parentPanel = _parentPanel;
            jbInit();
        }
        catch (Exception ex) {
            new ExceptionDialog(ex);
        }
    }
    void jbInit() throws Exception {
        border1 = BorderFactory.createEtchedBorder(Color.white, Color.gray);
        border2 = BorderFactory.createEtchedBorder(Color.white, new Color(161, 161, 161));
        this.setLayout(borderLayout1);
        
        splitPane.setOrientation(JSplitPane.HORIZONTAL_SPLIT);
        splitPane.setBorder(null);
        splitPane.setDividerSize(2);
        controlPanel.setLayout(borderLayout2);
        //calendar.setMinimumSize(new Dimension(200, 170));
        mainPanel.setLayout(borderLayout3);
        editorsPanel.setLayout(cardLayout1);
        statusPanel.setBackground(Color.black);
        statusPanel.setForeground(Color.white);
        statusPanel.setMinimumSize(new Dimension(14, 24));
        statusPanel.setPreferredSize(new Dimension(14, 24));
        statusPanel.setLayout(borderLayout4);
        currentDateLabel.setFont(new java.awt.Font("Dialog", 0, 16));
        currentDateLabel.setForeground(Color.white);
        currentDateLabel.setText(CurrentDate.get().getFullDateString());
        borderLayout4.setHgap(4);
        controlPanel.setBackground(new Color(230, 230, 230));
        controlPanel.setBorder(border2);
        controlPanel.setMinimumSize(new Dimension(20, 170));
        controlPanel.setPreferredSize(new Dimension(205, 170));
        //controlPanel.setMaximumSize(new Dimension(206, 170));
        //controlPanel.setSize(controlPanel.getMaximumSize());
        calendar.setFont(new java.awt.Font("Dialog", 0, 11));
        calendar.setMinimumSize(new Dimension(0, 168));
        toggleToolBar.setBackground(new Color(215, 225, 250));
        toggleToolBar.setRequestFocusEnabled(false);
        toggleToolBar.setFloatable(false);
        cmainPanel.setLayout(borderLayout5);
        cmainPanel.setBackground(SystemColor.desktop);
        cmainPanel.setMinimumSize(new Dimension(0, 168));
        cmainPanel.setOpaque(false);
        toggleButton.setMaximumSize(new Dimension(32767, 32767));
        toggleButton.setMinimumSize(new Dimension(16, 16));
        toggleButton.setOpaque(false);
        toggleButton.setPreferredSize(new Dimension(16, 16));
        toggleButton.setBorderPainted(false);
        toggleButton.setContentAreaFilled(false);
        toggleButton.setFocusPainted(false);
        toggleButton.setMargin(new Insets(0, 0, 0, 0));
        toggleButton.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                toggleButton_actionPerformed(e);
            }
        });
        toggleButton.setIcon(collIcon);
        indicatorsPanel.setOpaque(false);
        indicatorsPanel.setLayout(flowLayout1);
        alarmB.setMaximumSize(new Dimension(24, 24));
        alarmB.setOpaque(false);
        alarmB.setPreferredSize(new Dimension(24, 24));
        alarmB.setToolTipText(Local.getString("Active events"));
        alarmB.setBorderPainted(false);
        alarmB.setMargin(new Insets(0, 0, 0, 0));
        alarmB.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                alarmB_actionPerformed(e);
            }
        });
        alarmB.setIcon(IconFontSwing.buildIcon(GoogleMaterialDesignIcons.ALARM, 24, ColorMap.ICON));
        alarmB.setBackground(ColorMap.WORKBACKGROUND);
        flowLayout1.setAlignment(FlowLayout.RIGHT);
        flowLayout1.setVgap(0);
        taskB.setMargin(new Insets(0, 0, 0, 0));
        taskB.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(ActionEvent e) {
                taskB_actionPerformed(e);
            }
        });
        taskB.setPreferredSize(new Dimension(24, 24));
        taskB.setToolTipText(Local.getString("Active to-do tasks"));
        taskB.setBorderPainted(false);
        taskB.setMaximumSize(new Dimension(24, 24));
        taskB.setOpaque(false);
        taskB.setIcon(IconFontSwing.buildIcon(GoogleMaterialDesignIcons.VIEW_LIST, 24, ColorMap.ICON));
        taskB.setBackground(ColorMap.WORKBACKGROUND);
        
        notesControlPane.setFont(new java.awt.Font("Dialog", 1, 10));
        mainTabsPanel.setLayout(cardLayout2);
        this.add(splitPane, BorderLayout.CENTER);

        controlPanel.add(cmainPanel, BorderLayout.CENTER);
        cmainPanel.add(calendar, BorderLayout.NORTH);
        mainPanel.add(statusPanel, BorderLayout.NORTH);
        statusPanel.add(currentDateLabel, BorderLayout.CENTER);
        statusPanel.add(indicatorsPanel, BorderLayout.EAST);

        mainPanel.add(editorsPanel, BorderLayout.CENTER);
        
        editorsPanel.add(dayViewPanel, "AGENDA");
        editorsPanel.add(eventsPanel, "EVENTS");
        editorsPanel.add(tasksPanel, "TASKS");
        editorsPanel.add(editorPanel, "NOTES");
        
        splitPane.add(mainPanel, JSplitPane.RIGHT);
        splitPane.add(controlPanel, JSplitPane.LEFT);
        controlPanel.add(toggleToolBar, BorderLayout.SOUTH);
        toggleToolBar.add(toggleButton, null);

        splitPane.setDividerLocation((int) controlPanel.getPreferredSize().getWidth());
       
        //splitPane.setResizeWeight(0.0);

        CurrentDate.addDateListener(new DateListener() {
            public void dateChange(CalendarDate d) {
                currentDateChanged(d);
            }
        });

        CurrentProject.addProjectListener(new ProjectListener() {
            public void projectChange(Project p, NoteList nl, TaskList tl, ResourcesList rl) {
            	currentProjectChanged(p, nl, tl, rl);
            }
            public void projectWasChanged() {

                // cannot save note here, changing to new project
                currentNote = CurrentProject.getNoteList().getNoteForDate(CurrentDate.get());
                CurrentNote.set(currentNote,false);
                editorPanel.setDocument(currentNote);        
                
            }
        });

        CurrentNote.addNoteListener(new NoteListener() {
            public void noteChange(Note note, boolean toSaveCurrentNote) {
                currentNoteChanged(note, toSaveCurrentNote);
            }
        });
        
        calendar.addSelectionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (calendarIgnoreChange)
                    return;
                dateChangedByCalendar = true;
                CurrentDate.set(calendar.get());
                dateChangedByCalendar = false;
            }
        });

        AppFrame.addExitListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                if (editorPanel.isDocumentChanged()) {
                    saveNote();
                    CurrentStorage.get().storeNoteList(CurrentProject.getNoteList(), CurrentProject.get());
                }
            }
        });

        History.addHistoryListener(new HistoryListener() {
            public void historyWasRolledTo(HistoryItem hi) {
                historyChanged(hi);
            }
        });

        EventsScheduler.addListener(new EventNotificationListener() {
            public void eventIsOccured(net.sf.memoranda.Event ev) {
                Util.debug(ev.getTimeString() + " " + ev.getText());
                updateIndicators();
            }

            public void eventsChanged() {
                updateIndicators();
            }
        });

        currentDate = CurrentDate.get();
        currentNote = CurrentProject.getNoteList().getNoteForDate(CurrentDate.get());
        CurrentNote.set(currentNote,true);
        editorPanel.setDocument(currentNote);
        History.add(new HistoryItem(CurrentDate.get(), CurrentProject.get()));
        cmainPanel.add(mainTabsPanel, BorderLayout.CENTER);
        mainTabsPanel.add(eventsTabbedPane, "EVENTSTAB");
        mainTabsPanel.add(tasksTabbedPane, "TASKSTAB");
        mainTabsPanel.add(notesControlPane, "NOTESTAB");
        mainTabsPanel.add(agendaTabbedPane, "AGENDATAB");
        updateIndicators(CurrentDate.get(), CurrentProject.getTaskList());
        mainPanel.setBorder(null);
        
        notesControlPane.notesListPanel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
                KeyStroke.getKeyStroke(KeyEvent.VK_N, Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()), "Ctrl-N");
        notesControlPane.notesListPanel.getActionMap().put("Ctrl-N", new AbstractAction(){
            @Override
            public void actionPerformed(ActionEvent e) {
                editorPanel.newAction.actionPerformed(e);
            }
        });
    }
/**
 * If the date is changed it updates the display.
 * @param newdate
 */
    void currentDateChanged(CalendarDate newdate) {
        Cursor cur = App.getFrame().getCursor();
        App.getFrame().setCursor(waitCursor);
        if (!changedByHistory) {
           History.add(new HistoryItem(newdate, CurrentProject.get()));
        }
        if (!dateChangedByCalendar) {
            calendarIgnoreChange = true;
            calendar.set(newdate);
            calendarIgnoreChange = false;
        }

        /*if ((currentNote != null) && !changedByHistory && !addedToHistory)
                            History.add(new HistoryItem(currentNote));*/
        currentNoteChanged(currentNote,true);
        currentNote = CurrentProject.getNoteList().getNoteForDate(newdate);
         CurrentNote.set(currentNote,true);
        currentDate = CurrentDate.get();

        /*addedToHistory = false;
        if (!changedByHistory) {
            if (currentNote != null) {
                History.add(new HistoryItem(currentNote));
                addedToHistory = true;
            }
        }*/

        currentDateLabel.setText(newdate.getFullDateString());
        if ((currentNote != null) && (currentNote.isMarked())) {
            currentDateLabel.setIcon(IconFontSwing.buildIcon(GoogleMaterialDesignIcons.STAR, 8, ColorMap.ICON));
            currentDateLabel.setHorizontalTextPosition(SwingConstants.LEFT);
        }
        else {
            currentDateLabel.setIcon(null);
        }        

        updateIndicators(newdate, CurrentProject.getTaskList());
        App.getFrame().setCursor(cur);
    }

    /**
     * If a note is changed it is saved and then the panel is refreshed.
     * @param note
     * @param toSaveCurrentNote
     */
    void currentNoteChanged(Note note, boolean toSaveCurrentNote) {

        if (editorPanel.isDocumentChanged()) {
            if (toSaveCurrentNote) {
                saveNote();                
            }
            notesControlPane.refresh();
        }
        currentNote = note;
        editorPanel.setDocument(currentNote);
        calendar.set(CurrentDate.get());
        editorPanel.editor.requestFocus();        
    }
    
    /**
     * If the current project is changed the display and its resources are updated.
     * @param newprj
     * @param nl
     * @param tl
     * @param rl
     */
    void currentProjectChanged(Project newprj, NoteList nl, TaskList tl, ResourcesList rl) {

        Cursor cur = App.getFrame().getCursor();
        App.getFrame().setCursor(waitCursor);
        if (!changedByHistory)
            History.add(new HistoryItem(CurrentDate.get(), newprj));
        if (editorPanel.isDocumentChanged())
            saveNote();
        /*if ((currentNote != null) && !changedByHistory && !addedToHistory)
                    History.add(new HistoryItem(currentNote));*/
        CurrentProject.save();        
        
        /*addedToHistory = false;
        if (!changedByHistory) {
            if (currentNote != null) {
                History.add(new HistoryItem(currentNote));
                addedToHistory = true;
            }
        }*/
        
        updateIndicators(CurrentDate.get(), tl);
        App.getFrame().setCursor(cur);
    }


    void historyChanged(HistoryItem hi) {
        changedByHistory = true;
        CurrentProject.set(hi.getProject());
        CurrentDate.set(hi.getDate());
        changedByHistory = false;
    }

    /**
     * Stores the current note to the noteslist under the appropriate date.
     */
    public void saveNote() {
        if (currentNote == null)
            currentNote = CurrentProject.getNoteList().createNoteForDate(currentDate);
        currentNote.setTitle(editorPanel.titleField.getText());
        currentNote.setId(Util.generateId());
        CurrentStorage.get().storeNote(currentNote, editorPanel.getDocument());
        /*DEBUG* Util.debug("Save");*/
    }

    void toggleButton_actionPerformed(ActionEvent e) {
        if (expanded) {
            expanded = false;
            toggleButton.setIcon(expIcon);
            controlPanel.remove(toggleToolBar);
            controlPanel.add(toggleToolBar, BorderLayout.EAST);
            splitPane.setDividerLocation((int) controlPanel.getMinimumSize().getWidth());

        }
        else {
            expanded = true;
            toggleButton.setIcon(collIcon);
            controlPanel.remove(toggleToolBar);
            controlPanel.add(toggleToolBar, BorderLayout.SOUTH);
            splitPane.setDividerLocation((int) controlPanel.getPreferredSize().getWidth());
        }
    }

    /**
     * Update the display for tasks and schedules based on the day and time.
     * @param date
     * @param tl
     */
    public void updateIndicators(CalendarDate date, TaskList tl) {
        indicatorsPanel.removeAll();
        if (date.equals(CalendarDate.today())) {
            if (tl.getActiveSubTasks(null,date).size() > 0)
                indicatorsPanel.add(taskB, null);
            if (EventsScheduler.isEventScheduled()) {
                /*String evlist = "";
                for (Iterator it = EventsScheduler.getScheduledEvents().iterator(); it.hasNext();) {
                    net.sf.memoranda.Event ev = (net.sf.memoranda.Event)it.next();   
                    evlist += ev.getTimeString()+" - "+ev.getText()+"\n";
                } */
                net.sf.memoranda.Event ev = EventsScheduler.getFirstScheduledEvent();
                alarmB.setToolTipText(ev.getTimeString() + " - " + ev.getText());
                indicatorsPanel.add(alarmB, null);
            }
        }
        indicatorsPanel.updateUI();

        dayViewPanel.changeDay(date);
    }

    /**
     * Update the tasks list.
     */
    public void updateIndicators() {
        updateIndicators(CurrentDate.get(), CurrentProject.getTaskList());
    }

    /**
     * Based on the panel selected refresh the GUI.
     * @param pan
     */
    public void selectPanel(String pan) {
        if (calendar.jnCalendar.renderer.getTask() != null) {
            calendar.jnCalendar.renderer.setTask(null);
         //   calendar.jnCalendar.updateUI();
        }
        if (pan.equals("TASKS") && (tasksPanel.taskTable.getSelectedRow() > -1)) {
            Task t =
                CurrentProject.getTaskList().getTask(
                    tasksPanel
                        .taskTable
                        .getModel()
                        .getValueAt(tasksPanel.taskTable.getSelectedRow(), TaskTable.TASK_ID)
                        .toString());
            calendar.jnCalendar.renderer.setTask(t);
       //     calendar.jnCalendar.updateUI();
        }
        boolean isAg = pan.equals("AGENDA");
        if (isAg)
            dayViewPanel.changeDay(CurrentDate.get());
        cardLayout1.show(editorsPanel, pan);
        cardLayout2.show(mainTabsPanel, pan + "TAB");
        calendar.jnCalendar.updateUI();
        CurrentPanel=pan;
    }

    /**
     * Return the currently being used panel.
     * @return
     */
    public String getCurrentPanel() {
        return CurrentPanel;
    }
    public void taskB_actionPerformed(ActionEvent e) {
        parentPanel.tasksB_actionPerformed(null);
    }

    void alarmB_actionPerformed(ActionEvent e) {
        parentPanel.eventsB_actionPerformed(null);
    }
    void updateIcons(){
        taskB.setIcon(IconFontSwing.buildIcon(GoogleMaterialDesignIcons.VIEW_LIST, 24, ColorMap.ICON));
        alarmB.setIcon(IconFontSwing.buildIcon(GoogleMaterialDesignIcons.ALARM, 24, ColorMap.ICON));
        collIcon = IconFontSwing.buildIcon(GoogleMaterialDesignIcons.FIRST_PAGE, 24, ColorMap.ICON);
        expIcon = IconFontSwing.buildIcon(GoogleMaterialDesignIcons.LAST_PAGE, 24, ColorMap.ICON);
        if (expanded) {
            toggleButton.setIcon(collIcon);
        }
        else {
            toggleButton.setIcon(expIcon);
        }
    }
}