import com.ms.wfc.app.*;
import com.ms.wfc.core.*;
import com.ms.wfc.ui.*;
import cnrg.itx.signal.SignalEvent.*;
import cnrg.itx.signal.*;
import cnrg.itx.ds.*;
import cnrg.itx.datax.*;
import cnrg.itx.datax.devices.*;
import AutoComplete.trie;
import java.util.Properties;
import java.util.Hashtable;
import java.util.Vector;
import java.io.*;

/**
 * A instance of the cups class is create in the main method to run the cups program
 * under the Microsoft VM.
 * @author Jingyang Xu
 * @version 1.0
 */
public class cups extends Form implements SignalingObserver 
{
	
	/**************************************************************
	 * Variables to support ITX API
	 **************************************************************/
	// my instance of the signaling (ITX)
	private DesktopSignaling m_dts;
	// The object representing my current telephony connetion (ITX)
	private SignalConnection m_sigConn;
	// my instant of the Directory Service object (ITX)
	private DirectoryService m_ds;
	// An audioconnection object, we used this to play sounds through the speaker (ITX)
	// see the PlaySound function - here we're using ITX's AudioConnection to make
	// simply play wave files to the speaker.
	private AudioConnection ac;
	/*************************************************************
	 * End ITX Variables
	 *************************************************************/

	/*************************************************************
	 * Functions to support ITX API,
	 * necessary to implement SignalingObserver
	 *************************************************************/

	/**
	 * part of the SignalingObserver interface, called by Signaling when
	 * an invitation is received for making a connection
	 * @param se Signal Event describing the nature of the invitation
	 * @see ITX API - cnrg.itx.signal
	 */
	public void onInvite(InviteSignalEvent se)
	{
		// if we talking already, reject any new connections
		if (m_sigConn != null) {
			se.reject("Can't talk right now, talking to someone else");
			return;
		}
		// if we're in answering machine mode, accept immediately
		if(menuItem24.getChecked()) 
		{
			se.accept();
			m_peerUser = se.getSenderID().toString();
			return;
		}
		// else ask the user whether to accept the call
		Accept acc = new Accept();
		acc.setCaller(se.getSenderID().toString());
		PlaySound(notifyFile);
		if(acc.showDialog() == DialogResult.OK) 
		{
			se.accept();
			m_peerUser = se.getSenderID().toString();
		}
		else
			se.reject("Don't want to talk to you");
		acc.dispose();
		StopSound();
	}

	/**
	 * part of the SignalingObserver interface, called by Signaling when
	 * a connection has been negotiated, ie onInvite has been called and Signaling
	 * has confirmed the connection with the other side
	 * @param c A SignalConnection object encapsulating the connection
	 * @see ITX API - cnrg.itx.signal
	 */
	public void onStartCall(SignalConnection c)
	{
		// save the connection
		m_sigConn = c;
		try 
		{
			// if we're in answering machine mode, play the greeting file
			// and write the incoming voice to file as well as speaker
			if(menuItem24.getChecked()) 
			{
				try 
				{
					m_sigConn.getOutputChannel().setSource(new StreamSource(new FileInputStream(greetingFile), m_sigConn.getOutputChannel(), 100));
				}
				catch (IOException ioe) 
				{
				}
				try {
					m_sigConn.getInputChannel().addDestination(new StreamDestination(new FileOutputStream(messageFile, true)));
				}
				catch (IOException ioe) 
				{
				}
			}
			// open the connection, this starts up the network and the audio devices
			// which was setup by signaling
			m_sigConn.open();
		} catch (DataException de) {
			//TODO: catch data exception
		} 
		setAction("Connected to " + m_peerUser);
		RefreshItems();
	}
	
	/**
	 * part of the SignalingObserver interface, called by Signaling when
	 * onInvite has been called, but the connection was not negotiated
	 * @param ase Signal Event describing why the call was aborted
	 * @see ITX API - cnrg.itx.signal
	 */
	public void onAbortCall(AbortSignalEvent ase){
		m_peerUser = null;
		setAction("Call aborted");
	}

	/**
	 * part of the SignalingObserver interface, called by Signaling when
	 * the other user hangs up the connection
	 * @param se Signal Event describing the hangup
	 * @see ITX API - cnrg.itx.signal
	 */
	public void onHangup(HangupSignalEvent se){
		// Signaling should have hung up m_sigConn
		m_sigConn = null;
		m_peerUser = null;
		RefreshItems();
		setAction("Connection disconnected");
	}
	
	/**
	 * part of the SignalingObserver interface, called by Signaling when
	 * a DTMF tone is sent from a peer
	 * @param se Signal Event describing the DTMF
	 * @see ITX API - cnrg.itx.signal
	 */
	public void onDTMF(DTMFSignalEvent se)
	{
		// not doing anything for now
	}
	/*************************************************************
	 * End ITX Functions
	 *************************************************************/

	// my list of known users for auto-complete
	private trie m_userlist;
	// the currently logged-on user
	private UserPass m_currUser = null;
	// the user I'm talking to
	private String m_peerUser = null;
	// the user selected in the directory view
	private ListItem m_selectedUser = null;
	// The last size of the window so we can restore it from compact mode
	private Point m_size;
	// TRUE if current user has administrator access
	private boolean m_admStatus = false;
	// name of the file to save messages to, the contents of this files are raw,
	// headerless 8khz, 8bit samples
	private static final String messageFile = "message.rad";
	// name of the file to play for the greeting message for answering machine mode
	private static final String greetingFile = "greeting.wav";
	// name of the file to play for the accept notification
	private static final String notifyFile = "ringin.wav";

