/*
    Copyright 2005-2010 Intel Corporation.  All Rights Reserved.

    This file is part of Threading Building Blocks.

    Threading Building Blocks is free software; you can redistribute it
    and/or modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

    Threading Building Blocks 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 Threading Building Blocks; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA

    As a special exception, you may use this file as part of a free software
    library without restriction.  Specifically, if other files instantiate
    templates or use macros or inline functions from this file, or you compile
    this file and link it with other files to produce an executable, this
    file does not by itself cause the resulting executable to be covered by
    the GNU General Public License.  This exception does not however
    invalidate any other reasons why the executable file might be covered by
    the GNU General Public License.
*/

/////// Common internal implementation of Windows-specific stuff //////////////
///////                  Must be the first included header       //////////////

#ifndef _CRT_SECURE_NO_DEPRECATE
#define _CRT_SECURE_NO_DEPRECATE
#endif
// Check that the target Windows version has all API calls requried.
#ifndef _WIN32_WINNT
# define _WIN32_WINNT 0x0400
#endif
#if _WIN32_WINNT<0x0400
# define YIELD_TO_THREAD() Sleep(0)
#else
# define YIELD_TO_THREAD() SwitchToThread()
#endif
#include "video.h"
#include <fcntl.h>
#include <io.h>
#include <iostream>
#include <fstream>

#pragma comment(lib, "gdi32.lib")
#pragma comment(lib, "user32.lib")

// maximum mumber of lines the output console should have
static const WORD MAX_CONSOLE_LINES = 500;
const COLORREF              RGBKEY = RGB(8, 8, 16); // at least 8 for 16-bit palette
HWND                        g_hAppWnd;           // The program's window handle
HANDLE                      g_handles[2] = {0,0};// thread and wake up event
unsigned int *              g_pImg = 0;          // drawing memory
int                         g_sizex, g_sizey;
static video *              g_video = 0;
WNDPROC                     g_pUserProc = 0;
HINSTANCE                   video::win_hInstance = 0;
int                         video::win_iCmdShow = 0;
static WNDCLASSEX *         gWndClass = 0;
static HACCEL               hAccelTable = 0;
static DWORD                g_msec = 0;
static int g_fps = 0, g_updates = 0, g_skips = 0;

bool DisplayError(LPSTR lpstrErr, HRESULT hres = 0); // always returns false
LRESULT CALLBACK InternalWndProc(HWND hwnd, UINT iMsg, WPARAM wParam, LPARAM lParam);

//! Create window
bool WinInit(HINSTANCE hInstance, int nCmdShow, WNDCLASSEX *uwc, const char *title, bool fixedsize)
{
    WNDCLASSEX wndclass;  // Our app's windows class
    if(uwc) {
        memcpy(&wndclass, uwc, sizeof(wndclass));
        g_pUserProc = uwc->lpfnWndProc;
    } else {
        memset(&wndclass, 0, sizeof(wndclass));
        wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
        wndclass.lpszClassName = title;
    }
    wndclass.cbSize = sizeof(wndclass);
    wndclass.hInstance = hInstance;
    wndclass.lpfnWndProc = InternalWndProc;
    wndclass.style |= CS_HREDRAW | CS_VREDRAW;
    wndclass.hbrBackground = CreateSolidBrush(RGBKEY);

    if( !RegisterClassExA(&wndclass) ) return false;
    int xaddend = GetSystemMetrics(fixedsize?SM_CXFIXEDFRAME:SM_CXFRAME)*2;
    int yaddend = GetSystemMetrics(fixedsize?SM_CYFIXEDFRAME:SM_CYFRAME)*2 + GetSystemMetrics(SM_CYCAPTION);
    if(wndclass.lpszMenuName) yaddend += GetSystemMetrics(SM_CYMENU);

    // Setup the new window's physical parameters - and tell Windows to create it
    g_hAppWnd = CreateWindowA(wndclass.lpszClassName,  // Window class name
                             title,  // Window caption
                             !fixedsize ? WS_OVERLAPPEDWINDOW :  // Window style
                             WS_OVERLAPPED|WS_CAPTION|WS_SYSMENU|WS_MINIMIZEBOX,
                             CW_USEDEFAULT,  // Initial x pos: use default placement
                             0,              // Initial y pos: not used here
                             g_sizex+xaddend,// Initial x size
                             g_sizey+yaddend,// Initial y size
                             NULL,      // parent window handle
                             NULL,      // window menu handle
                             hInstance, // program instance handle
                             NULL);     // Creation parameters
    return g_hAppWnd != NULL;
}

