import com.nttdocomo.ui.*;
import com.nttdocomo.io.*;
import javax.microedition.io.*;
import java.io.*;
import java.util.*;

public class A extends IApplication {
	// ------------------------------------------------------------------
	// データ構造
	// ------------------------------------------------------------------
	
	class Member {
		String name;
		String state;

		Member(String name, String state) {
			this.name = name;
			this.state = state;
		}
	}
	class Data {
		String myname = null;
		Vector member = new Vector();
		
		String[] getMemberNamesAndState() {
			String[] names = new String[member.size()];
			for (int i = 0; i < names.length; i++) {
				Member m = (Member)member.elementAt(i);
				names[i] = m.name + " [" + m.state + "]";
			}
			return names;
		}
		String[] getMemberNames() {
			String[] names = new String[member.size()];
			for (int i = 0; i < names.length; i++) {
				Member m = (Member)member.elementAt(i);
				names[i] = m.name;
			}
			return names;
		}
		int getMemberLength() {
			return member.size();
		}
	}
	Data data;

	class Message {
		String name;
		String message;

		Message(String name, String message) {
			this.name = name;
			this.message = message;
		}
	}
	
	// ------------------------------------------------------------------
	// データの永続化
	// ------------------------------------------------------------------
	
	final int SP_DATA_POS = 0;
	void writeData(Data data) {
		try {
			OutputStream os = Connector.openOutputStream("scratchpad:///0;pos=" + SP_DATA_POS);
			writeString(os, data.myname);
			os.write(data.member.size());
			for (int i = 0; i < data.member.size(); i++) {
				Member member = (Member)data.member.elementAt(i);
				writeString(os, member.name);
				writeString(os, member.state);
			}
		} catch (Exception e) {
		}
	}
	void writeString(OutputStream os, String s) throws Exception {
		os.write(s.length());
		os.write(s.getBytes());
	}
	
	Data readData() {
		InputStream is = null;
		try {
			is = Connector.openInputStream("scratchpad:///0;pos=" + SP_DATA_POS);
			
			Data data = new Data();
			data.myname = readString(is);
			if (data.myname == null)
				return null;
			int n = is.read();
			for (int i = 0; i < n; i++) {
				Member member = new Member(readString(is), readString(is));
				data.member.addElement(member);
			}
			is.close();
			return data;
		} catch (Exception e) {
			try {
				if (is != null)
					is.close();
			} catch (Exception e2) {
			}
		}
		return null; // エラー時にはnullを返す
	}
	String readString(InputStream is) throws Exception {
		int len = is.read();
		if (len == 0)
			return null;
		byte[] b = new byte[len];
		int off = 0;
		for (;;) {
			int n = is.read(b, off, len);
			if (n < 0)
				return null;
			off += n;
			len -= n;
			if (len == 0)
				break;
		}
		return new String(b);
	}
	
	// ------------------------------------------------------------------
	// サーバとの通信（ダミー実装）
	// ------------------------------------------------------------------
	
	class Network {
		boolean sendInit(String myname) { // IDを受け取る
			System.out.println("sendInit(\"" + myname + "\")");
			return true;
		}
		Message[] update(Data data) { // 定期的に
			System.out.println("changeData(data)");
			if (data.member.size() == 0) { // データがないのでテストデータを作成する
				for (int i = 0; i < 4; i++) {
					Member member = new Member("テスト" + i, "仕事中");
					data.member.addElement(member);
				}
			}
			Message[] message = new Message[2];
			for (int i = 0; i < message.length; i++) {
				message[i] = new Message("テスト" + i, "メッセージ" + i);
			}
			return message;
		}
		void sendState(String myname, String state) {
			System.out.println("sendMessage(\"" + myname + "\", \"" + state + "\")");
		}
		void sendMessage(String myname, String toname, String mes) {
			System.out.println("sendMessage(\"" + myname + "\", \"" + toname + "\", \"" + mes + "\")");
		}
	}
	Network network = new Network();
	
	// ------------------------------------------------------------------
	// 各パネルの実装
	// ------------------------------------------------------------------

	class InitPanel extends Panel implements SoftKeyListener {
		TextBox name;
		InitPanel() {
			data = readData();
			if (data != null) {
				new StateViewPanel();
				return;
			}

			setTitle("初回登録");
			
			add(new Label("名前"));
			name = new TextBox("", 20, 1, TextBox.DISPLAY_ANY);
			add(name);
			
			setSoftLabel(Frame.SOFT_KEY_1, "ＯＫ");
			setSoftKeyListener(this);
			Display.setCurrent(this);
		}
		public void softKeyPressed(int key) {
			if (key == Frame.SOFT_KEY_1) {
				String myname = name.getText();
				network.sendInit(myname);
				data = new Data();
				data.myname = myname;
				writeData(data);
				new StateViewPanel();
			}
		}
		public void softKeyReleased(int key) {
		}
	}

