/*
 * hiptopClient.java	1.0
 *
 * Copyright 2002 by Danger Research, Inc.
 * 124 University Avenue, Palo Alto, CA  94301
 * All rights reserved.
 */
package com.danger.hiptopClient;

import danger.util.StringUtils;
import danger.app.*;
import danger.net.HiptopConnection;
import danger.net.HiptopTransaction;
import danger.ui.*;

import java.io.IOException;

/**
 * Implements the main application class.
 *
 */
public class hiptopClient extends Application
{
	//*	--------------------	bang

    /**
     * Creates the main application class.
     *
     */
	public
	hiptopClient()
	{
		//*	Create our app's main window
		mWindow = new MainWindow();
		mWindow.setTitle("hiptop Client");
	}

	//*	--------------------	ReceiveEvent

    /**
     * Receives OS events.
     *
     */

	public boolean
    receiveEvent(Event e)
	{
		switch (e.type)
		{
            case kCmd_SendTime:
            {
                byte[] b;
                int t;

                b = new byte[4];
                t = danger.system.Hardware.getSystemTime();
		
                b[0] = (byte)((t & 0xFF000000) >> 24);
                b[1] = (byte)((t & 0x00FF0000) >> 16);
                b[2] = (byte)((t & 0x0000FF00) >> 8);
                b[3] = (byte)(t & 0x000000FF);
				
                HiptopSend(mWindow.mWhoField.toString(), b, 42);
                return (true);
            }
			
            case kCmd_SendMisc:
            {
                HiptopSendMiscellaneous();
                return (true);
            }
			
			case kCmd_Start:
			{	
				mWho = mWindow.mWhoField.toString();
				mSize = StringUtils.toInt(mWindow.mSizeField.toString());
                mData = new byte[mSize];
				mTotal = 0;
				mCount = 0;
				mWindow.mCountField.setText("0");
				mWindow.mTimeField.setText("-");
				mWindow.mAvgField.setText("-");
				mTimer = new Timer(StringUtils.toInt(mWindow.mFreqField.toString()), true, this);
				mTimer.start();
				mWindow.mStartStop.setTitle(mWindow.kStr_Stop);
				mWindow.mStartStop.setEvent(kCmd_Stop);

                // Put the send time in the data
                int t = danger.system.Hardware.getSystemTime();		
                mData[0] = (byte)((t & 0xFF000000) >> 24);
                mData[1] = (byte)((t & 0x00FF0000) >> 16);
                mData[2] = (byte)((t & 0x0000FF00) >> 8);
                mData[3] = (byte)(t & 0x000000FF);

                // Go ahead and send the first one.
				HiptopSend(mWho, mData, mCount);
//                HiptopSend_ThrowError(mWho, mData, mCount);
				return (true);
			}
			
			case kCmd_Stop:
			{
				mTimer.stop();
				mTimer = null;
				mWindow.mStartStop.setTitle(mWindow.kStr_Start);
				mWindow.mStartStop.setEvent(kCmd_Start);
				return (true);
			}
			
			case Event.EVENT_TIMER:
            {
                // Update the send time in the data
                int t = danger.system.Hardware.getSystemTime();		
                mData[0] = (byte)((t & 0xFF000000) >> 24);
                mData[1] = (byte)((t & 0x00FF0000) >> 16);
                mData[2] = (byte)((t & 0x0000FF00) >> 8);
                mData[3] = (byte)(t & 0x000000FF);
				HiptopSend(mWho, mData, mCount);
//                HiptopSend_ThrowError(mWho, mData, mCount);
				return (true);
            }
		}
		return (super.receiveEvent(e));
	}

	//*	--------------------	ReceiveEvent

    /**
     * Receives OS events.
     *
     */