	/**
	 * Returns the current SignalConnection for this cups instantiation
	 */
	public SignalConnection getSignalConnection() 
	{
		return m_sigConn;
	}
	/**
	 * Constructor
	 */
	public cups() { 

		super();
		
		// Required for Visual J++ Form Designer support
		initForm();		

		// print all outputs to "debug".txt
		try {
			System.setOut(new PrintStream(new FileOutputStream("debug.txt", true)));
		}
		catch (IOException ioe) 
		{
		}
		RefreshItems();
		// read the config file
		try {
			FileInputStream istream = new FileInputStream("cups.cfg");
			ObjectInputStream p = new ObjectInputStream(istream);
			cupsSaved i = (cupsSaved)p.readObject();
			m_currUser = i.user;
			m_userlist = i.userlist;
			// switch into compact mode if that's what was used in the last session
			if(i.compactmode)
			{
				menuItem29_click(null, null);
			}
			// read our known frequently dialed user list and put it in the
			// call box for auto-complete
			toolbar1.setComboBoxItems(i.combolist);
			trie t = new trie();
			for(int index = 0; index < i.combolist.length; index++) {
				t.put(i.combolist[index], new Object());
			}
			toolbar1.setWordstrie(t);
			istream.close();
		}
		catch (FileNotFoundException fe) {
			m_currUser = null;
			m_userlist = null;
		}
		catch (IOException ioe) {
			ioe.printStackTrace();
		}
		catch (ClassNotFoundException ce) {
		}
		Login();
	}

	/**
	 * cups overrides dispose so it can clean up the
	 * component list.
	 */
	public void dispose()
	{
		super.dispose();
		components.dispose();
	}

	/**
	 * Play a sound file using ITX services
	 * @param fileName name of the 8khz, 8-bit file to play, can be a .wav file but the headers will be played
	 */
	private void PlaySound(String fileName) {
		try 
		{
			//create a new channel
			Channel c = new Channel();

			//set a StreamSource as the source of the channel
			//and set a SpeakerDestination as the destination
			//when we open it, sound will be streamed from file to speaker
			FileInputStream fis = new FileInputStream(fileName);
			c.setSource(new StreamSource(fis, c));
			c.addDestination(new SpeakerDestination() );

			//make an AudioConnection with only the input channel
			ac = new AudioConnection (c, null);
			//open it
			ac.open();
		} catch (Exception ex) {
		}
	}
	
	/**
	 * Stops playing the current sound
	 */
	private void StopSound() {
		if (ac!= null)
			ac.close();
		ac = null;
	}

	/**
	 * Reads all the entry from the Directory and update the listview
	 */
	private void RefreshDirectory() 
	{
		if(m_ds == null) 
			return;
		Vector users;
		// call dumpAllUsers() to get all users (ITX)
		try {
			users = m_ds.dumpAllUsers();
		} catch (DirectoryServiceException de) {
			//TODO: catch directory exception
			return;
		} 
		// now we have a vector of users, copy them to the listview
		// as well as add all the users to the auto-complete list
		// of the call box
		String[] temp = new String[3];
		
		listView1.removeAllItems();
		trie t = new trie();
		Object[] temparray = toolbar1.getComboBoxItems();
		for(int index = 0; index < temparray.length; index++)
			t.put((String)temparray[index],new Object());
		for(int i = 0; i<users.size(); i++) {
			UserProperty up = (UserProperty)users.elementAt(i);
			temp[0] = "" + up.getExtension();
			Location l = up.getRoamingLocation();
			if(l!=null)
				temp[1] = l.getIP() + ":" +l.getPort();
			else
				temp[1] = "";
			temp[2] = up.getCustomMessage();
			listView1.addItem(up.getUserID().toString(), -1, temp);
			// add this to the autocomplete list too
			t.put(up.getUserID().toString(), new Object());
		}
		toolbar1.setWordstrie(t);
	}
	
	/**
	 * puts text on the 3rd status panel
	 * @param p_status Text to be displayed
	 */
	private void setStatus(String p_status) {
		statusBarPanel3.setText(p_status);
	}
	
	/**
	 * puts text on the 1st status panel
	 * @param p_action Text to be displayed
	 */
	private void setAction(String p_action) {
		statusBarPanel1.setText(p_action);
	}

	/**
	 * Makes a call to m_peeruser
	 */
	private void Call() {
		if(m_dts != null) 
		{
			// hangup the current call first, if any
			if(m_sigConn != null) {
				Hangup();
			}
			setAction("Calling " + m_peerUser);
			try 
			{
				// make the Dial call (ITX)
				m_sigConn = m_dts.Dial(m_peerUser);
				// open the connection (ITX)
				m_sigConn.open();
				RefreshItems();
			} catch (DesktopSignalingException dse) {
				//TODO: catch desktopSignalingException
				setAction(dse.toString());
				return;
			} catch (DataException de) {
				//TODO: catch data exception
				de.printStackTrace();
				return;
			} catch (DirectoryServiceException dse) {
				//TODO: catch directory service exception
				setAction(dse.toString());
				return;
			}
			setAction("Connected to " + m_peerUser);
		} else {
			setAction("Unable to call without logging in");
		}
	}
	
	/**
	 * Login as m_curruser to the ITX directory service
	 */
	private void Login() {
		if(m_currUser == null) {
			Login myLogin = new Login(m_userlist);
			if(myLogin.showDialog() == DialogResult.OK) {
				m_userlist = myLogin.getUserlist();
				m_currUser = myLogin.getUserPass();
			}
			myLogin.dispose();
		}
		if (m_currUser != null) {
			try {
				setAction("Logging in ...");
				// create an instance of DesktopSignaling (ITX)
				// using the current username and password (ITX)
				m_dts = new DesktopSignaling(this, m_currUser.getUsername(), m_currUser.getPassword()/*, "Cups Application", "resolve.conf"*/);
				// get the directory service (ITX)
				m_ds = m_dts.getDirectory();
				// obtain the access level (ITX)
				if(m_ds.getAccessLevel() == DirectoryService.ADM_ACCESS_LEVEL)
					m_admStatus = true;
				else
					m_admStatus = false;
				setAction("");
				setStatus("Logged in as " + m_currUser.getUsername());
				RefreshDirectory();
				RefreshItems();
				return;
			} catch (DirectoryServiceException dse) {
				//TODO: catch directory service exception
				setAction(dse.toString());
			}
		}
		setStatus("Not logged in");
	}
	