	class StateViewPanel extends Panel implements SoftKeyListener, Runnable {
		ListBox memberview;
		StateViewPanel() {
			setTitle("ビジネスＩＭ");
			
			memberview = new ListBox(ListBox.SINGLE_SELECT, 6);
			memberview.setItems(data.getMemberNames());
			add(memberview);

			// ソフトキーのラベルを設定し、ソフトキー受け取りを有効にする
			setSoftLabel(Frame.SOFT_KEY_1, "状態"); // 状態変更
			setSoftLabel(Frame.SOFT_KEY_2, "送信");  // メッセージ送信
			setSoftKeyListener(this);
			Display.setCurrent(this);
			
			// 一定時間置きに更新するスレッドを起動する
			new Thread(this).start();
		}
		public void softKeyPressed(int key) {
			if (key == Frame.SOFT_KEY_1) { // 状態変更
				new ChangeStatePanel(this);
			} else if (key == Frame.SOFT_KEY_2) { // メッセージ送信
				new SendMessagePanel(this);
			}
		}
		public void softKeyReleased(int key) {
		}
		
		// 一定時間置きに更新するスレッド処理
		public void run() {
			for (;;) {
				if (Display.getCurrent() == this) {
					Message[] message = network.update(data); // dataを更新する
					writeData(data); // dataをスクラッチパッドに書き出す
					memberview.setItems(data.getMemberNames()); // dataを画面に反映する
					new ReceiveMessagePanel(this, message);
				}
				try {
					Thread.sleep(10 * 1000); // 10秒待ち
				} catch (Exception e) {
				}
			}
		}
	}

	class ChangeStatePanel extends Panel implements SoftKeyListener {
		Panel back;
		
		ListBox state;
		String[] STATE_LIST = { "仕事中", "休憩中", "会議中", "外出中", "帰宅" };
		ChangeStatePanel(Panel back) {
			this.back = back;

			setTitle("状態変更");
			
			add(new Label("状態"));
			state = new ListBox(ListBox.CHOICE);
			state.setItems(STATE_LIST);
			state.select(0);
			add(state);
			
			setSoftLabel(Frame.SOFT_KEY_1, "ＯＫ");
			setSoftLabel(Frame.SOFT_KEY_2, "中止");
			setSoftKeyListener(this);
			Display.setCurrent(this);
		}
		public void softKeyPressed(int key) {
			if (key == Frame.SOFT_KEY_1) {
				String st = state.getItem(state.getSelectedIndex());
				network.sendState(data.myname, st);
			}
			Display.setCurrent(back);
		}
		public void softKeyReleased(int key) {
		}
	}
	
	class SendMessagePanel extends Panel implements SoftKeyListener {
		Panel back;
		
		ListBox to;
		ListBox mes;
		
		String[] MESSAGE_LIST = { "電話求む", "メール読め", "助けて", "いいよ", "やだね" };
		SendMessagePanel(Panel back) {
			this.back = back;
			
			setTitle("メッセージ送信");
			
			add(new Label("送り先"));
			to = new ListBox(ListBox.CHOICE);
			String[] names = data.getMemberNames();
			if (names.length == 0) // メンバーが０なら何もせず終わる
				return;
			to.setItems(names);
			to.select(0);
			add(to);

			add(new Label("送信メッセージ"));
			mes = new ListBox(ListBox.CHOICE);
			mes.setItems(MESSAGE_LIST);
			mes.select(0);
			add(mes);
			
			setSoftLabel(Frame.SOFT_KEY_1, "ＯＫ");
			setSoftLabel(Frame.SOFT_KEY_2, "中止");
			setSoftKeyListener(this);
			Display.setCurrent(this);
		}
		
		public void softKeyPressed(int key) {
			if (key == Frame.SOFT_KEY_1) {
				String message = mes.getItem(mes.getSelectedIndex());
				String toname = to.getItem(to.getSelectedIndex());
				network.sendMessage(data.myname, toname, message);
			}
			Display.setCurrent(back);
		}
		public void softKeyReleased(int key) {
		}
	}

	class ReceiveMessagePanel extends Panel implements SoftKeyListener {
		Panel back;
		
		Message[] message;
		
		ReceiveMessagePanel(Panel back, Message[] message) {
			this.back = back;
			this.message = message;
			if (message.length == 0)
				return;
			
			setTitle("メッセージ受信");
			
			add(new Label("送り主"));
			add(new TextBox(message[0].name, 20, 1, TextBox.DISPLAY_ANY));

			add(new Label("受信メッセージ"));
			add(new TextBox(message[0].message, 20, 1, TextBox.DISPLAY_ANY));
			
			setSoftLabel(Frame.SOFT_KEY_1, "ＯＫ");
			setSoftKeyListener(this);
			Display.setCurrent(this);
		}
		
		public void softKeyPressed(int key) {
			if (key == Frame.SOFT_KEY_1) {
				if (message.length > 1) { // 表示すべきメッセージがあれば
					Message[] m = new Message[message.length - 1];
					System.arraycopy(message, 1, m, 0, m.length);
					Display.setCurrent(new ReceiveMessagePanel(back, m));
				} else { // 表示すべきメッセージがなければ戻る
					Display.setCurrent(back);
				}
			}
		}
		public void softKeyReleased(int key) {
		}
	}
	// ------------------------------------------------------------------
	// iアプリの開始メソッド
	// ------------------------------------------------------------------
	public void start() {
		new InitPanel();
	}
}