	public void
    networkEvent(Object s)
	{
		if (s instanceof HiptopTransaction)
		{
			HiptopTransaction ht = (HiptopTransaction)s;
            
            switch(ht.getCommand())
            {
            
            case HiptopTransaction.COMMAND_DEVICE_DATA:
                {
                    int received = danger.system.Hardware.getSystemTime();
                    int sent;
                    int t;
                    int sequenceID = ht.getSequenceID();
                    byte[] b = ht.getBytes();
                    
                    sent = ((b[0] & 0xFF) << 24) + 
                           ((b[1] & 0xFF) << 16) +
                           ((b[2] & 0xFF) << 8) + 
                           (b[3] & 0xFF);
        
                    t = received - sent;
                    System.err.println("***received in=" + t + "ms");

                    System.err.println("Sequence ID=" + sequenceID);                   
                    System.err.println("FromUsername=" + ht.getFromUsername());
                    System.err.println("ToUsername=" + ht.getToUsername());
                    
                    mTotal += t;
                    mCount++;
                    mWindow.mCountField.setText("" + mCount);
                    mWindow.mTimeField.setText("" + t);
                    mWindow.mAvgField.setText("" + (mTotal / mCount));
                    mWindow.invalidate();
                }
                break;

                case HiptopTransaction.COMMAND_MISCELLANEOUS:
                    {
                        int sequenceID = ht.getSequenceID();
                        byte[] b = ht.getBytes();
                    
                        System.err.println("Sequence ID=" + sequenceID);
                        System.err.println("b[0]=" + b[0]);
                        System.err.println("b[1]=" + b[1]);
                        System.err.println("b[2]=" + b[2]);
                        System.err.println("b[3]=" + b[3]);
                    }
                    break;
            }
		}
	}

	//*	--------------------	Resume

    /**
     * Handles the Resume event.
     *
     */
	public void
    resume()
	{
		mWindow.show();
	}
	
	//*	--------------------	Suspend

    /**
     * Handles the Suspend event..
     *
     */
	public void
    suspend()
	{
	}
	
    public void
    HiptopSend(String inDestination, byte[] inData, int inSequenceID)
    {
        HiptopConnection.send(inDestination, inData, inSequenceID);
    }
	
    public void
    HiptopSend_ThrowError(String inDestination, byte[] inData, int inSequenceID)
    {
        try
        {
            HiptopConnection.send_ThrowError(inDestination, inData, inSequenceID);
        }
        catch (IOException ex)
        {
            ex.fillInStackTrace();
            ex.printStackTrace();
        }
    }
	
    
    // This provides room for future expansion.  
    // For now, it should not be used by applications.
    public void
    HiptopSendMiscellaneous()
    {
        byte[] b;

        b = new byte[4];
		
        b[0] = (byte)1;
        b[1] = (byte)2;
        b[2] = (byte)3;
        b[3] = (byte)4;
				
        HiptopConnection.miscellaneous(b, 42);
    }
	
	//*	--------------------	Variables
	MainWindow	mWindow;
	Timer		mTimer;
	String		mWho;
	int			mSize;
	int			mCount;
	int			mTotal;
    byte[]      mData;

    static final String	kStr_SendTime	= "Send Time";
    static final int	kCmd_SendTime	= 1;
    static final String	kStr_SendMisc	= "Send Miscellaneous";
    static final int	kCmd_SendMisc	= 2;

	static final int	kCmd_Start		= 100;
	static final int	kCmd_Stop		= 101;

}

class MainWindow extends ScreenWindow
{
	//*	--------------------	MainWindow
	public
	MainWindow()
	{
		mBounds = getBounds();

		BuildActionMenu();
		
		BuildWorld();
	}

    public final boolean
    eventWidgetUp(int inWhichWidget, Event event)
    {
        switch (inWhichWidget)
        {
            case Event.DEVICE_BUTTON_CANCEL:
            case Event.DEVICE_BUTTON_BACK:
                getApplication().returnToLauncher();
                return true;
        }
        return super.eventWidgetUp(inWhichWidget, event);
    }

