Index: client/Client/main.cpp
===================================================================
--- client/Client/main.cpp	(revision 439f7bc1eec5d0b56344db9cc23399640026dba2)
+++ client/Client/main.cpp	(revision 87b3ee2526ba9b73d93862e48b4d519434148b39)
@@ -18,5 +18,4 @@
 #include <string>
 #include <iostream>
-#include <vector>
 
 #include <allegro5/allegro.h>
@@ -26,4 +25,7 @@
 #include "../../common/message.h"
 
+#include "Window.h"
+#include "Textbox.h"
+#include "Button.h"
 #include "chat.h"
 
@@ -36,5 +38,12 @@
 void initWinSock();
 void shutdownWinSock();
-void processMessage(NETWORK_MSG &msg, int &state, chat &chatConsole, string &username);
+void processMessage(NETWORK_MSG &msg, int &state, chat &chatConsole);
+
+// callbacks
+void registerAccount();
+void login();
+void logout();
+void quit();
+void sendChatMessage();
 
 void error(const char *);
@@ -53,7 +62,25 @@
 enum STATE {
    STATE_START,
-   STATE_LOGIN,
-   STATE_LOGOUT
+   STATE_LOGIN // this means you're already logged in
 };
+
+int state;
+
+bool doexit;
+
+Window* wndLogin;
+Window* wndMain;
+Window* wndCurrent;
+
+Textbox* txtUsername;
+Textbox* txtPassword;
+Textbox* txtChat;
+
+int sock;
+struct sockaddr_in server, from;
+struct hostent *hp;
+NETWORK_MSG msgTo, msgFrom;
+string username;
+chat chatConsole;
  
 int main(int argc, char **argv)
@@ -63,13 +90,12 @@
    ALLEGRO_TIMER *timer = NULL;
    ALLEGRO_BITMAP *bouncer = NULL;
+   bool key[4] = { false, false, false, false };
+   bool redraw = true;
+   doexit = false;
+
    float bouncer_x = SCREEN_W / 2.0 - BOUNCER_SIZE / 2.0;
    float bouncer_y = SCREEN_H / 2.0 - BOUNCER_SIZE / 2.0;
-   bool key[4] = { false, false, false, false };
-   bool redraw = true;
-   bool doexit = false;
-
-   int state = STATE_START;
-
-   chat chatConsole;
+
+   state = STATE_START;
 
    if(!al_init()) {
@@ -78,4 +104,5 @@
    }
 
+   al_init_primitives_addon();
    al_init_font_addon();
    al_init_ttf_addon();
@@ -93,4 +120,9 @@
       return -1;
    }
+
+    if(!al_install_mouse()) {
+      fprintf(stderr, "failed to initialize the mouse!\n");
+      return -1;
+   }
  
    timer = al_create_timer(1.0 / FPS);
@@ -106,5 +138,24 @@
       return -1;
    }
