#include once "window9.bi"

Extern As Long ERROR_COLOR

Dim Shared As HBRUSH hBrush
Dim Shared As Long iColorBg,iColorFg
Dim Shared f_move_splitter_callback As Sub (w  As Any Ptr , iCurPos As Long )
Dim Shared f_size_allocate_splitter_callback As Sub (widget  As Any Ptr , ix As Long , iy As Long , iw As Long , ih As Long)
dim shared as HCURSOR hCursorGor , hCursorVert
hCursorGor = LoadCursor(NULL, IDC_SIZEWE) ' gor
hCursorVert = LoadCursor(NULL, IDC_SIZENS) ' vert

#Ifndef FBIDSCROLLBAR
    #Define FBIDSCROLLBAR 5
#EndIf

#Ifndef FBIDCOMBOLBOX
    #Define FBIDCOMBOLBOX 13
#EndIf

private Function wndproc(byval hwnd As HWND, byval msg As UINT, byval wparam As WPARAM, byval lparam As LPARAM) As LRESULT
    Select Case Msg
        Case WM_CTLCOLORSTATIC,WM_CTLCOLOREDIT,WM_CTLCOLORLISTBOX,WM_CTLCOLORSCROLLBAR
            Var GETGadgetClassCOMBO_and_SCROLLBAR=win9GetGadgetClass(Cast(HWND,lparam))
            If GETGadgetClassCOMBO_and_SCROLLBAR=FBIDCOMBOLBOX Then
                SetBkColor(Cast(HDC,wparam),iColorBg)
                SetTextColor(Cast(HDC,wParam),iColorFg)
                Return Cast(Integer,hBrush) ' !!!
            Else
                Static As  COLORREF iColorBackup
                Static As hwnd hwndBackup
                Static As Integer iMsgBackup
                Dim As Integer iColorTemp
                If GETGadgetClassCOMBO_and_SCROLLBAR=FBIDSCROLLBAR And GetGadgetColor(lparam,4)=0 Then
                    iColorTemp = &hf0f0f0
                Else
                    iColorTemp=GetGadgetColor(lparam,3)
                EndIf
                If ERROR_COLOR=0 Then
                    If iColorTemp<>iColorBackup Or hwndBackup<>hWnd Or iMsgBackup<>msg Then
                        iColorBackup=iColorTemp
                        hwndBackup = hWnd
                        iMsgBackup = msg
                        DeleteObject(hBrush)
                        hBrush= CreateSolidBrush(iColorBackup)
                        SetBkColor(Cast(HDC,wparam),iColorBackup)
                    Else
                        SetBkColor(Cast(HDC,wparam),iColorBackup)
                    EndIf
                    SetTextColor(Cast(HDC,wParam),Cast(COLORREF,GetGadgetColor(lparam,4)))
                Else
                    ERROR_COLOR=0
                EndIf
            EndIf
            
            Return Cast(integer,hBrush) ' !!!
        Case WM_SIZE,WM_ACTIVATE,WM_SETFOCUS,WM_KILLFOCUS,WM_CLOSE,WM_NOTIFY, _
            WM_KEYDOWN,WM_KEYUP,WM_SYSKEYDOWN,WM_SYSKEYUP, _
            WM_COMMAND,WM_SYSCOMMAND,WM_TIMER,WM_HSCROLL,WM_VSCROLL, _
            WM_MENUSELECT,WM_DROPFILES, _
            WM_MOUSEMOVE, _
            WM_LBUTTONUP,WM_LBUTTONDBLCLK, _
            WM_RBUTTONUP,WM_RBUTTONDBLCLK, _
            WM_MBUTTONUP,WM_MBUTTONDBLCLK, _ 
            WM_HOTKEY,WM_USER,WM_PAINT,WM_VKEYTOITEM
            if msg = WM_MOUSEMOVE then
                dim as HWND gIDPan = getprop(hwnd , "HANDLEPAN")
                dim as long iStyle  = cint(getprop(hwnd , "STYLEPAN"))
                if Ismouseover(gIDPan) Orelse getprop(hwnd , "SPLITTERMOVE") Then
                    if iStyle then
                        SetCursor(hCursorGor)
                    else
                        SetCursor(hCursorVert)
                    EndIf
                    If ((wParam = MK_LBUTTON) Andalso getprop(hwnd , "SPLITTERMOVE")) Then
                        Dim As RECT rect
                        GetClientRect(hwnd, @rect)
                        If iStyle andalso ((Loword(lParam)+3 > rect.Right) orelse Loword(lParam) < 0) Then
                            Return 0
                        elseif iStyle=0 andalso ((Hiword(lParam)+3 > rect.Bottom) orelse Hiword(lParam) < 0) Then
                            Return 0
                        EndIf
                        if iStyle then
                            setprop(hwnd , "POSITIONPAN" , cast(any ptr,cint(Loword(lParam))))
                            If f_move_splitter_callback Then
                                f_move_splitter_callback( hwnd , Loword(lParam))
                            Endif
                        else
                            setprop(hwnd , "POSITIONPAN" , cast(any ptr,cint(Hiword(lParam))))
                            If f_move_splitter_callback Then
                                f_move_splitter_callback( hwnd , Hiword(lParam))
                            Endif                            
                        EndIf
                        SendMessage(hWnd, WM_SIZE, 100, MAKELPARAM(rect.Right, rect.bottom))
                    Endif
                    SendMessage(GetParent(Hwnd),msg,wparam,lparam)
                    return 0
                EndIf
            elseif msg = WM_SIZE then
                dim as Long iPos = cint(getprop(hwnd , "POSITIONPAN"))
                dim as long iStyle  = cint(getprop(hwnd , "STYLEPAN"))
                If (wParam <> SIZE_MINIMIZED) then
                    if iStyle andalso Loword(lParam) < iPos then
                        iPos = Loword(lParam) - 10
                    elseif iStyle = 0 andalso hiword(lParam) < iPos then
                        iPos = Hiword(lParam) - 10
                    EndIf
                Endif
                setprop(hwnd , "POSITIONPAN" , cast(any ptr,cint(iPos)))
                dim as Long iGadgetChild1 = cint(getprop(hwnd , "GADGET1"))
                dim as Long iGadgetChild2 = cint(getprop(hwnd , "GADGET2"))
                if iGadgetChild1 andaLSO iGadgetChild2 then
                    dim as Long iGadgetSplitter = id_in_number(hwnd)
                    dim as HWND gIDPan = getprop(hwnd , "HANDLEPAN")
                    dim as Long iW = gadgetwidth(iGadgetSplitter) , iH = gadgetheight(iGadgetSplitter)
                    if iStyle = 0 then ' vert
                        resizegadget(iGadgetChild1 , 0 , 0, iW , iPos)
                        resizegadget(iGadgetChild2 , 0 , iPos+3, iW , iH-(iPos+3))
                        MoveWindow(gIDPan, 0 , iPos ,iW , 3, True)
                    else
                        resizegadget(iGadgetChild1 , 0 , 0, iPos , iH)
                        resizegadget(iGadgetChild2 , iPos+3 , 0, iW-(iPos+3) , iH)
                        MoveWindow(gIDPan, iPos , 0 , 3 , iH, True)
                    EndIf
                    if f_size_allocate_splitter_callback andalso wParam = 0 then
                        f_size_allocate_splitter_callback(hwnd , gadgetX(iGadgetSplitter) , gadgety(iGadgetSplitter) , iW , iH)
                    endif
                endif
            elseif Msg = WM_LBUTTONUP then
                ReleaseCapture()
                setprop(hwnd , "SPLITTERMOVE" , cast(any ptr , cint(0)))
            EndIf
            SendMessage(GetParent(Hwnd),msg,wparam,lparam)
        Case WM_LBUTTONDOWN,WM_RBUTTONDOWN,WM_MBUTTONDOWN
            SetProp(GetParent(Hwnd),"eventmousebutton",cast(handle,1))
            SendMessage(GetParent(Hwnd),msg,wparam,lparam)
            if Msg = WM_LBUTTONDOWN then
                dim as HWND gIDPan = getprop(hwnd , "HANDLEPAN")
                dim as long iStyle  = cint(getprop(hwnd , "STYLEPAN"))
                If Ismouseover(gIDPan) Then
                    if iStyle then
                        SetCursor(hCursorGor)
                    else
                        SetCursor(hCursorVert)
                    EndIf
                    setprop(hwnd , "SPLITTERMOVE" , cast(any ptr , cint(1)))
                    SetCapture(hWnd)
                Endif
                Return 0
            endif
    End Select
    Return DefWindowProc(hwnd,msg,wparam,lparam)