	//*	--------------------	BuildActionMenu
	final void
	BuildActionMenu()
	{
		Menu menu = getActionMenu();
		menu.removeAllItems();
        menu.addItem(hiptopClient.kStr_SendTime, 
                     hiptopClient.kCmd_SendTime, 
                     1, 
                     null, 
                     Application.getCurrentApp()).setShortcut('1');
        
        menu.addItem(hiptopClient.kStr_SendMisc, 
                     hiptopClient.kCmd_SendMisc, 
                     2, 
                     null, 
                     Application.getCurrentApp()).setShortcut('2');
	}

	//*	--------------------	BuildWorld
	final void
    BuildWorld()
	{
		mWhoField = BuildTextField(kStr_WhoLabel, // Static text label
								   50,			 // Label width (pixels)
								   5,			 // Left (pixels)
								   10);			 // top
		mWhoField.setWidth(50);
		mWhoField.setText(HiptopConnection.getUserName());
		
		mSizeField = BuildTextField(kStr_SizeLabel,
										50,
										5,
										30);
		mSizeField.setWidth(50);
		mSizeField.setText("10");
		
		mFreqField = BuildTextField(kStr_FreqLabel,
										50,
										5,
										50);
		mFreqField.setWidth(50);
		mFreqField.setText("3000");
		
		mStartStop = new Button(kStr_Start);
		mStartStop.setTop((mBounds.bottom - mStartStop.getHeight()) - 2);
		mStartStop.setLeft((mBounds.right - mStartStop.getWidth()) - 2);
		mStartStop.setEvent(hiptopClient.kCmd_Start);
		addChild(mStartStop);
		mStartStop.show();

		mCountField = BuildTextField(kStr_CountLabel, // Static text label
								   50,			 // Label width (pixels)
								   115,			 // Left (pixels)
								   10);			 // top
		mCountField.setWidth(50);
		mCountField.setText("-");
		
		mTimeField = BuildTextField(kStr_TimeLabel,
										50,
										115,
										30);
		mTimeField.setWidth(50);
		mTimeField.setText("-");
		
		mAvgField = BuildTextField(kStr_AvgLabel,
										50,
										115,
										50);
		mAvgField.setWidth(50);
		mAvgField.setText("-");
		
		if (getFocusedChild() == null)
		{
			setFocusedChild(mWhoField);
		}
	}


	//*	--------------------	BuildTextField
	final TextField
	BuildTextField(String inLabel, int inLabelSpace, int inLeft, int inTop)
	{
		StaticText labelView = new StaticText(inLabel);

		labelView.setSize(inLabelSpace, labelView.getHeight());
		labelView.setPosition(inLeft, inTop);
//		labelView.SetFont(Contacts.mBoldFont);
		labelView.setAlignment(StaticText.HALIGN_RIGHT);
		addChild(labelView);
		labelView.show();

		TextField textField = new TextField(null, true, true);
		Layout.positionToRight(textField, labelView, labelView.getTop() - 2, 2);
//		textField.SetFont(Contacts.mBoldFont);
		addChild(textField);
		textField.show();

		return textField;
	}

	
	//*	--------------------	GetWindowTitle
	public String
	GetWindowTitle()
	{
		return ("hiptop Client");
	}

	//*	--------------------------------	Instance Variables
	Rect			mBounds;
	static final String			kStr_WhoLabel   = "Who";
	static final String			kStr_SizeLabel  = "Size";
	static final String			kStr_FreqLabel	= "ms";
	static final String			kStr_CountLabel = "#";
	static final String			kStr_TimeLabel  = "ms";
	static final String			kStr_AvgLabel	= "avg";
	static final String			kStr_Start		= "Start";
	static final String			kStr_Stop		= "Stop";

				 TextField		mWhoField;
				 TextField		mSizeField;
				 TextField		mFreqField;
				 TextField		mCountField;
				 TextField		mTimeField;
				 TextField		mAvgField;
				 Button			mStartStop;
}