	/**
	 * logout m_curruser
	 */
	private void Logout() {
		if(m_dts != null) {
			setAction("Loggin out...");
			if(m_sigConn != null) {
				try 
				{
					// if connected, hang it up (ITX)
					m_dts.Hangup(m_sigConn);
				} catch (ConnectException ce) {
					ce.printStackTrace();
				}
				m_sigConn = null;
			}
			m_dts.logout();
			m_dts = null;
			setAction("Logged out");
			setStatus("Not logged in");
		}
		m_currUser = null;
		m_admStatus = false;
		m_ds = null;
		m_peerUser = null;
		RefreshItems();
	}
	
	/**
	 * hangup the current connection
	 */
	private void Hangup()
	{
		if(m_sigConn == null) {
			setAction("Unable to hangup, not connected");
			RefreshItems();
		} else {
			try 
			{
				// hangup the current connection (ITX)
				m_dts.Hangup(m_sigConn);
			} catch (ConnectException ce) {
				//TODO: catch connection exception
			}
			m_sigConn = null;
			RefreshItems();
			setAction("Hanged up connection");
		}
	}

	/**
	 * update the UI states according to current state
	 */
	private void RefreshItems() 
	{
		// disable everything if we're playing something
		if(ac != null) 
		{
			menuItem1.setEnabled(false);
			menuItem6.setEnabled(false);
			menuItem9.setEnabled(false);
			menuItem13.setEnabled(false);
			menuItem25.setEnabled(false);
			menuItem28.setEnabled(false);
			toolBar1.setEnabled(false);
		}
		else 
		{
			menuItem1.setEnabled(true);
			menuItem6.setEnabled(true);
			menuItem9.setEnabled(true);
			menuItem13.setEnabled(true);
			menuItem25.setEnabled(true);
			menuItem28.setEnabled(true);
			toolBar1.setEnabled(true);
		}
			
		// enable/disable hangup and tones
		if(m_sigConn == null) {
			menuItem11.setEnabled(false);
			toolBarButton3.setEnabled(false);
			groupBox1.setVisible(false);
			menuItem10.setEnabled(false);
		} else {
			menuItem11.setEnabled(true);
			toolBarButton3.setEnabled(true);
			groupBox1.setVisible(true);
			menuItem10.setEnabled(true);
		}
		// enable/disable add/remove users
		if(m_admStatus) {
			menuItem15.setEnabled(true);
			toolBarButton5.setEnabled(true);
			if(m_selectedUser != null) {
				menuItem16.setEnabled(true);
				toolBarButton6.setEnabled(true);
			} else {
				menuItem16.setEnabled(false);
				toolBarButton6.setEnabled(false);
			}			
		} else {
			menuItem15.setEnabled(false);
			menuItem16.setEnabled(false);
			toolBarButton5.setEnabled(false);
			toolBarButton6.setEnabled(false);
		}
		// enable/disable logout + edit current user
		if(m_dts == null) {
			menuItem3.setEnabled(false);
			toolBarButton2.setEnabled(false);
			menuItem17.setEnabled(false);
			toolBarButton7.setEnabled(false);	
		} else {
			menuItem3.setEnabled(true);
			toolBarButton2.setEnabled(true);
			menuItem17.setEnabled(true);
			toolBarButton7.setEnabled(true);
		}
		// enable/disable edit user
		// TODO do this for edit selected user
/*		if(m_selectedUser != null) {
			if(m_admStatus) {
				menuItem17.setEnabled(true);
				toolBarButton7.setEnabled(true);
			} else {
				menuItem17.setEnabled(false);
				toolBarButton7.setEnabled(false);
			}
			if(m_currUser != null) {
				if(m_currUser.getUsername().equals(m_selectedUser)) {
					menuItem17.setEnabled(true);
					toolBarButton7.setEnabled(true);
				} else {
					menuItem17.setEnabled(false);
					toolBarButton7.setEnabled(false);
				}
			}
		} else {
			menuItem17.setEnabled(false);
			toolBarButton7.setEnabled(false);	
		} */
	}

	/**
	 * Add an user to directory service
	 */
	private void DoAddUser() {
		AddUser au = new AddUser();
		if(au.showDialog() == DialogResult.OK) {
			String username = au.getUserPass().getUsername();
			String password = au.getUserPass().getPassword();
			String extension = au.getExtension();
			String message = au.getMessage();
			Digits d;
			int admacc;
			if(au.getAdmAccess())
				admacc = DirectoryService.ADM_ACCESS_LEVEL;
			else
				admacc = DirectoryService.USER_ACCESS_LEVEL;
			try 
			{
				if(extension == null) {
					d = m_ds.addUser(new UserID(username), 3, new Password(password), admacc, message);
				}
				else 
				{
					d = new Digits(extension);
					m_ds.addUser(new UserID(username), d, new Password(password), admacc, message);
				}

			} catch (DirectoryServiceException dse) {
				//TODO: catch directory service exception
				return;
			}
			setAction("User " + username + " was added to the directory at extension " + d.getValue());
		}
		au.dispose();
	}

	/**
	 * edit properties for m_curruser
	 */
	private void DoEditUser() {
		//Stats s = m_sigConn.getInputChannel().getStatistics();
		EditUser eu = new EditUser(new UserID(m_currUser.getUsername()), new Password(m_currUser.getPassword()));
		eu.showDialog();
		eu.dispose();
	}

	/**
	 * remove all selected users from the directory service
	 */
	private void DoRemoveUser() {
		ListItem[] lis = listView1.getSelectedItems();
		for(int i = 0; i<lis.length; i++) {
			try {
				m_ds.removeUser(new Digits(lis[i].getSubItem(0)));
				listView1.removeItem(lis[i]);
			} catch (DirectoryServiceException ae) {
				ae.printStackTrace();
			}
		}
	}