End Function

Dim Shared NameClass As USTRING
Function RegClassSplitter() As BOOL
    Dim As WNDCLASSEX wc
    Static n As Integer
    NameClass="SplitterGadget" & n
    n+=1
    With wc
        .cbSize=SizeOf(WNDCLASSEX)
        .style=CS_HREDRAW Or CS_VREDRAW
        .lpfnWndProc=@wndproc
        .hInstance=GetModuleHandle(0)
        .hbrBackground=Cast(HBRUSH,COLOR_WINDOW)
        #ifdef UNICODE
            .lpszClassName=*NameClass
        #else	
            .lpszClassName=StrPtr(NameClass)
        #EndIf
        .hCursor = LoadCursor(0,IDC_ARROW)
    End With
    If RegisterClassEx(@wc)=0 Then
        Print "Register error, press any key"
        Return 0
    EndIf
    Return 1
End Function

Function SplitterGadget(iGadget As Long , iX As Long , iY As Long , iWidth As Long ,_
iHeight As Long, iPos As Long , iStyle As Long = 0) As HWND Export
    RegClassSplitter()
    #ifdef UNICODE
        Dim gID As HWND=CreateWindowEx(0,*NameClass,"", WS_VISIBLE Or WS_CHILD or WS_CLIPCHILDREN, iX,iY,iWidth,iHeight, Cast(HWND,win9GetCurrent()), Cast(HMENU,CInt(iGadget)),0,0)	
    #else	
        Dim gID As HWND=CreateWindowEx(0,strptr(NameClass),"", WS_VISIBLE Or WS_CHILD or WS_CLIPCHILDREN, iX,iY,iWidth,iHeight, Cast(HWND,win9GetCurrent()), Cast(HMENU,CInt(iGadget)),0,0)
    #EndIf
    if iPos > iWidth then
        iPos = iWidth
    EndIf
    if iPos < 0 then
        iPos = 0
    EndIf
    
    Dim gIDPan As HWND
    if iStyle = 0 then ' vert
        gIDPan = CreateWindowEx(0,"static","", WS_VISIBLE Or WS_CHILD , 0,iPos,iWidth,3, Cast(HWND,gID), 0,0,0)
    else
        gIDPan = CreateWindowEx(0,"static","", WS_VISIBLE Or WS_CHILD , iPos,0,3,iHeight, Cast(HWND,gID), 0,0,0)	
    EndIf
    setprop(gID , "HANDLEPAN" , gIDPan)
    setprop(gID , "POSITIONPAN" , cast(any ptr,cint(iPos)))
    setprop(gID , "STYLEPAN" , cast(any ptr,cint(iStyle)))
    win9AddNewGadget(iGadget,gID)
    win9AddColor(gID,&hf0f0f0,0)
    UseGadgetList(gID)
    Return gID
