#include <GDI.h>
#include <math.h>
#include <aygshell.h>
#include <stdlib.h>
#include <strtool.h>
#include <graphics/bitmap.h>

#include "MainFrm.h"
#include "resource.h"
#include "weathersource.h"
#include "weatherinfo.h"

//#define TEST

const WCHAR* CMainFrame::cities[] = {L"Gdansk", L"Krakow", L"Lodz", L"Poznan", L"Warszawa", L"Wroclaw"};

CMainFrame::CMainFrame()
{
    // Set the Resource IDs for the toolbar buttons
    m_ToolbarData.clear();
    m_ToolbarData.push_back(0);         // Separator
    m_ToolbarData.push_back(IDM_REFRESH);
}

BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM /*lParam*/)
{
    switch (LOWORD(wParam))
    {
        case IDM_HELP_ABOUT:
        {
            CDialog HelpDialog(IDW_ABOUT, m_hWnd);
            HelpDialog.DoModal();
        }
        break;

        // Respond to Toolbar buttons
        case IDM_REFRESH:
            break;

        // Respond to the accelerator key
        case IDW_QUIT:
            ::SendMessage(m_hWnd, WM_CLOSE, 0, 0);
            break;
    }

    switch (HIWORD(wParam))
    {
        case CBN_DROPDOWN:
            break;
        case CBN_CLOSEUP:
            updateWeather();
            break;

        case LBN_DBLCLK:
            break;
    }

    return 0;
}

void CMainFrame::OnInitialUpdate()
{
    SHFullScreen(m_hWnd, SHFS_HIDESIPBUTTON);

    RECT r = GetViewRect();

    cbCity.CreateEx(0, L"combobox", L"", WS_CHILD | WS_BORDER | WS_VISIBLE | WS_VSCROLL | CBS_DROPDOWNLIST, 
        r.left+1, r.top+1, r.right-r.left-2, 220, m_hWnd, NULL);
    for (int i(0); i < sizeof(cities)/sizeof(char*); i++)
    {
        ::SendMessage(cbCity, CB_ADDSTRING, 0, (LPARAM)cities[i]);
    }
    cbCity.ShowWindow(SW_SHOW);

    //view.Create(m_hWnd);
    //view.MoveWindow(r.left+1, r.top+22, r.right-r.left-2, 200);
    //view.ShowWindow(SW_SHOW);
}