	/**
	 * switch between compact and normal view
	 */
	private synchronized void switchstate() 
	{
		System.out.println("In switch state()");
		if(this.getTopMost()) 
		{
			this.setTopMost(false);
			this.setText("cups");
			this.setBorderStyle(FormBorderStyle.SIZABLE);
			this.setSize(m_size);
			this.setMenu(mainMenu1);
			statusBar1.show();
			rebar1.addBand(rebarBand2);
			groupBox1.show();
			listView1.show();
			this.centerToScreen();
		}
		else 
		{
			this.setMenu(null);
			statusBar1.hide();
			rebar1.removeBand(rebarBand2);
			groupBox1.hide();
			listView1.hide();
			m_size = this.getSize();
			this.setSize(150, 60);
			this.setBorderStyle(FormBorderStyle.FIXED_TOOLWINDOW);
			this.setTopMost(true);
			this.setText("cups - " + m_currUser.getUsername());
		}
	}

	/*************************************************************
	 * WFC Event Handlers
	 *************************************************************/
	
	/**
	 * The "Call" has been pressed or the user has pressed return in the call box
	 */
	private void toolbar1_calling(Object source, Event e)
	{
		m_peerUser = (String)e.extendedInfo;
		Call();
	}

	/**
	 * User pressed login
	 */
	private void menuItem2_click(Object source, Event e)
	{
		Logout();
		Login();
	}

	/**
	 * User pressed logout
	 */
	private void menuItem3_click(Object source, Event e)
	{
		Logout();
	}

	/**
	 * User pressed refresh directory
	 */
	private void menuItem14_click(Object source, Event e)
	{
		RefreshDirectory();
	}
	
	/**
	 * The icon toolbar has just been clicked on
	 */
	private void toolBar1_buttonClick(Object source, ToolBarButtonClickEvent e)
	{
		// delegate the work to menu item handlers
		if(e.button == toolBarButton1) {
			menuItem2_click(source, e);
		} else if (e.button == toolBarButton2) {
			menuItem3_click(source, e);
		} else if (e.button == toolBarButton3) {
			menuItem11_click(source, e);
		} else if (e.button == toolBarButton4) {
			menuItem14_click(source, e);
		} else if (e.button == toolBarButton5) {
			menuItem15_click(source, e);
		} else if (e.button == toolBarButton6) {
			menuItem16_click(source, e);
		} else if (e.button == toolBarButton7) {
			menuItem17_click(source, e);
		}
		else if (e.button == toolBarButton20) 
		{
			menuItem29_click(source,e);
		}
	}

	/**
	 * The program is closing
	 */
	private void cups_closing(Object source, CancelEvent e) { 
		
		cupsSaved i = new cupsSaved();
		i.user = m_currUser;
		i.userlist = m_userlist;
		i.compactmode = this.getTopMost();
		Object[] temparray = toolbar1.getComboBoxItems();
		i.combolist = new String[temparray.length];
		for(int index = 0; index < temparray.length; index++)
			i.combolist[index] = (String)temparray[index];
		if(menuItem12.getChecked()) {
			try {
				FileOutputStream fo = new FileOutputStream("cups.cfg");
				ObjectOutputStream oo = new ObjectOutputStream(fo);
				oo.writeObject(i);
				oo.close();
				fo.close();
			} catch (IOException ioe) {
				MessageBox.show("Error in saving settings - Possible cause: cups.cfg file is read only", "Could not save settings", MessageBox.ICONERROR);
			}
		}
		Logout();
	}

	/**
	 * Clearing the user list
	 */
	private void menuItem22_click(Object source, Event e)
	{
		m_userlist = new trie();
		toolbar1.setWordstrie(new trie());
		toolbar1.setComboBoxItems(null);
	}

	/**
	 * Exit has been pressed
	 */
	private void menuItem4_click(Object source, Event e) {
		Application.exit();
	}

	/**
	 * Toggle save users
	 */
	private void menuItem12_click(Object source, Event e) {
		menuItem12.setChecked(!menuItem12.getChecked());
	}

	/**
	 * Add user has been pressed
	 */
	private void menuItem15_click(Object source, Event e) {
		DoAddUser();
	}
	
	/**
	 * Edit user has been pressed
	 */
	private void menuItem17_click(Object source, Event e) {
		DoEditUser();
	}
	
	/**
	 * Hangup has been pressed
	 */
	private void menuItem11_click(Object source, Event e) {
		Hangup();
	}

	/**
	 * Remove user has been pressed
	 */
	private void menuItem16_click(Object source, Event e) {
		DoRemoveUser();
	}
	
	/**
	 * the list view has been clicked on
	 */
	private void listView1_click(Object source, Event e) {
		ListItem[] lis = listView1.getSelectedItems();
		if(lis.length > 0) {
			m_selectedUser = listView1.getSelectedItems()[0];
		} else {
			m_selectedUser = null;
		}
		RefreshItems();
	}

	/**
	 * Toggle answering machine mode
	 */
	private void menuItem24_click(Object source, Event e)
	{
		menuItem24.setChecked(!menuItem24.getChecked());
	}

	/**
	 * Play Message has been pressed
	 */
	private void menuItem25_click(Object source, Event e)
	{
		PlaySound(messageFile);
		RefreshItems();
	}
	
	/**
	 * Stop message has been pressed
	 */
	private void menuItem26_click(Object source, Event e)
	{
		StopSound();
		RefreshItems();
	}

	/**
	 * The dial pad has been pressed
	 */
	private void toolBar2_buttonClick(Object source, ToolBarButtonClickEvent e)
	{
		try {
			if(e.button == toolBarButton8) {
				m_dts.sendDTMF("1", m_sigConn);
			} else if (e.button == toolBarButton9) {
				m_dts.sendDTMF("2", m_sigConn);			
			} else if (e.button == toolBarButton10) {
				m_dts.sendDTMF("3", m_sigConn);			
			} else if (e.button == toolBarButton11) {
				m_dts.sendDTMF("4", m_sigConn);
			} else if (e.button == toolBarButton12) {
				m_dts.sendDTMF("5", m_sigConn);
			} else if (e.button == toolBarButton13) {
				m_dts.sendDTMF("6", m_sigConn);
			} else if (e.button == toolBarButton14) {
				m_dts.sendDTMF("7", m_sigConn);
			} else if (e.button == toolBarButton15) {
				m_dts.sendDTMF("8", m_sigConn);
			} else if (e.button == toolBarButton16) {
				m_dts.sendDTMF("9", m_sigConn);			
			} else if (e.button == toolBarButton17) {
				m_dts.sendDTMF("*", m_sigConn);			
			} else if (e.button == toolBarButton18) {
				m_dts.sendDTMF("0", m_sigConn);			
			} else if (e.button == toolBarButton19) {
				m_dts.sendDTMF("#", m_sigConn);
			}
		}
		catch (DesktopSignalingException dse) 
		{
		}
	}

