/* -*- Mode: java; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */

package com.danger.terminal;

import danger.app.ComponentVersion;
import danger.app.Event;
import danger.app.Timer;
import danger.ui.AlertWindow;
import danger.ui.DialogWindow;
import danger.ui.Menu;
import danger.ui.ScreenWindow;
import danger.ui.StaticTextBox;
import danger.util.format.StringFormat;
import java.util.Calendar;


public class SessionListWindow
    extends ScreenWindow
    implements TerminalResources, TerminalEvents
{

    public SessionListWindow()
    {
        super();

        new Timer(1000*3600, true, this).start();
    }

    public void
    init (SessionManager manager, TerminalScreen terminal)
    {
        mMe = this;
        mTerminal = terminal;

        mSessionManager = manager;
        mListView = (SessionListView) getDescendantWithID(ID_SESSION_LIST_VIEW);
        mListView.init(manager);
        mListView.setAutoResize(false);
        mListView.setHasBorder(false);

        deactivateMenu();
    }

    public void
    onDecoded ()
    {
        Calendar today = Calendar.getInstance();
        int month = today.get(Calendar.MONTH);
        int day = today.get(Calendar.DAY_OF_MONTH);

        setIcon(getApplication().getBundle().getSmallIcon());

        if (month == Calendar.JANUARY) {
            if (day == 26) {
                setIcon(getApplication().getBitmap(ID_AUS_ICON));
            }
        } else if (month == Calendar.FEBRUARY) {
            if (day == 6) {
                // missing NZ flag
            }
        } else if (month == Calendar.MARCH) {
            if (day == 1) {
                setIcon(getApplication().getBitmap(ID_WALES_ICON));
            } else if (day == 17) {
                setIcon(getApplication().getBitmap(ID_NIRELAND_ICON));
            }
        } else if (month == Calendar.APRIL) {
            if (day == 23) {
                setIcon(getApplication().getBitmap(ID_ENGLAND_ICON));
            }
        } else if (month == Calendar.MAY) {
            if (day == 5) {
                setIcon(getApplication().getBitmap(ID_CINCO_ICON));
            }
        } else if (month == Calendar.JULY) {
            if (day == 1) {
                setIcon(getApplication().getBitmap(ID_CANADA_ICON));
            } else if (day == 4) {
                setIcon(getApplication().getBitmap(ID_IND_ICON));
            } else if (day == 14) {
                setIcon(getApplication().getBitmap(ID_BASTILLE_ICON));
            }
        } else if (month == Calendar.AUGUST) {
            if (day == 1) {
                // swiss confederation day
            }
        } else if (month == Calendar.SEPTEMBER) {
            if (day == 19) {
                setIcon(getApplication().getBitmap(ID_PIRATE_ICON));
            }
        } else if (month == Calendar.OCTOBER) {
            if (day == 3) {
                setIcon(getApplication().getBitmap(ID_DEUTSCH_ICON));
            } else if (day == 26) {
                // interestingly, austria day is the day the USSR left in 1955
                setIcon(getApplication().getBitmap(ID_AUSTRIA_ICON));
            }                
        } else if (month == Calendar.NOVEMBER) {
            if (day == 30) {
                setIcon(getApplication().getBitmap(ID_SCOTLAND_ICON));
            }
        }
    }

    /**
     * Deactivate the action menu (done when there are no entries left).
     */
    public void
    deactivateMenu ()
    {
        Menu menu = getActionMenu();
        menu.removeAllItems();
        menu.addFromResource(Terminal.instance().getResources(), ID_EMPTY_MENU, this);
    }
    
    public void
    enableDelete (boolean enable)
    {
        Menu menu = getActionMenu();
        menu.getItemWithID(ID_DELETE_SERVER).setEnabled(enable);
    }
    
    public void
    useServerMenu ()
    {
        Menu menu = getActionMenu();
        menu.removeAllItems();
        menu.addFromResource(Terminal.instance().getResources(), ID_SERVER_MENU, this);
    }
    
    public void
    useSessionMenu ()
    {
        Menu menu = getActionMenu();
        menu.removeAllItems();
        menu.addFromResource(Terminal.instance().getResources(), ID_SESSION_MENU, this);
    }

    public void
    useMoveMenu ()
    {
        Menu menu = getActionMenu();
        menu.removeAllItems();
        menu.addFromResource(Terminal.instance().getResources(), ID_MOVE_MENU, this);        
    }
    
    public void
    adjustActionMenuState (Menu menu)
    {
        menu.getItemWithID(ID_NEW_SERVER).setEnabled(! mSessionManager.hostListIsFull());
    }

    public boolean
    eventShortcut (char c, Event e)
    {
        switch (c) {
        case 'v':
            showAbout();
            return true;
        case '1':
            setIcon(getApplication().getBitmap(ID_IND_ICON));
            return true;
        case '2':
            setIcon(getApplication().getBitmap(ID_BASTILLE_ICON));
            return true;
        case '3':
            setIcon(getApplication().getBitmap(ID_CANADA_ICON));
            return true;
        case '4':
            setIcon(getApplication().getBitmap(ID_AUS_ICON));
            return true;
        case '5':
            setIcon(getApplication().getBitmap(ID_DEUTSCH_ICON));
            return true;
        case '6':
            setIcon(getApplication().getBitmap(ID_CINCO_ICON));
            return true;
        case '7':
            setIcon(getApplication().getBitmap(ID_AUSTRIA_ICON));
            return true;
        case '!':
            setIcon(getApplication().getBitmap(ID_ENGLAND_ICON));
            return true;
        case '\\':
            setIcon(getApplication().getBitmap(ID_SCOTLAND_ICON));
            return true;
        case '#':
            setIcon(getApplication().getBitmap(ID_WALES_ICON));
            return true;
        case '$':
            setIcon(getApplication().getBitmap(ID_NIRELAND_ICON));
            return true;
        case '%':
            setIcon(getApplication().getBitmap(ID_PIRATE_ICON));
            return true;
        case '0':
            setIcon(getApplication().getBundle().getSmallIcon());
            return true;
        }

        return super.eventShortcut(c, e);
    }

    public final boolean
    eventWidgetUp (int widget, Event event)
    {
        if (super.eventWidgetUp(widget, event)) {
            return true;
        }
        
        switch (widget) {
        case Event.DEVICE_BUTTON_CANCEL:
        case Event.DEVICE_BUTTON_BACK:
            getApplication().returnToLauncher();
            return true;
        }
        
        return false;
    }
    
    public boolean
    eventKeyDown (char c, Event event)
    {
        if (((int) c ^ FONT_MAX) == FONT_SIZES[mFontCycle]) {
            mFontCycle++;
            if (mFontCycle == 6) {
                Terminal.instance().setBoring(false);
            } else if (mFontCycle >= FONT_SIZES.length) {
                mFontCycle = 0;
                Terminal.instance().setBoring(true);
            }
            return true;
        }
        
        mFontCycle = 0;
        return super.eventKeyDown(c, event);
    }

    private void
    switchToFirstConsole ()
    {
        TerminalConsole console = mSessionManager.consoleAt(0);
        if (console != null) {
            mTerminal.switchToConsole(console);
            mTerminal.show();
        }
    }

    private void
    switchToLastConsole ()
    {
        TerminalConsole console = mSessionManager.consoleAt(-1);
        if (console != null) {
            mTerminal.switchToConsole(console);
            mTerminal.show();
        }
    }

    public boolean
    eventWidgetDown (int widget, Event event)
    {
        switch (widget) {
        case Event.DEVICE_ARROW_RIGHT:
            if (event.modifiers == Event.EVENT_MODIFIER_MENU_BUTTON) {
                switchToFirstConsole();
                return true;
            }
            break;
        case Event.DEVICE_BUTTON_RIGHT_SHOULDER:
            switchToFirstConsole();
            return true;
        case Event.DEVICE_ARROW_LEFT:
            if (event.modifiers == Event.EVENT_MODIFIER_MENU_BUTTON) {
                switchToLastConsole();
                return true;
            }
            break;
        case Event.DEVICE_BUTTON_LEFT_SHOULDER:
            switchToLastConsole();
            return true;
        }

        return super.eventWidgetDown(widget, event);
    }

    public boolean
    receiveEvent (Event e)
    {
        AlertWindow alert;
        ConnectDialog dialog;
        SessionListItem item;
        
        switch (e.type) {
        case EVENT_NEW_SERVER:
            if (! mSessionManager.hostListIsFull()) {
                dialog = (ConnectDialog) getApplication().getDialog(ID_CONNECT_DIALOG, this);
                dialog.show();
            }
            return true;

        case EVENT_OPEN_SESSION:
            item = (SessionListItem) mListView.getFocusedItem();
            item.itemActivated();
            return true;

        case EVENT_EDIT_SERVER:
            item = (SessionListItem) mListView.getFocusedItem();
            Terminal.instance().openSettings(item.getServerInfo());
            return true;
            
        case EVENT_MOVE_SERVER:
            mListView.enterMoveMode();
            return true;
            
        case EVENT_PLACE_SERVER:
            mListView.leaveMoveMode(true);
            break;
            
        case EVENT_CANCEL_MOVE:
            mListView.leaveMoveMode(false);
            break;

        case EVENT_DISCARD_SERVER_DIALOG:
            alert = getApplication().getAlert(DIALOG_CONFIRM_DISCARD_SERVER, this);
            item = (SessionListItem) mListView.getFocusedItem();
            alert.setEventForControlWithID(ID_DISCARD_SERVER_BUTTON, new Event(EVENT_DISCARD_SERVER, 0, 0, item));
            alert.setMessage(StringFormat.withFormat(alert.getMessage(), item.getServerInfo().getHostname()));
            alert.show();
            return true;

        case EVENT_DISCARD_SERVER:
            item = (SessionListItem) e.argument;
            mSessionManager.deleteServer(item.getServerInfo());
            return true;

        case EVENT_CLOSE_SESSION:
            item = (SessionListItem) mListView.getFocusedItem();
            item.close();
            return true;

        case EVENT_SAVE:
            dialog = (ConnectDialog) e.argument;
            if (dialog.getHostname().indexOf('.') < 0) {
                dialog.show();
                new AlertWindow(getApplication().getString(STRING_INVALID_HOSTNAME)).show();
                return true;
            }
            mSessionManager.sessionChanged(dialog.getHostInfo());
            return true;

        case EVENT_CONNECT:
            dialog = (ConnectDialog) e.argument;
            if (dialog.getHostname().indexOf('.') < 0) {
                dialog.show();
                new AlertWindow(getApplication().getString(STRING_INVALID_HOSTNAME)).show();
                return true;
            }
            // don't save this permanently, and make it vanish after the last session closes:
            // FIXME: i chickened out on this at the last minute.  i don't think you'll ever want to connect to a host and not save it.
            //dialog.getHostInfo().setTransient(true);
            Terminal.instance().openSession(dialog.getHostInfo());
            return true;

        case Event.EVENT_TIMER:
            onDecoded();
            break;
            
        case EVENT_HELP:
            Terminal.instance().getResources().getDialog(ID_KEYBOARD_HELP_DIALOG).show();
            return true;
        }

        return super.receiveEvent(e);
    }
    
    public void
    saveConnection (ConnectDialog dialog)
    {
        mSessionManager.addServer(dialog.getHostInfo());
    }

    public static SessionListWindow
    getSessionListWindow ()
    {
        return mMe;
    }

    final private void
    showAbout ()
    {
        ComponentVersion cv = new ComponentVersion("");
        getApplication().getBundle().getComponentVersion(cv);

        DialogWindow dialog = getApplication().getDialog(ID_ABOUT_DIALOG, this);
        StaticTextBox box = (StaticTextBox) dialog.getDescendantWithID(ID_ABOUT_TEXT1);
        box.setText(StringFormat.withFormat(box.getText(), cv.getVersionString(false)));

        dialog.show();
    }

    
    private static SessionListWindow    mMe;
    private SessionManager              mSessionManager;
    private TerminalScreen              mTerminal;
    private SessionListView             mListView;
    private int                         mFontCycle;
    
    private static final int[] FONT_SIZES = { 14, 12, 13, 8, 6, 26, 13, 12 };
    private static final int FONT_MAX = 99;
}