End Function

Sub SplitterGadgetAddGadget(iGadgetSplitter As Long , iGadgetChild1 As Long , iGadgetChild2 As Long) Export
    
    dim as HWND gID = gadgetid(iGadgetSplitter)
    dim as HWND gFirstWinPan = gadgetid(iGadgetChild1)
    dim as HWND gSecondWinPan = gadgetid(iGadgetChild2)
    
    if gID andalso gFirstWinPan andalso gSecondWinPan then
        
        dim as HWND gIDPan = getprop(gID , "HANDLEPAN")
        dim as Long iPos = cint(getprop(gID , "POSITIONPAN"))
        dim as long iStyle  = cint(getprop(gID , "STYLEPAN"))
        
        setprop(gID , "GADGET1" , cast(any ptr , cint(iGadgetChild1)))
        setprop(gID , "GADGET2" , cast(any ptr , cint(iGadgetChild2)))
        
        if iStyle = 0 then ' vert
            resizegadget(iGadgetChild1 , 0 , 0, gadgetwidth(iGadgetSplitter) , iPos)
            resizegadget(iGadgetChild2 , 0 , iPos+3, gadgetwidth(iGadgetSplitter) , gadgetheight(iGadgetSplitter)-(iPos+3))
        else
            resizegadget(iGadgetChild1 , 0 , 0, iPos , gadgetheight(iGadgetSplitter))
            resizegadget(iGadgetChild2 , iPos+3 , 0, gadgetwidth(iGadgetSplitter)-(iPos+3) , gadgetheight(iGadgetSplitter))
        EndIf
        
    EndIf
    