	/**
	 * Text to Speech has been checked
	 */
	private void menuItem27_click(Object source, Event e)
	{
		menuItem18.setChecked(false);
		menuItem19.setChecked(false);
		menuItem27.setChecked(true);
		RefreshItems();
	}

	/**
	 * Microphone has been checked
	 */
	private void menuItem18_click(Object source, Event e)
	{
		menuItem18.setChecked(true);
		menuItem19.setChecked(false);
		menuItem27.setChecked(false);
		RefreshItems();
	}

	/**
	 * "protect" check box checked
	 */
	private void checkBox1_click(Object source, Event e)
	{
		if(checkBox1.getChecked()) {
			edit3.setPasswordChar('*');
		} else {
			edit3.setPasswordChar((char)0);
		}
	}

	/**
	 * keys are pressed in the DTMF text box
	 */
	private void edit3_keyPress(Object source, KeyPressEvent e)
	{
		int x = e.keyChar;
		try {
			if(e.keyChar == '1'){
				edit3.setText(edit3.getText()+"1");
				m_dts.sendDTMF("1", m_sigConn);
			} else if (e.keyChar == '2') {
				edit3.setText(edit3.getText()+"2");
				m_dts.sendDTMF("2", m_sigConn);			
			} else if (e.keyChar == '3') {
				edit3.setText(edit3.getText()+"3");
				m_dts.sendDTMF("3", m_sigConn);			
			} else if (e.keyChar == '4') {
				edit3.setText(edit3.getText()+"4");
				m_dts.sendDTMF("4", m_sigConn);
			} else if (e.keyChar == '5') {
				edit3.setText(edit3.getText()+"5");
				m_dts.sendDTMF("5", m_sigConn);
			} else if (e.keyChar == '6') {
				edit3.setText(edit3.getText()+"6");
				m_dts.sendDTMF("6", m_sigConn);
			} else if (e.keyChar == '7') {
				edit3.setText(edit3.getText()+"7");
				m_dts.sendDTMF("7", m_sigConn);
			} else if (e.keyChar == '8') {
				edit3.setText(edit3.getText()+"8");
				m_dts.sendDTMF("8", m_sigConn);
			} else if (e.keyChar == '9') {
				edit3.setText(edit3.getText()+"9");
				m_dts.sendDTMF("9", m_sigConn);			
			} else if (e.keyChar == '*') {
				edit3.setText(edit3.getText()+"*");
				m_dts.sendDTMF("*", m_sigConn);			
			} else if (e.keyChar == '0') {
				edit3.setText(edit3.getText()+"0");
				m_dts.sendDTMF("0", m_sigConn);			
			} else if (e.keyChar == '#') {
				edit3.setText(edit3.getText()+"#");
				m_dts.sendDTMF("#", m_sigConn);			
			}
		}
		catch (DesktopSignalingException dse) 
		{
		}					
	}

	/**
	 * a key was pressed in the cups application
	 */
	private void cups_keyPress(Object source, KeyPressEvent e)
	{
		if(e.keyChar == Key.ESCAPE) {
			if(m_sigConn != null) {
				try {
					m_dts.Hangup(m_sigConn);
				} catch (ConnectException de) {}
				m_sigConn = null;
				RefreshItems();
				e.handled = true;
			}
		}
	}
	
	/**
	 * Compact view was pressed
	 */
	private void menuItem29_click(Object source, Event e)
	{
		switchstate();
	}

	/**
	 * the application has been resized
	 */
	private void cups_resize(Object source, Event e)
	{
		if(this.getWindowState() == FormWindowState.MAXIMIZED) 
		{
			this.setWindowState(FormWindowState.NORMAL);
			switchstate();
		}
	}
	
	/**
	 * the application is being moved
	 */
	private void cups_move(Object source, Event e)
	{
		if(this.getTop() < 0) 
			this.setTop(0);
	}

	private void listView1_itemActivate(Object source, Event e)
	{
		Object selection[] = listView1.getSelectedItems();
		String temp = ((ListItem)selection[0]).getText();
		if(temp.equals(m_currUser.getUsername())) return;
		m_peerUser = temp;
		Call();
	}

	private void menuItem10_click(Object source, Event e)
	{
		StatsDialog sDialog = new StatsDialog();
		m_sigConn.getConnection().addObserver(sDialog);
		sDialog.showDialog();
		m_sigConn.getConnection().deleteObserver(sDialog);
		sDialog.dispose();
	}

	private void menuItem30_click(Object source, Event e)
	{
		HelpDialog hDialog = new HelpDialog();
		hDialog.showDialog();
		hDialog.dispose();
	}