- 
+
+   wndLogin = new Window(0, 0, SCREEN_W, SCREEN_H);
+   wndLogin->addComponent(new Textbox(104, 40, 100, 20, font));
+   wndLogin->addComponent(new Textbox(104, 70, 100, 20, font));
+   wndLogin->addComponent(new Button(22, 100, 90, 20, font, "Register", registerAccount));
+   wndLogin->addComponent(new Button(122, 100, 60, 20, font, "Login", login));
+   wndLogin->addComponent(new Button(540, 10, 80, 20, font, "Quit", quit));
+
+   txtUsername = (Textbox*)wndLogin->getComponent(0);
+   txtPassword = (Textbox*)wndLogin->getComponent(1);
+
+   wndMain = new Window(0, 0, SCREEN_W, SCREEN_H);
+   wndMain->addComponent(new Textbox(95, 40, 525, 20, font));
+   wndMain->addComponent(new Button(95, 70, 160, 20, font, "Send Message", sendChatMessage));
+   wndMain->addComponent(new Button(540, 10, 80, 20, font, "Logout", logout));
+
+   txtChat = (Textbox*)wndMain->getComponent(0);
+
+   wndCurrent = wndLogin;
+
    bouncer = al_create_bitmap(BOUNCER_SIZE, BOUNCER_SIZE);
    if(!bouncer) {
@@ -131,18 +182,11 @@
  
    al_register_event_source(event_queue, al_get_display_event_source(display));
- 
    al_register_event_source(event_queue, al_get_timer_event_source(timer));
- 
    al_register_event_source(event_queue, al_get_keyboard_event_source());
+   al_register_event_source(event_queue, al_get_mouse_event_source());
  
    al_clear_to_color(al_map_rgb(0,0,0));
  
    al_flip_display();
-
-   int sock;
-   struct sockaddr_in server, from;
-   struct hostent *hp;
-   NETWORK_MSG msgTo, msgFrom;
-   string username;
 
    if (argc != 3) {
@@ -171,6 +215,9 @@
       ALLEGRO_EVENT ev;
       al_wait_for_event(event_queue, &ev);
- 
-      if(ev.type == ALLEGRO_EVENT_TIMER) {
+
+      if(wndCurrent->handleEvent(ev)) {
+         // do nothing
+      }
+      else if(ev.type == ALLEGRO_EVENT_TIMER) {
          if(key[KEY_UP] && bouncer_y >= 4.0) {
             bouncer_y -= 4.0;
@@ -195,81 +242,20 @@
       }
       else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
-         bool eventConsumed = chatConsole.processEvent(ev);
-
-         if (eventConsumed) {
-            string input = chatConsole.getInput();
-            if (!input.empty()) {
-               cout << "input: " << input << endl;
-               strcpy(msgTo.buffer, input.c_str());
-
-               switch(state)
-               {
-                  case STATE_START:
-                  {
-                     username = input;
-                     strcpy(msgTo.buffer+input.size()+1, "MyPassword");
-                     msgTo.type = MSG_TYPE_REGISTER;
-                     //msgTo.type = MSG_TYPE_LOGIN;
-
-                     sendMessage(&msgTo, sock, &server);
-                     receiveMessage(&msgFrom, sock, &from);
-                     processMessage(msgFrom, state, chatConsole, username);
-                     cout << "state: " << state << endl;
-
-                     break;
-                  }
-                  case STATE_LOGIN:
-                  {
-                     if (input.compare("quit") == 0 ||
-                         input.compare("exit") == 0 ||
-                         input.compare("logout") == 0)
-                     {
-                        strcpy(msgTo.buffer, username.c_str());
-                        msgTo.type = MSG_TYPE_LOGOUT;
-                     }
-                     else
-                        msgTo.type = MSG_TYPE_CHAT;
-
-                     sendMessage(&msgTo, sock, &server);
-                     receiveMessage(&msgFrom, sock, &from);
-                     processMessage(msgFrom, state, chatConsole, username);
-                     cout << "state: " << state << endl;
-
-                     break;
-                  }
-                  case STATE_LOGOUT:
-                  {
-                     chatConsole.addLine("You're logged out, so you can't send any messages to the server.");
-
-                     cout << "You're logged out, so you can't send any messages to the server." << endl;
-                  
-                     break;
-                  }
-                  default:
-                  {
-                     cout << "The state has an invalid value: " << state << endl;
-                  
-                     break;
-                  }
-               }
-            }
-         }else {
-            switch(ev.keyboard.keycode) {
-               case ALLEGRO_KEY_UP:
-                  key[KEY_UP] = true;
-                  break;
- 
-               case ALLEGRO_KEY_DOWN:
-                  key[KEY_DOWN] = true;
-                  break;
- 
-               case ALLEGRO_KEY_LEFT: 
-                  key[KEY_LEFT] = true;
-                  break;
- 
-               case ALLEGRO_KEY_RIGHT:
-                  key[KEY_RIGHT] = true;
-                  break;
-            }
+         switch(ev.keyboard.keycode) {
+            case ALLEGRO_KEY_UP:
+               key[KEY_UP] = true;
+               break;
+ 
+            case ALLEGRO_KEY_DOWN:
+               key[KEY_DOWN] = true;
+               break;
+ 
+            case ALLEGRO_KEY_LEFT: 
+               key[KEY_LEFT] = true;
+               break;
+ 
+            case ALLEGRO_KEY_RIGHT:
+               key[KEY_RIGHT] = true;
+               break;
          }
       }
@@ -301,9 +287,17 @@
          redraw = false;
  
-         al_clear_to_color(al_map_rgb(0,0,0));
+         wndCurrent->draw(display);
  
          al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0);
 
          chatConsole.draw(font, al_map_rgb(255,255,255));
+
+         if(wndCurrent == wndLogin) {
+            al_draw_text(font, al_map_rgb(0, 255, 0), 4, 43, ALLEGRO_ALIGN_LEFT, "Username:");
+            al_draw_text(font, al_map_rgb(0, 255, 0), 1, 73, ALLEGRO_ALIGN_LEFT, "Password:");
+         }
+         else if(wndCurrent == wndMain) {
+            al_draw_text(font, al_map_rgb(0, 255, 0), 4, 43, ALLEGRO_ALIGN_LEFT, "Message:");
+         }
 
          al_flip_display();
@@ -319,4 +313,7 @@
    shutdownWinSock();
    
+   delete wndLogin;
+   delete wndMain;
+
    al_destroy_event_queue(event_queue);
    al_destroy_bitmap(bouncer);
@@ -360,5 +357,5 @@
 }
 
-void processMessage(NETWORK_MSG &msg, int &state, chat &chatConsole, string &username)
+void processMessage(NETWORK_MSG &msg, int &state, chat &chatConsole)
 {
    string response = string(msg.buffer);
@@ -372,16 +369,31 @@
          chatConsole.addLine(response);
 
-         /*
-         if (response.compare("Player has already logged in.") == 0)
+         switch(msg.type)
          {
-            cout << "User login failed" << endl;
-            username.clear();
-         }
-         else
-         {
-            cout << "User login successful" << endl;
-            state = STATE_LOGIN;
-         }
-         */
+            case MSG_TYPE_REGISTER:
+            {
+               break;
+            }
+            case MSG_TYPE_LOGIN:
+            {
+               if (response.compare("Player has already logged in.") == 0)
+               {
+                  username.clear();
+                  cout << "User login failed" << endl;
+               }
+               else if (response.compare("Incorrect username or password") == 0)
+               {
+                  username.clear();
+                  cout << "User login failed" << endl;
+               }
+               else
+               {
+                  state = STATE_LOGIN;
+                  wndCurrent = wndMain;
+                  cout << "User login successful" << endl;
+               }
+               break;
+            }
+         }
 
          break;
@@ -391,20 +403,27 @@
          chatConsole.addLine(response);
 
-         if (response.compare("You have successfully logged out. You may quit the game.") == 0)
+          switch(msg.type)
          {
-            cout << "Logged out" << endl;
-            state = STATE_LOGOUT;
-         }
-         else
-         {
-            cout << "Added new line" << endl;
+            case MSG_TYPE_REGISTER:
+            {
+               break;
+            }
+            case MSG_TYPE_LOGIN:
+            {
+               if (response.compare("You have successfully logged out.") == 0)
+               {
+                  cout << "Logged out" << endl;
+                  state = STATE_START;
+                  wndCurrent = wndLogin;
+               }
+               else
+               {
+                  cout << "Added new line" << endl;
+               }
+
+               break;
+            }
          }
                      
-         break;
-      }
-      case STATE_LOGOUT:
-      {
-         cout << "Bug: You're logged out, so you shouldn't be receiving any messages." << endl;
-                  
          break;
       }
@@ -417,2 +436,74 @@
    }
 }