//! create console window with redirection
static bool RedirectIOToConsole(void)
{
    int hConHandle; size_t lStdHandle;
    CONSOLE_SCREEN_BUFFER_INFO coninfo;
    FILE *fp;
    // allocate a console for this app
    AllocConsole();

    // set the screen buffer to be big enough to let us scroll text
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
    coninfo.dwSize.Y = MAX_CONSOLE_LINES;
    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);

    // redirect unbuffered STDOUT to the console
    lStdHandle = (size_t)GetStdHandle(STD_OUTPUT_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    if(hConHandle <= 0) return false;
    fp = _fdopen( hConHandle, "w" );
    *stdout = *fp;
    setvbuf( stdout, NULL, _IONBF, 0 );

    // redirect unbuffered STDERR to the console
    lStdHandle = (size_t)GetStdHandle(STD_ERROR_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    if(hConHandle > 0) {
        fp = _fdopen( hConHandle, "w" );
        *stderr = *fp;
        setvbuf( stderr, NULL, _IONBF, 0 );
    }

    // redirect unbuffered STDIN to the console
    lStdHandle = (size_t)GetStdHandle(STD_INPUT_HANDLE);
    hConHandle = _open_osfhandle(lStdHandle, _O_TEXT);
    if(hConHandle > 0) {
        fp = _fdopen( hConHandle, "r" );
        *stdin = *fp;
        setvbuf( stdin, NULL, _IONBF, 0 );
    }

    // make cout, wcout, cin, wcin, wcerr, cerr, wclog and clog
    // point to console as well
    std::ios::sync_with_stdio();
    return true;
}


video::video()
    : red_mask(0xff0000), red_shift(16), green_mask(0xff00),
      green_shift(8), blue_mask(0xff), blue_shift(0), depth(24)
{
    assert(g_video == 0);
    g_video = this; title = "Video"; running = threaded = calc_fps = false; updating = true;
}

//! optionally call it just before init() to set own 
void video::win_set_class(WNDCLASSEX &wcex)
{
    gWndClass = &wcex;
}

void video::win_load_accelerators(int idc)
{
    hAccelTable = LoadAccelerators(win_hInstance, MAKEINTRESOURCE(idc));
}

bool video::init_console()
{
    if(RedirectIOToConsole()) {
        if(!g_pImg && g_sizex && g_sizey)
            g_pImg = new unsigned int[g_sizex * g_sizey];
        if(g_pImg) running = true;
        return true;
    }
    return false;
}

video::~video()
{
    if(g_video) terminate();
}

DWORD WINAPI thread_video(LPVOID lpParameter)
{
    video *v = (video*)lpParameter;
    v->on_process();
    return 0;
}

static bool loop_once(video *v)
{
    // screen update notify
    if(int updates = g_updates) {
        g_updates = 0;
        if(g_video->updating) { g_skips += updates-1; g_fps++; }
        else g_skips += updates;
        UpdateWindow(g_hAppWnd);
    }
    // update fps
    DWORD msec = GetTickCount();
    if(v->calc_fps && msec >= g_msec+1000) {
        double sec = (msec - g_msec)/1000.0;
        char buffer[256], n = _snprintf(buffer, 128, "%s: %d fps", v->title, int(double(g_fps + g_skips)/sec));
        if(g_skips) _snprintf(buffer+n, 128, " - %d skipped = %d updates", int(g_skips/sec), int(g_fps/sec));
        SetWindowTextA(g_hAppWnd, buffer);
        g_msec = msec; g_skips = g_fps = 0;
    }
    // event processing, including painting
    MSG msg;
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
    {
        if( msg.message == WM_QUIT ) { v->running = false; return false; }
        if( !hAccelTable || !TranslateAccelerator(msg.hwnd, hAccelTable, &msg) )
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
        return true; // try again
    }
    return false;
}

//! Do standard event loop
void video::main_loop()
{
    // let Windows draw and unroll the window
    InvalidateRect(g_hAppWnd, 0, false);
    g_msec = GetTickCount(); // let's stay for 0,5 sec
    while(g_msec + 500 > GetTickCount()) { loop_once(this); Sleep(1); }
    g_msec = GetTickCount();
    // now, start main process
    if(threaded) {
        g_handles[0] = CreateThread (
            NULL,             // LPSECURITY_ATTRIBUTES security_attrs
            0,                // SIZE_T stacksize
            (LPTHREAD_START_ROUTINE) thread_video,
            this,               // argument
            0, 0);
        if(!g_handles[0]) { DisplayError("Can't create thread"); return; }
        else // harmless race is possible here
            g_handles[1] = CreateEvent(NULL, false, false, NULL);
        while(running) {
            while(loop_once(this));
            YIELD_TO_THREAD(); // give time for processing when running on single CPU
            DWORD r = MsgWaitForMultipleObjects(2, g_handles, false, INFINITE, QS_ALLINPUT^QS_MOUSEMOVE);
            if(r == WAIT_OBJECT_0) break; // thread terminated
        }
        running = false;
        if(WaitForSingleObject(g_handles[0], 300) == WAIT_TIMEOUT)
            TerminateThread(g_handles[0], 0);
        if(g_handles[0]) CloseHandle(g_handles[0]);
        if(g_handles[1]) CloseHandle(g_handles[1]);
        g_handles[0] = g_handles[1] = 0;
    }
    else on_process();
}

//! Refresh screen picture
bool video::next_frame()
{
    if(!running) return false;
    g_updates++; // Fast but inaccurate counter. The data race here is benign.
    if(!threaded) while(loop_once(this));
    else if(g_handles[1]) {
        SetEvent(g_handles[1]);
        YIELD_TO_THREAD();
    }
    return true;
}

//! Change window title
void video::show_title()
{
    if(g_hAppWnd)
        SetWindowTextA(g_hAppWnd, title);
}