	/**
	 * NOTE: The following code is required by the Visual J++ form
	 * designer.  It can be modified using the form editor.  Do not
	 * modify it using the code editor.
	 */
	Container components = new Container();
	ImageList imageList1 = new ImageList();
	RebarBand rebarBand1 = new RebarBand();
	RebarBand rebarBand2 = new RebarBand();
	toolbar toolbar1 = new toolbar();
	Rebar rebar1 = new Rebar();
	MainMenu mainMenu1 = new MainMenu();
	MenuItem menuItem11 = new MenuItem();
	MenuItem menuItem21 = new MenuItem();
	MenuItem menuItem4 = new MenuItem();
	MenuItem menuItem9 = new MenuItem();
	MenuItem menuItem20 = new MenuItem();
	MenuItem menuItem18 = new MenuItem();
	MenuItem menuItem5 = new MenuItem();
	MenuItem menuItem12 = new MenuItem();
	MenuItem menuItem2 = new MenuItem();
	MenuItem menuItem1 = new MenuItem();
	ToolBar toolBar1 = new ToolBar();
	StatusBar statusBar1 = new StatusBar();
	StatusBarPanel statusBarPanel1 = new StatusBarPanel();
	StatusBarPanel statusBarPanel2 = new StatusBarPanel();
	StatusBarPanel statusBarPanel3 = new StatusBarPanel();
	MenuItem menuItem3 = new MenuItem();
	MenuItem menuItem17 = new MenuItem();
	MenuItem menuItem13 = new MenuItem();
	MenuItem menuItem14 = new MenuItem();
	MenuItem menuItem15 = new MenuItem();
	MenuItem menuItem16 = new MenuItem();
	ToolBarButton toolBarButton1 = new ToolBarButton();
	ToolBarButton toolBarButton2 = new ToolBarButton();
	ToolBarButton toolBarButton3 = new ToolBarButton();
	ToolBarButton toolBarButton4 = new ToolBarButton();
	ToolBarButton toolBarButton5 = new ToolBarButton();
	ToolBarButton toolBarButton6 = new ToolBarButton();
	ListView listView1 = new ListView();
	MenuItem menuItem6 = new MenuItem();
	MenuItem menuItem7 = new MenuItem();
	MenuItem menuItem19 = new MenuItem();
	MenuItem menuItem8 = new MenuItem();
	ColumnHeader columnHeader1 = new ColumnHeader();
	ColumnHeader columnHeader2 = new ColumnHeader();
	ColumnHeader columnHeader3 = new ColumnHeader();
	ColumnHeader columnHeader4 = new ColumnHeader();
	ToolBarButton toolBarButton7 = new ToolBarButton();
	MenuItem menuItem22 = new MenuItem();
	MenuItem menuItem23 = new MenuItem();
	MenuItem menuItem24 = new MenuItem();
	MenuItem menuItem25 = new MenuItem();
	MenuItem menuItem26 = new MenuItem();
	GroupBox groupBox1 = new GroupBox();
	ToolBar toolBar2 = new ToolBar();
	ToolBarButton toolBarButton8 = new ToolBarButton();
	ToolBarButton toolBarButton9 = new ToolBarButton();
	ToolBarButton toolBarButton10 = new ToolBarButton();
	ToolBarButton toolBarButton11 = new ToolBarButton();
	ToolBarButton toolBarButton12 = new ToolBarButton();
	ToolBarButton toolBarButton13 = new ToolBarButton();
	ToolBarButton toolBarButton14 = new ToolBarButton();
	ToolBarButton toolBarButton15 = new ToolBarButton();
	ToolBarButton toolBarButton16 = new ToolBarButton();
	ToolBarButton toolBarButton17 = new ToolBarButton();
	ToolBarButton toolBarButton18 = new ToolBarButton();
	ToolBarButton toolBarButton19 = new ToolBarButton();
	ImageList buttonsimagelist = new ImageList();
	MenuItem menuItem27 = new MenuItem();
	Edit edit3 = new Edit();
	CheckBox checkBox1 = new CheckBox();
	ToolBarButton toolBarButton20 = new ToolBarButton();
	MenuItem menuItem28 = new MenuItem();
	MenuItem menuItem29 = new MenuItem();
	MenuItem menuItem10 = new MenuItem();
	MenuItem menuItem30 = new MenuItem();

