/*
    Robot Interface
    (C) 2006 Jason Hunt
    nulluser@gmail.com
    
    File: main.cpp
*/

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

#include "main.h"
#include "display.h"
#include "input.h"
#include "camera.h"
#include "network.h"
#include "robot.h"
#include "config.h"
#include "serial.h"
#include "joystick.h"
#include "time.h"
#include "utility.h"
#include "automode.h"


#define UPDATE_TIMER            1           // ID for update timer
#define SECOND_TIMER            2           // ID for update timer

#define UPDATE_TIME             10          //  Period for update timer


/* Runs when program starts is created */
void system_start(HWND hwnd)
{
    display_start();

    debug_start();
    time_start();

    load_config("config.txt");

    robot.start();

    camera.start(hwnd);
    network_start(hwnd);        
    joystick_start();

    automode_start();
    
    SetTimer(hwnd, UPDATE_TIMER, UPDATE_TIME, NULL);  
    SetTimer(hwnd, SECOND_TIMER, 1000, NULL);  
}
/* End of system_startup */


/* Runs when window is closed */
void system_stop(void)
{
    automode_stop();
    
    camera.stop();
    robot.stop();
    network_stop();        


    PostQuitMessage(0);
}
/* End of system_shutdown */



/* Deal with the system timer */
void timer_message(HWND hwnd, WPARAM w)
{
    if (w == UPDATE_TIMER)
    {
        network_check();
        joystick_check();
        input_check();
        update_display(hwnd);

        InvalidateRect(hwnd, NULL, 0);                        
    } else
    if (w  == SECOND_TIMER)
    {
        camera.update();
    }    
}   
/* End of timer message */


/* Ehe message handler */
LRESULT CALLBACK WinProc(HWND hwnd, UINT message, WPARAM w, LPARAM l)
{
    switch (message)                 
    {
        case WM_CREATE:      
            system_start(hwnd);                
            setup_display(hwnd);  
            return(0);

        case WM_TIMER: timer_message(hwnd, w);    
            return(0);

        case WM_DESTROY: 
            system_stop();
            return(0);

        case WM_CHAR:
            if (w == 27) DestroyWindow(hwnd);  
            if (w == 'c') camera.setup_camera(hwnd, true);  
            
            return(0);
            
        case WM_KEYDOWN:    
            input_key_down(w, l); 
            return(0);
                  
        case WM_KEYUP:     
            input_key_up(w);     
            return(0);
                 
        case WM_PAINT:    
            do_paint(hwnd);     
            return(0);
                       
        case WM_NETEVENT:  
            network_message(w, l); 
            return(0);

        case WM_KILLFOCUS:
            input_lose_focus();
            return(0);

        case WM_SIZE:
            resize_display(hwnd, l);
            return(0);

        default: return DefWindowProc (hwnd, message, w, l);
    }

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


/* WinMain */
int WINAPI WinMain(HINSTANCE h_this_inst, HINSTANCE h_prev_inst, LPSTR args, int mode)
{
    WNDCLASS wnd_class;

    char class_name[] = "RobotTest";
       
    wnd_class.hInstance = h_this_inst;
    wnd_class.lpszClassName = class_name;
    wnd_class.lpfnWndProc = WinProc;
    wnd_class.style = 0;
    
    wnd_class.hIcon = LoadIcon(NULL, IDI_APPLICATION);
    wnd_class.hCursor = LoadCursor(NULL, IDC_ARROW);
    wnd_class.lpszMenuName = NULL;
    
    wnd_class.cbClsExtra = 0;
    wnd_class.cbWndExtra = 0;
    
    wnd_class.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
    
    if (!RegisterClass(&wnd_class)) return(0);
        
    // Create the window
    HWND hwnd = CreateWindow(class_name, "Robot Server (C) 2006 Jason Hunt", 
                             WS_CAPTION  | WS_SYSMENU | WS_MINIMIZEBOX ,
                             200, 200,   // Pos
                             display_x, display_y+20,   // Size
                             HWND_DESKTOP, NULL, h_this_inst, NULL);

    ShowWindow(hwnd, mode);
    UpdateWindow(hwnd);
           
    MSG msg;
        
    // Windows message loop
    while(GetMessage(&msg, NULL, 0, 0))
    { 
        TranslateMessage(&msg);
        DispatchMessage(&msg);                            
    }
                                                                        
    return(msg.wParam);
}
/* End of winmain */