End Sub

sub SplitterGadgetUnMapGadget(iGadgetSplitter as Long  , iParam as Long)
    
    dim as HWND gID = gadgetid(iGadgetSplitter)
    if gID then
        if iParam = 1 then
            freegadget(cint(getprop(gID , "GADGET1")))
            setprop(gID , "GADGET1" , cast(any ptr , cint(0)))
        elseif iParam = 2 then
            freegadget(cint(getprop(gID , "GADGET2")))
            setprop(gID , "GADGET2" , cast(any ptr , cint(0)))
        EndIf
    EndIf
    
End Sub

sub SplitterGadgetMapGadget(iGadgetSplitter as Long  , iGadget as Long , iParam as Long)
    
    dim as HWND gID = gadgetid(iGadgetSplitter)
    dim as HWND gGadget = gadgetid(iGadget)
    
    if gID andalso gGadget then
        setparent(gGadget , gID)
        if iParam = 1 then
            setprop(gID , "GADGET1" , cast(any ptr , cint(iGadget)))
        elseif iParam = 2 then
            setprop(gID , "GADGET2" , cast(any ptr , cint(iGadget)))            
        EndIf
        SendMessage(gID, WM_SIZE, 100, MAKELPARAM(gadgetwidth(iGadgetSplitter), gadgetheight(iGadgetSplitter)))
    EndIf
    
End Sub

Sub AddCallbackSplitterPosition(pFunc As Any Ptr)
    
    f_move_splitter_callback = pFunc
    
End Sub

Sub AddCallbackSplitterResize(pFunc As Any Ptr)
    
    f_size_allocate_splitter_callback = pFunc
    
End Sub

sub SetSplitterPos(iGadgetSplitter as Long , iPos as Long)
    
    dim as HWND gID = gadgetid(iGadgetSplitter)
    
    if gID then
        dim as HWND gIDPan = getprop(gID , "HANDLEPAN")
        dim as Long iGadgetChild1 = cint(getprop(gID , "GADGET1"))
        dim as Long iGadgetChild2 = cint(getprop(gID , "GADGET2"))
        setprop(gID , "POSITIONPAN" , cast(any ptr , cint(iPos)))
        sendmessage(gID , WM_SIZE , 100, MAKELPARAM(gadgetwidth(iGadgetSplitter), gadgetheight(iGadgetSplitter)))
    EndIf
    
End Sub

function GetSplitterPos(iGadgetSplitter as Long) as LONG
    dim as HWND gID = gadgetid(iGadgetSplitter)
    if gID then
        return cint(Getprop(gID , "POSITIONPAN"))
    EndIf
End Function