	private void initForm()
	{
		// NOTE:  This form is storing resource information in an
		// external file.  Do not modify the string parameter to any
		// resources.getObject() function call. For example, do not
		// modify "foo1_location" in the following line of code
		// even if the name of the Foo object changes: 
		//   foo1.setLocation((Point)resources.getObject("foo1_location"));

		IResourceManager resources = new ResourceManager(this, "cups");
		imageList1.setImageStream((ImageListStreamer)resources.getObject("imageList1_imageStream"));
		/* @designTimeOnly imageList1.setLocation(new Point(640, 192)); */

		toolbar1.setDock(ControlDock.FILL);
		toolbar1.setLocation(new Point(9, 34));
		toolbar1.setSize(new Point(512, 26));
		toolbar1.setTabIndex(0);
		toolbar1.setText("toolbar1");
		toolbar1.addOnCalling(new EventHandler(this.toolbar1_calling));

		rebarBand1.setBandBreak(true);
		rebarBand1.setChildControl(toolbar1);
		rebarBand1.setChildEdge(false);
		rebarBand1.setIdealWidth(418);
		rebarBand1.setInitialHeight(42);
		rebarBand1.setMaxInitialHeight(42);
		rebarBand1.setMinChildHeight(26);
		rebarBand1.setWidth(323);

		menuItem11.setEnabled(false);
		menuItem11.setText("&Hangup");
		menuItem11.addOnClick(new EventHandler(this.menuItem11_click));

		menuItem21.setEnabled(false);
		menuItem21.setText("&File...");

		menuItem4.setText("E&xit");
		menuItem4.addOnClick(new EventHandler(this.menuItem4_click));

		menuItem9.setMenuItems(new MenuItem[] {
							   menuItem11});
		menuItem9.setText("&Action");

		menuItem20.setChecked(true);
		menuItem20.setText("&Default");

		menuItem18.setChecked(true);
		menuItem18.setText("&Microphone");
		menuItem18.addOnClick(new EventHandler(this.menuItem18_click));

		menuItem5.setText("-");

		menuItem12.setChecked(true);
		menuItem12.setText("&Save Users");
		menuItem12.addOnClick(new EventHandler(this.menuItem12_click));

		menuItem2.setShortcut(Shortcut.F2);
		menuItem2.setText("Log&in...");
		menuItem2.addOnClick(new EventHandler(this.menuItem2_click));

		statusBarPanel1.setAutoSize(StatusBarPanelAutoSize.SPRING);
		statusBarPanel1.setWidth(231);

		statusBarPanel2.setWidth(50);

		statusBarPanel3.setAutoSize(StatusBarPanelAutoSize.SPRING);
		statusBarPanel3.setWidth(231);

		statusBar1.setBackColor(Color.CONTROL);
		statusBar1.setLocation(new Point(0, 353));
		statusBar1.setSize(new Point(529, 20));
		statusBar1.setTabIndex(3);
		statusBar1.setText("");
		statusBar1.setShowPanels(true);
		statusBar1.setPanels(new StatusBarPanel[] {
							 statusBarPanel1, 
							 statusBarPanel2, 
							 statusBarPanel3});

		menuItem3.setEnabled(false);
		menuItem3.setShortcut(Shortcut.F3);
		menuItem3.setText("Log&out");
		menuItem3.addOnClick(new EventHandler(this.menuItem3_click));

		menuItem1.setMenuItems(new MenuItem[] {
							   menuItem2, 
							   menuItem3, 
							   menuItem12, 
							   menuItem5, 
							   menuItem4});
		menuItem1.setText("&File");

		menuItem17.setShortcut(Shortcut.CTRL_E);
		menuItem17.setText("&Edit User");
		menuItem17.addOnClick(new EventHandler(this.menuItem17_click));

		menuItem14.setShortcut(Shortcut.F5);
		menuItem14.setText("Re&fresh");
		menuItem14.addOnClick(new EventHandler(this.menuItem14_click));

		menuItem15.setShortcut(Shortcut.CTRL_A);
		menuItem15.setText("&Add User");
		menuItem15.addOnClick(new EventHandler(this.menuItem15_click));

		menuItem16.setShortcut(Shortcut.CTRL_DEL);
		menuItem16.setText("&Remove User");
		menuItem16.addOnClick(new EventHandler(this.menuItem16_click));

		menuItem13.setMenuItems(new MenuItem[] {
								menuItem14, 
								menuItem15, 
								menuItem16, 
								menuItem17});
		menuItem13.setText("&Directory");

		toolBarButton1.setImageIndex(2);
		toolBarButton1.setToolTipText("Login");

		toolBarButton2.setEnabled(false);
		toolBarButton2.setImageIndex(3);
		toolBarButton2.setToolTipText("Logout");

		toolBarButton3.setEnabled(false);
		toolBarButton3.setImageIndex(1);
		toolBarButton3.setToolTipText("Hangup");

		toolBarButton4.setImageIndex(4);
		toolBarButton4.setToolTipText("Refresh");

		toolBarButton5.setImageIndex(5);
		toolBarButton5.setToolTipText("Add User");

		toolBarButton6.setImageIndex(6);
		toolBarButton6.setToolTipText("Remove User");

		menuItem19.setEnabled(false);
		menuItem19.setText("&File...");

		menuItem8.setMenuItems(new MenuItem[] {
							   menuItem20, 
							   menuItem21});
		menuItem8.setText("&Output");

		columnHeader1.setText("Username");
		columnHeader1.setWidth(79);

		columnHeader2.setText("Extension");
		columnHeader2.setWidth(69);

		columnHeader3.setText("Location");
		columnHeader3.setWidth(76);

		columnHeader4.setText("Message");
		columnHeader4.setWidth(127);

		listView1.setAnchor(ControlAnchor.ALL);
		listView1.setFont(new Font("MS Sans Serif", 10.0f, FontSize.POINTS, FontWeight.NORMAL, false, false, false, CharacterSet.DEFAULT, 0));
		listView1.setLocation(new Point(0, 68));
		listView1.setSize(new Point(354, 286));
		listView1.setTabIndex(0);
		listView1.setText("listView1");
		listView1.setFullRowSelect(true);
		listView1.setGridLines(true);
		listView1.setHideSelection(false);
		listView1.setSorting(SortOrder.ASCENDING);
		listView1.setView(ViewEnum.REPORT);
		listView1.setColumns(new ColumnHeader[] {
							 columnHeader1, 
							 columnHeader2, 
							 columnHeader3, 
							 columnHeader4});
		listView1.addOnClick(new EventHandler(this.listView1_click));
		listView1.addOnItemActivate(new EventHandler(this.listView1_itemActivate));

		toolBarButton7.setImageIndex(7);
		toolBarButton7.setText("toolBarButton7");
		toolBarButton7.setToolTipText("Edit");

		menuItem22.setText("Clear Users");
		menuItem22.addOnClick(new EventHandler(this.menuItem22_click));

		menuItem24.setText("&Answering Machine Mode");
		menuItem24.addOnClick(new EventHandler(this.menuItem24_click));

		menuItem25.setText("&Play");
		menuItem25.addOnClick(new EventHandler(this.menuItem25_click));

		menuItem26.setText("&Stop");
		menuItem26.addOnClick(new EventHandler(this.menuItem26_click));

		menuItem23.setMenuItems(new MenuItem[] {
								menuItem24, 
								menuItem25, 
								menuItem26});
		menuItem23.setText("&Messages");

		groupBox1.setAnchor(ControlAnchor.TOPBOTTOMRIGHT);
		groupBox1.setLocation(new Point(359, 68));
		groupBox1.setSize(new Point(169, 286));
		groupBox1.setTabIndex(1);
		groupBox1.setTabStop(false);
		groupBox1.setText("Tones");

		toolBarButton8.setImageIndex(1);

		toolBarButton9.setImageIndex(2);

		toolBarButton10.setImageIndex(3);

		toolBarButton11.setImageIndex(4);

		toolBarButton12.setImageIndex(5);

		toolBarButton13.setImageIndex(6);

		toolBarButton14.setImageIndex(7);

		toolBarButton15.setImageIndex(8);

		toolBarButton16.setImageIndex(9);

		toolBarButton17.setImageIndex(11);

		toolBarButton18.setImageIndex(0);

		toolBarButton19.setImageIndex(10);

		buttonsimagelist.setImageSize(new Point(32, 32));
		buttonsimagelist.setImageStream((ImageListStreamer)resources.getObject("buttonsimagelist_imageStream"));
		/* @designTimeOnly buttonsimagelist.setLocation(new Point(216, 324)); */

		toolBar2.setDock(ControlDock.NONE);
		toolBar2.setLocation(new Point(24, 20));
		toolBar2.setSize(new Point(124, 168));
		toolBar2.setTabIndex(0);
		toolBar2.setAppearance(ToolBarAppearance.FLAT);
		toolBar2.setAutoSize(false);
		toolBar2.setButtons(new ToolBarButton[] {
							toolBarButton8, 
							toolBarButton9, 
							toolBarButton10, 
							toolBarButton11, 
							toolBarButton12, 
							toolBarButton13, 
							toolBarButton14, 
							toolBarButton15, 
							toolBarButton16, 
							toolBarButton17, 
							toolBarButton18, 
							toolBarButton19});
		toolBar2.setButtonSize(new Point(40, 40));
		toolBar2.setDivider(false);
		toolBar2.setDropDownArrows(true);
		toolBar2.setImageList(buttonsimagelist);
		toolBar2.setShowToolTips(true);
		toolBar2.addOnButtonClick(new ToolBarButtonClickEventHandler(this.toolBar2_buttonClick));

		menuItem27.setEnabled(false);
		menuItem27.setText("&Text to Speech");
		menuItem27.addOnClick(new EventHandler(this.menuItem27_click));

		menuItem7.setMenuItems(new MenuItem[] {
							   menuItem18, 
							   menuItem19, 
							   menuItem27});
		menuItem7.setText("&Input");

		menuItem6.setMenuItems(new MenuItem[] {
							   menuItem7, 
							   menuItem8, 
							   menuItem22});
		menuItem6.setText("&Edit");

		edit3.setBackColor(Color.SCROLLBAR);
		edit3.setLocation(new Point(16, 192));
		edit3.setSize(new Point(136, 20));
		edit3.setTabIndex(1);
		edit3.setText("");
		edit3.setReadOnly(true);
		edit3.addOnKeyPress(new KeyPressEventHandler(this.edit3_keyPress));

		checkBox1.setLocation(new Point(8, 216));
		checkBox1.setSize(new Point(152, 16));
		checkBox1.setTabIndex(2);
		checkBox1.setText("Protect");
		checkBox1.addOnClick(new EventHandler(this.checkBox1_click));

		toolBarButton20.setImageIndex(8);
		toolBarButton20.setText("toolBarButton8");

		toolBar1.setDock(ControlDock.NONE);
		toolBar1.setLocation(new Point(9, 2));
		toolBar1.setSize(new Point(512, 26));
		toolBar1.setTabIndex(1);
		toolBar1.setAppearance(ToolBarAppearance.FLAT);
		toolBar1.setButtons(new ToolBarButton[] {
							toolBarButton1, 
							toolBarButton2, 
							toolBarButton3, 
							toolBarButton4, 
							toolBarButton5, 
							toolBarButton6, 
							toolBarButton7, 
							toolBarButton20});
		toolBar1.setButtonSize(new Point(26, 24));
		toolBar1.setDivider(false);
		toolBar1.setDropDownArrows(true);
		toolBar1.setImageList(imageList1);
		toolBar1.setTextAlign(ToolBarTextAlign.RIGHT);
		toolBar1.setShowToolTips(true);
		toolBar1.addOnButtonClick(new ToolBarButtonClickEventHandler(this.toolBar1_buttonClick));

		rebarBand2.setBandBreak(true);
		rebarBand2.setChildControl(toolBar1);
		rebarBand2.setChildEdge(false);
		rebarBand2.setIdealWidth(100);
		rebarBand2.setInitialHeight(22);
		rebarBand2.setMaxInitialHeight(32);
		rebarBand2.setMinChildHeight(26);
		rebarBand2.setWidth(221);

		rebar1.setSize(new Point(529, 66));
		rebar1.setTabIndex(2);
		rebar1.setText("rebar1");
		rebar1.setBands(new RebarBand[] {
						rebarBand2, 
						rebarBand1});
		rebar1.setImageList(null);

		menuItem29.setText("&Compact");
		menuItem29.addOnClick(new EventHandler(this.menuItem29_click));

		menuItem10.setText("&Statistics");
		menuItem10.addOnClick(new EventHandler(this.menuItem10_click));

		menuItem28.setMenuItems(new MenuItem[] {
								menuItem29, 
								menuItem10});
		menuItem28.setText("&View");

		menuItem30.setShortcut(Shortcut.F1);
		menuItem30.setShowShortcut(false);
		menuItem30.setText("&Help");
		menuItem30.addOnClick(new EventHandler(this.menuItem30_click));

		mainMenu1.setMenuItems(new MenuItem[] {
							   menuItem1, 
							   menuItem9, 
							   menuItem6, 
							   menuItem13, 
							   menuItem23, 
							   menuItem28, 
							   menuItem30});
		/* @designTimeOnly mainMenu1.setLocation(new Point(640, 216)); */

		this.setText("cups");
		this.setAutoScaleBaseSize(new Point(5, 13));
		this.setClientSize(new Point(529, 373));
		this.setIcon((Icon)resources.getObject("this_icon"));
		this.setKeyPreview(true);
		this.setMenu(mainMenu1);
		this.setStartPosition(FormStartPosition.CENTER_SCREEN);
		this.addOnKeyPress(new KeyPressEventHandler(this.cups_keyPress));
		this.addOnMove(new EventHandler(this.cups_move));
		this.addOnResize(new EventHandler(this.cups_resize));
		this.addOnClosing(new CancelEventHandler(this.cups_closing));

		this.setNewControls(new Control[] {
							groupBox1, 
							statusBar1, 
							listView1, 
							rebar1});
		rebar1.setNewControls(new Control[] {
							  toolBar1, 
							  toolbar1});
		groupBox1.setNewControls(new Control[] {
								 checkBox1, 
								 edit3, 
								 toolBar2});
	}

	/**
	 * The main entry point for the application. 
	 *
	 * @param args Array of parameters passed to the application
	 * via the command line.
	 */
	public static void main(String args[])
	{
		Application.run(new cups());
	}
}