+
+void registerAccount()
+{
+   string username = txtUsername->getStr();
+   string password = txtPassword->getStr();
+
+   txtUsername->clear();
+   txtPassword->clear();
+
+   msgTo.type = MSG_TYPE_REGISTER;
+
+   strcpy(msgTo.buffer, username.c_str());
+   strcpy(msgTo.buffer+username.size()+1, password.c_str());
+
+   sendMessage(&msgTo, sock, &server);
+   receiveMessage(&msgFrom, sock, &from);
+   processMessage(msgFrom, state, chatConsole);
+   cout << "state: " << state << endl;
+}
+
+void login()
+{
+   string strUsername = txtUsername->getStr();
+   string strPassword = txtPassword->getStr();
+   username = strUsername;
+
+   txtUsername->clear();
+   txtPassword->clear();
+
+   msgTo.type = MSG_TYPE_LOGIN;
+
+   strcpy(msgTo.buffer, strUsername.c_str());
+   strcpy(msgTo.buffer+username.size()+1, strPassword.c_str());
+
+   sendMessage(&msgTo, sock, &server);
+   receiveMessage(&msgFrom, sock, &from);
+   processMessage(msgFrom, state, chatConsole);
+   cout << "state: " << state << endl;
+}
+
+void logout()
+{
+   txtChat->clear();
+
+   msgTo.type = MSG_TYPE_LOGOUT;
+
+   strcpy(msgTo.buffer, username.c_str());
+
+   sendMessage(&msgTo, sock, &server);
+   receiveMessage(&msgFrom, sock, &from);
+   processMessage(msgFrom, state, chatConsole);
+}
+
+void quit()
+{
+   doexit = true;
+}
+
+void sendChatMessage()
+{
+   string msg = txtChat->getStr();
+
+   txtChat->clear();
+
+   msgTo.type = MSG_TYPE_CHAT;
+
+   strcpy(msgTo.buffer, msg.c_str());
+
+   sendMessage(&msgTo, sock, &server);
+   receiveMessage(&msgFrom, sock, &from);
+   processMessage(msgFrom, state, chatConsole);
+}
