/*
    ORPP Client

    (C) 2005 Jason Hunt

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; either version 2
    of the License, or (at your option) any later version.

    This program is distributed in the hope that it will be useful
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    Contact: huntjas2@msu.edu

    Compile with -lwsock32

    FILE: client.cpp
*/


#include <windows.h>
#include <stdio.h>

#pragma hdrstop

#include "version.h"
#include "resource.h"
#include "client.h"
#include "display.h"
#include "network.h"
#include "camera.h"
#include "window.h"
#include "key.h"
#include "mouse.h"
#include "log.h"

#define SEND_KEEP_ALIVE_TIME 100 // time in ms to set the keep alive data

HWND main_win = NULL;            // keep track of the main window

unsigned int window_active = 0;


/* ran when window is created */
void system_startup(HWND hwnd)
{
    addlog("**** Program startup ****");
    
    setup_buffer(); // setup image buffers

    reset_keys(); // clear set keys
    
    // setup keep alive timer
    if(SetTimer(hwnd, ID_KEEP_ALIVE, SEND_KEEP_ALIVE_TIME, NULL) == 0)
        add_line("Unable to set timer");
        
    // setup second timer
    if(SetTimer(hwnd, ID_SECOND, 1000, NULL) == 0)
        add_line("Unable to set timer");

    startup_network(hwnd);  // start the network
                
    add_line(VERSION);
}
/* end of system_startup */


/* ran when window is closed */
void system_shutdown(void)
{
    send_value(0x64); 

    shutdown_network();     // close network connections
    PostQuitMessage(0);     // shutdown application
}
/* end of system_shutdown */


/* deal with the system timer */
void timer_message(WPARAM wParam)
{
    if (wParam == ID_KEEP_ALIVE)
    {
        // tell the server that we are still alive
        if (connected)
            send_keep_alive();
        else
        {
            // try to reconnect
            if (!attempting_connect && !no_connect)
                connect_to_server();
        }
        
        if (!camera_connected && !attempting_camera_connect && !no_connect)
            connect_to_camera_server();
    }

    // one second timer
    if (wParam == ID_SECOND) 
    {
      /* if (camera_connected)
        {
            char b[128];
            sprintf(b, "FPS: %d", frames);
            add_line(b);    
        }*/

        frames = 0; // reset frame counter
    }
}
/* end of timer message */


void check_active(int active)
{
    window_active = active;
    if (window_active == 0)
    {
        add_line("deactivate window");
        stop();
    } else
        add_line("activate window");
}

/* handles menu commands */
void handle_menu( UINT menu_command )
{
    switch(menu_command)
    {
        case IDM_SERVER: get_servername(); break;

        case IDM_CONNECT: connect(); break;

        case IDM_DISCONNECT: disconnect(); break;

        case IDM_STOP: no_connect = 1; break;

        case IDM_EXIT: system_shutdown(); break;

        case IDM_SHUTDOWN: remote_shutdown(); break;
    }
}
/* end of hendle_menu */


/* the message handler */
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)                 
    {
        case WM_CREATE:     system_startup(hwnd);    break;
        case WM_NETEVENT:   control_socket_message(wParam, lParam); break;
        case WM_CAMEVENT:   camera_socket_message(wParam, lParam); break;
        case WM_TIMER:      timer_message(wParam); break;
        case WM_COMMAND:    handle_menu(wParam); break;
        case WM_DESTROY:    system_shutdown(); break;
        case WM_KEYDOWN:    process_key_down(wParam & 0xff); break;
        case WM_KEYUP:      process_key_up(wParam & 0xff); break;
        case WM_MOUSEMOVE:  process_mouse(lParam); break;
        case WM_LBUTTONDOWN:  fire_on(); break;
        case WM_LBUTTONUP:  fire_off(); break;
        
        case WM_PAINT:      display(); break;
        case WM_SIZE:       resize_window(lParam & 0xffff, lParam >> 16); break;
        case WM_ACTIVATEAPP: check_active(wParam); break;
  
        default: return DefWindowProc (hwnd, message, wParam, lParam);
    }

    return(0);
}
/* end of winproc */


/* gets the data from the command line, and loads the variables */
void parse_command_line(LPSTR lpCmdLine)
{
    LPWSTR *szArglist;
    DWORD nArgs;

    szArglist = CommandLineToArgvW(GetCommandLineW(), (int *)&nArgs);

    if (nArgs == 2)
        set_host_name(lpCmdLine);
    else
       set_host_name("justinbox.no-ip.org");
}
/* end of parse command line */


/* winmain */
int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
    clear_text_area(); // clear the buffer so we can add data to it during startup

    parse_command_line(lpCmdLine); // get the command line values before we start up

    // make the main window
    if (setup_window(hinstance, nCmdShow)) return(1);

    MSG messages;

    while (GetMessage (&messages, NULL, 0, 0))
    {
        TranslateMessage(&messages);
        DispatchMessage(&messages);
    }

    return(messages.wParam);
}
/* end of winmain */



