/*
 * OleView (pane.c)
 *
 * Copyright 2006 Piotr Caban
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
 */

#include "main.h"

static int GetSplitPos(HWND hWnd)
{
    PANE *pane = (PANE *)GetMenu(hWnd);

    if(pane->pos < pane->size/2+1) pane->pos = pane->size/2+1;

    return (pane->width>pane->pos+pane->size/2+1 ?
            pane->pos : pane->width-pane->size/2-1);
}

static void DrawSplitMoving(HWND hWnd, int x)
{
    RECT rt;
    HDC hdc = GetDC(hWnd);
    PANE *pane = (PANE *)GetMenu(hWnd);

    GetClientRect(hWnd, &rt);

    if(pane->last!=-1)
    {
        rt.left = pane->last-pane->size/2;
        rt.right = pane->last+pane->size/2;
        InvertRect(hdc, &rt);
    }

    pane->pos = x>MAX_WINDOW_WIDTH ? -1 : x;
    x = GetSplitPos(hWnd);

    pane->pos = x;
    rt.left = x-pane->size/2;
    rt.right = x+pane->size/2;
    pane->last = x;
    InvertRect(hdc, &rt);

    ReleaseDC(hWnd, hdc);
}

static LRESULT CALLBACK PaneProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
    POINT pt;
    PANE *pane = (PANE*)GetMenu(hWnd);

    switch(uMsg)
    {
        case WM_SETCURSOR:
            GetCursorPos(&pt);
            ScreenToClient(hWnd, &pt);

            if(pt.x >= GetSplitPos(hWnd)-pane->size/2 &&
                    pt.x <= GetSplitPos(hWnd)+pane->size/2)
                SetCursor(LoadCursor(0, IDC_SIZEWE));
            break;
        case WM_LBUTTONDOWN:
            if((short)LOWORD(lParam) >= GetSplitPos(hWnd)-pane->size/2 &&
               (short)LOWORD(lParam) <= GetSplitPos(hWnd)+pane->size/2)
            {
                pane->last = -1;
                DrawSplitMoving(hWnd, (short)LOWORD(lParam));
                SetCapture(hWnd);
            }
            break;
        case WM_LBUTTONUP:
            if(GetCapture() == hWnd)
            {
                pane->last = -1;
                DrawSplitMoving(hWnd, (short)LOWORD(lParam));

                MoveWindow(pane->left, 0, 0,
                        GetSplitPos(hWnd)-pane->size/2, pane->height, TRUE);
                MoveWindow(pane->right, GetSplitPos(hWnd)+pane->size/2, 0,
                        pane->width-GetSplitPos(hWnd)-pane->size/2, pane->height, TRUE);

                ReleaseCapture();
            }
            break;
        case WM_MOUSEMOVE:
            if(GetCapture() == hWnd)
                DrawSplitMoving(hWnd, (short)LOWORD(lParam));
            break;
        case WM_NOTIFY:
            if((int)wParam != TYPELIB_TREE) break;
            switch(((LPNMHDR)lParam)->code)
            {
                case TVN_SELCHANGED:
                    UpdateData(((NMTREEVIEW *)lParam)->itemNew.hItem);
                    break;
            }
            break;
        case WM_SIZE:
            if(wParam == SIZE_MINIMIZED) break;
            pane->width = LOWORD(lParam);
            pane->height = HIWORD(lParam);

            MoveWindow(pane->left, 0, 0,
                    GetSplitPos(hWnd)-pane->size/2, HIWORD(lParam), TRUE);
            MoveWindow(pane->right, GetSplitPos(hWnd)+pane->size/2, 0,
                    LOWORD(lParam)-GetSplitPos(hWnd)-pane->size/2,
                    HIWORD(lParam), TRUE);
            break;
        case WM_DESTROY:
            HeapFree(GetProcessHeap(), 0, pane);
            break;
        default:
            return DefWindowProc(hWnd, uMsg, wParam, lParam);
    }
    return 0;
}

BOOL PaneRegisterClass(void)
{
    WNDCLASS wcc;
    const WCHAR wszPaneClass[] = { 'P','A','N','E','\0' };

    memset(&wcc, 0, sizeof(WNDCLASS));
    wcc.lpfnWndProc = PaneProc;
    wcc.hbrBackground = (HBRUSH)(COLOR_WINDOW);
    wcc.lpszClassName = wszPaneClass;

    if(!RegisterClass(&wcc))
        return FALSE;
    return TRUE;
}

BOOL CreatePanedWindow(HWND hWnd, HWND *hWndCreated, HINSTANCE hInst)
{
    const WCHAR wszPaneClass[] = { 'P','A','N','E','\0' };
    PANE *pane;

    pane = HeapAlloc(GetProcessHeap(), 0, sizeof(PANE));
    *hWndCreated = CreateWindow(wszPaneClass, NULL, WS_CHILD|WS_VISIBLE,
            CW_USEDEFAULT, CW_USEDEFAULT, 0, 0,    hWnd, (HMENU)pane, hInst, NULL);
    if(!hWndCreated)
    {
        HeapFree(GetProcessHeap(), 0, pane);
        return FALSE;
    }

    pane->left = NULL;
    pane->right = NULL;
    pane->pos = 300;
    pane->size = 5;
    
    return TRUE;
}

void SetLeft(HWND hParent, HWND hWnd)
{
    PANE *pane = (PANE *)GetMenu(hParent);
    pane->left = hWnd;
}

void SetRight(HWND hParent, HWND hWnd)
{
    PANE *pane = (PANE *)GetMenu(hParent);
    pane->right = hWnd;
}