void CMainFrame::OnPaint(HDC hDC)
{
    WCHAR temp[256];
    Win32xx::GradientFill(hDC, RGB(0, 0, 128), RGB(0, 128, 255), GetViewRect(), true);
    
    if (wInfo.locality.empty())
        return;

    CRect vr = GetViewRect();
    CDC dc(hDC);
    
    LOGFONT font;
    font.lfHeight = (-16 * GetDeviceCaps(hDC, LOGPIXELSY)) / 72; 
    font.lfWidth = 0; 
    font.lfEscapement = 0; 
    font.lfOrientation = 0; 
    font.lfWeight = FW_NORMAL; 
    font.lfItalic = false; 
    font.lfUnderline = false; 
    font.lfStrikeOut = false; 
    font.lfCharSet = DEFAULT_CHARSET; 
    font.lfOutPrecision = OUT_DEFAULT_PRECIS; 
    font.lfClipPrecision = CLIP_DEFAULT_PRECIS; 
    font.lfQuality = ANTIALIASED_QUALITY; 
    font.lfPitchAndFamily = FF_SWISS | DEFAULT_PITCH; 
    wcscpy(font.lfFaceName, TEXT("Arial"));
    dc.CreateFontIndirect(&font);
    
    SetTextAlign(hDC, TA_LEFT | TA_TOP);
    SetTextColor(hDC, RGB(255, 255, 255));
    SetBkMode(hDC, TRANSPARENT);
    int lh = abs(font.lfHeight) + 2;
    
    int cy = 64;
    StrTool::utf8ToUtf16(temp, sizeof(temp)/sizeof(wchar_t), (unsigned char*)wInfo.locality.c_str());
    CRect dr(4, cy, vr.right - 4, cy + 60);
    ::DrawText(hDC, temp, wcslen(temp), &dr, DT_LEFT | DT_TOP | DT_WORDBREAK);
    cy += 2*lh;
    
    StrTool::utf8ToUtf16(temp, sizeof(temp)/sizeof(wchar_t), (unsigned char*)wInfo.condition.c_str());
    if (!wInfo.icon.empty())
    {
        dc.AttachPen((HPEN)::GetStockObject(BLACK_PEN));
        dc.AttachBrush((HBRUSH)::GetStockObject(WHITE_BRUSH));
        ::Rectangle(hDC, 4, cy, 48, cy + 44);
        
        char iconName[256];
        wchar_t uIconName[256];
        sprintf(iconName, "\\images\\%s.png", wInfo.icon.c_str());
        mbstowcs(uIconName, iconName, strlen(iconName)+1);
        Graphics::Bitmap icon(uIconName);
        icon.draw(hDC, 6, cy + 2);
        
        dr = CRect(52, cy, vr.right - 4, cy + 44);
        ::DrawText(hDC, temp, wcslen(temp), &dr, DT_LEFT | DT_TOP | DT_WORDBREAK);
        cy += 2*lh;
    }
    else
    {
        dr = CRect(4, cy, vr.right - 4, cy + 30);
        ::DrawText(hDC, temp, wcslen(temp), &dr, DT_LEFT | DT_TOP | DT_WORDBREAK);
        cy += lh;
    }
    
    StrTool::utf8ToUtf16(temp, sizeof(temp)/sizeof(wchar_t), 
        (unsigned char*)("Temperatura: " + wInfo.temperature + " °C").c_str());
    dr = CRect(4, cy, vr.right - 4, cy + 30);
    ::DrawText(hDC, temp, wcslen(temp), &dr, DT_LEFT | DT_TOP | DT_WORDBREAK);
    cy += lh;
    
    StrTool::utf8ToUtf16(temp, sizeof(temp)/sizeof(wchar_t), (unsigned char*)wInfo.wind.c_str());
    dr = CRect(4, cy, vr.right - 4, cy + 60);
    ::DrawText(hDC, temp, wcslen(temp), &dr, DT_LEFT | DT_TOP | DT_WORDBREAK);
    cy += 2*lh;
    
    StrTool::utf8ToUtf16(temp, sizeof(temp)/sizeof(wchar_t), (unsigned char*)wInfo.humidity.c_str());
    dr = CRect(4, cy, vr.right - 4, cy + 30);
    ::DrawText(hDC, temp, wcslen(temp), &dr, DT_LEFT | DT_TOP | DT_WORDBREAK);
        
    HFONT hFont = dc.DetachFont();
    DeleteObject(hFont);
}

LRESULT CMainFrame::WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    // handle left mouse button up/down and mouse move messages
    // a seperate function for each case keeps the code tidy.
    switch (uMsg)
    {
        case WM_LBUTTONDOWN:
            break;
        case WM_MOUSEMOVE:
            break;
        case WM_LBUTTONUP:
            break;
    }

    // Pass unhandled messages on to WndProcDefault
    return WndProcDefault(hwnd, uMsg, wParam, lParam);
}

void CMainFrame::updateWeather()
{
    char city[256];
    wchar_t utemp[256];
    char temp[256];
    
    int itemIdx = ::SendMessage(cbCity, CB_GETCURSEL, 0, 0);
    ::SendMessage(cbCity, CB_GETLBTEXT, itemIdx, (LPARAM)utemp);
    wcstombs(city, utemp, wcslen(utemp));
    WeatherInfo wi;

#ifdef TEST
    strcpy(temp, "\\Storage Card\\weather.xml");
    if (WeatherInfo::parse(temp, wi) && !wi.locality.empty())
    {
        wInfo = wi;
        InvalidateRect((LPRECT)GetClientRect(), FALSE);
    }
#else
    //GetTempPath(sizeof(utemp)/sizeof(wchar_t), utemp);
    //wcstombs(temp, utemp, wcslen(utemp));
    strcpy(temp, "\\weather.xml");
    
    if (WeatherSource::getWeather(city, temp))
    {
	    if (WeatherInfo::parse(temp, wi) && !wi.locality.empty())
	    {
	        wInfo = wi;
	        InvalidateRect((LPRECT)GetClientRect(), FALSE);
	    }
    }
#endif
}

