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

// Copyright 2001-2003, Danger, Inc.  All Rights Reserved.
// This file is subject to the Danger, Inc. Sample Code License,
// which is provided in the file SAMPLE_CODE_LICENSE.
// Copies are also available from http://developer.danger.com/

package com.danger.terminal;

import danger.app.Event;
import danger.ui.DialogWindow;
import danger.ui.PopupMenu;
import danger.ui.TextField;


public class ConnectDialog
    extends DialogWindow
    implements TerminalResources, TerminalEvents
{
    public static class HostTextField
        extends TextField
    {
        public void
        loseFocus ()
        {
            ((ConnectDialog) getWindow()).updateHostname();
            super.loseFocus();
        }
    }


    public
    ConnectDialog ()
    {
        mHostInfo = null;
        mHadUsername = false;
        mLastSessionName = "";
    }

    public void
    onDecoded ()
    {
        setProtocol(ServerInfo.PROT_SSH2);
        setPort(ServerInfo.DEFAULT_PORT[ServerInfo.PROT_SSH2]);
        PopupMenu menu = (PopupMenu) getDescendantWithID(ID_CONNECT_PROTOCOL);
        menu.setExitEvent(new Event(this, EVENT_PROTOCOL_CHANGED));
        mLastProtocol = ServerInfo.PROT_SSH2;
    }

    public boolean
    receiveEvent (Event e)
    {
        switch (e.type) {
        case EVENT_PROTOCOL_CHANGED: {
            // if the port # was set to the default for this protocol, change it
            int protocol = getProtocol();
            if (mLastProtocol != protocol) {
                int port = getPort();
                if ((port == ServerInfo.DEFAULT_PORT[mLastProtocol]) || (port == 0)) {
                    setPort(ServerInfo.DEFAULT_PORT[protocol]);
                }
                mLastProtocol = protocol;
            }
            return true;
        }
        }
        
        return super.receiveEvent(e);
    }
    
    /* scan the hostname field and break out common things like putting
     * the port in there, etc.
     */
    private void
    parseHostname ()
    {
        String hostname = getHostname();
        int port = getPort();
    
        /* support old-skool port specification */
        int separator = hostname.indexOf(':');
        if (separator == -1) {
            separator = hostname.indexOf(' ');
        }
        if (separator != -1) {
            String portStr = hostname.substring(separator + 1).trim();
            if (portStr.equals("local")) {
                port = -1;
            } else {
                try {
                    port = Integer.parseInt(portStr);
                } catch (NumberFormatException exc) {
                    // pass
                }
            }
            hostname = hostname.substring(0, separator);
        }
        
        setHostname(hostname);
        setPort(port);
    }
    
    // called when the cursor leaves the hostname field
    /* package */ void
    updateHostname ()
    {
        parseHostname();
        if (mLastSessionName.equals(getSessionName())) {
            /* just copy whatever they had */
            mLastSessionName = getHostname();
            setSessionName(mLastSessionName);
        }
    }

    protected void
    updateHostInfo ()
    {
        int protocol = getProtocol();

        if (protocol != mHostInfo.getProtocol()) {
            /* need to create a new session-info object, because the old one might
             * be a descendant of HostInfo with protocol-specific fields.
             */
            SessionManager manager = Terminal.instance().getSessionManager();
            ServerInfo info = ServerInfo.createServerInfo(manager, protocol);
            manager.replaceSession(mHostInfo, info);
            mHostInfo = info;
        }

        /* now set common things */
        parseHostname();
        String hostname = getHostname();
        int port = getPort();

        /* look for 'user@hostname' format */
        int at = hostname.indexOf('@');
        if (at > 0) {
            mHostInfo.setHostname(hostname.substring(at + 1));
            mHostInfo.setUsername(hostname.substring(0, at));
        } else {
            mHostInfo.setHostname(hostname);

            /* if we started with a user name, then clear it */
            if (mHadUsername) {
                mHostInfo.setUsername("");
            }
        }

        mHostInfo.setSessionName(getSessionName());
        mHostInfo.setPort(port);
    }
    
    public ServerInfo
    getHostInfo ()
    {
        if (mHostInfo == null) {
            mHostInfo = ServerInfo.createServerInfo(Terminal.instance().getSessionManager(), getProtocol());
            updateHostInfo();
            Terminal.instance().getSessionManager().addServer(mHostInfo);
        } else {
            /* make sure what we have is up to date! */
            updateHostInfo();
        }
        
        return mHostInfo;
    }

    public final String
    getHostname ()
    {
        return getDescendantWithID(ID_CONNECT_HOST).toString();
    }

    public final void
    setHostname (String hostname)
    {
        ((TextField) getDescendantWithID(ID_CONNECT_HOST)).setText(hostname);
    }

    public final int
    getPort ()
    {
        try {
            return Integer.parseInt(getDescendantWithID(ID_CONNECT_PORT).toString());
        } catch (NumberFormatException x) {
            return ServerInfo.DEFAULT_PORT[getProtocol()];
        }
    }
    
    public final void
    setPort (int port)
    {
        ((TextField) getDescendantWithID(ID_CONNECT_PORT)).setText(Integer.toString(port));
    }
    
    public final String
    getSessionName ()
    {
        return getDescendantWithID(ID_CONNECT_NAME).toString();
    }
    
    public final void
    setSessionName (String name)
    {
        ((TextField) getDescendantWithID(ID_CONNECT_NAME)).setText(name);
    }

    public int
    getProtocol ()
    {
        PopupMenu menu = (PopupMenu) getDescendantWithID(ID_CONNECT_PROTOCOL);

        switch (menu.getValueAsItemID()) {
        case ID_PROTOCOL_SSH2:
            return ServerInfo.PROT_SSH2;
        case ID_PROTOCOL_TELNET:
            return ServerInfo.PROT_TELNET;
        case ID_PROTOCOL_RAW:
            return ServerInfo.PROT_RAW;
        default:
            System.err.println("WHAT:? " + menu.getValueAsItemID());
        }
        return 0;
    }

    public void
    setProtocol (int protocol)
    {
        PopupMenu menu = (PopupMenu) getDescendantWithID(ID_CONNECT_PROTOCOL);
        switch (protocol) {
        case ServerInfo.PROT_SSH2:
            menu.setValueWithItemID(ID_PROTOCOL_SSH2);
            break;
        case ServerInfo.PROT_TELNET:
            menu.setValueWithItemID(ID_PROTOCOL_TELNET);
            break;
        case ServerInfo.PROT_RAW:
            menu.setValueWithItemID(ID_PROTOCOL_RAW);
            break;
        }
    }


    private ServerInfo            mHostInfo;
    private String              mLastSessionName;
    private boolean             mHadUsername;
    private int                 mLastProtocol;
}
