# This file is part of GNU Enterprise.
#
# GNU Enterprise is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public
# License as published by the Free Software Foundation; either
# version 3, or (at your option) any later version.
#
# GNU Enterprise 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 program; see the file COPYING. If not,
# write to the Free Software Foundation, Inc., 59 Temple Place
# - Suite 330, Boston, MA 02111-1307, USA.
#
# Copyright 2000-2009 Free Software Foundation
#
# $Id: wrappers.py 9956 2009-10-11 18:54:57Z reinhard $
#
# DESCRIPTION:
# A PyWin32 based user interface driver for GNUe forms.
#
# NOTES:
#

import array
import struct

import win32gui
import win32con
import win32api
import commctrl

from gnue.forms.uidrivers.win32.widgets._base import UIHelper, Win32Window, Win32Page
from gnue.forms.uidrivers.win32.common import *


class ScrollableWrapper(Win32Window):
    def __init__(self, uiform):
        self.uiform = uiform
        self.frame = frame = uiform.mainWindow
        self.form = form = uiform._form

        formWidth = int(form._layout.Char__width)
        formHeight = int(form._layout.Char__height)

        style = win32con.WS_OVERLAPPED | win32con.WS_CHILD #| win32con.WS_BORDER
                   #win32con.WS_VSCROLL | win32con.WS_HSCROLL
        styleEx = 0
        self.sw=Win32Window(self.uiform._uiDriver, styleEx, self.uiform._uiDriver._wndclass, "ScrollableWrapper", style,
            2,
            self.uiform.buttonbarHeight+4,
            max(formWidth*uiform._uiDriver.widgetWidth, self.uiform.buttonbarWidth)+8,
            #formWidth*uiform._uiDriver.widgetWidth+8,
            formHeight*uiform._uiDriver.widgetHeight+self.uiform.tabHeight,
            frame)

        self._fitted = 0
        self._pageList = []


    def finalize(self):
        # This is the initial panel window setup during init
        # not a wxPanel set per page right after this
        self.sw.Show()


    def OnFrameSize(self, event):
        pass

    def fixScrollbars(self):
        pass


#
# Notebook pages
#
class TabbedWrapper(ScrollableWrapper):
    tabHeight = 0

    def __init__(self, *args, **parms):
        ScrollableWrapper.__init__(self, *args, **parms)
        formWidth = int(self.form._layout.Char__width)
        formHeight = int(self.form._layout.Char__height)
        hinst = win32api.GetModuleHandle(None)
        tabstyle  = _tabStyles[self.form._layout.tabbed]
        style = win32con.WS_CHILD | commctrl.TCS_TABS | tabstyle #| win32con.WS_BORDER
        styleEx = 0
        self.pane = Win32Window(self.uiform._uiDriver, styleEx, commctrl.WC_TABCONTROL, "tabcontrol", style,
            2,
            2,
            max(formWidth*self.uiform._uiDriver.widgetWidth+6, self.uiform.buttonbarWidth-16),
            formHeight*self.uiform._uiDriver.widgetHeight+self.uiform.tabHeight-6,
            self.sw, getNextId(), hinst)

        self.pane.Show()

    def createPage(self, object):
        pszText = "%s" % (object.caption or object.name)
        buff = array.array('c', textEncode(pszText) + "\0")
        addrText = buff.buffer_info()[0]
        tab=struct.pack("iilliii", commctrl.TCIF_TEXT | commctrl.TCIF_STATE, 0, 0, addrText, 0, 0, -1)
        icount = win32gui.SendMessage(self.pane.GetHwnd(), commctrl.TCM_GETITEMCOUNT, 0, 0)
        win32gui.SendMessage(self.pane.GetHwnd(), commctrl.TCM_INSERTITEM, icount, tab)

        l,t,r,b = win32gui.GetWindowRect(self.pane.GetHwnd())

        buff = array.array('i', [0,0,0,0])
        addrBuff = buff.buffer_info()[0]
        win32gui.SendMessage(self.pane.GetHwnd(), commctrl.TCM_GETITEMRECT, 1, addrBuff)
        self.tabWidth = buff[2]-buff[0]
        self.tabHeight = buff[3]-buff[1]

        if self.form._layout.tabbed == 'top':
            x, y, w, h = 2, self.tabHeight+3, r-l-5, b-t-self.tabHeight-6

        elif self.form._layout.tabbed == 'bottom':
            x, y, w, h = 2, 2, r-l-5, b-t-self.tabHeight-6

        elif self.form._layout.tabbed == 'left':
            x, y, w, h = self.tabWidth+3, 3, r-l-30, b-t-6

        elif self.form._layout.tabbed == 'right':
            x, y, w, h = 2, 2, r-l-30, b-t-6


        style = win32con.WS_OVERLAPPED | win32con.WS_CHILD #| win32con.WS_BORDER
        styleEx = 0
        newWidget = Win32Page(self.uiform._uiDriver, styleEx, self.uiform._uiDriver._wndclass, "tabbedPage", style,
            x,
            y,
            w,
            h,
            self.pane, getNextId())

        # Only show first page
        if not self._fitted:
            newWidget.Show()
        else:
            newWidget.Hide()

        self._pageList.append(newWidget)
        self.fit()
        return newWidget

    def fit(self):
        if self._fitted: return
        self._fitted = 1

    def setPage(self, page):
        pageId = self._pageList.index(page)
        win32gui.SendMessage(self.pane.GetHwnd(), commctrl.TCM_SETCURSEL, pageId, 0)

        for p in self._pageList:
            if p != page:
                p.Hide()
            else:
                p.Show()


#
# Single pages        win32con.CW_USEDEFAULT,
#
class PlainWrapper(ScrollableWrapper):
    def __init__(self, *args, **parms):

        ScrollableWrapper.__init__(self, *args, **parms)
        formWidth = int(self.form._layout.Char__width)
        formHeight = int(self.form._layout.Char__height)
    
        style = win32con.WS_OVERLAPPED | win32con.WS_CHILD #| win32con.WS_BORDER
        styleEx = 0
        self.pane = Win32Window(self.uiform._uiDriver, styleEx, self.uiform._uiDriver._wndclass, "PlainWrapper", style,
            0,
            0,
            max(formWidth*self.uiform._uiDriver.widgetWidth, self.uiform.buttonbarWidth)+8,
            formHeight*self.uiform._uiDriver.widgetHeight,
            self.sw, getNextId())

        self.pane.Show()

    def createPage(self, object):

        formWidth = int(self.form._layout.Char__width)
        formHeight = int(self.form._layout.Char__height)
        style = win32con.WS_OVERLAPPED | win32con.WS_CHILD #| win32con.WS_BORDER
        styleEx = 0
        newWidget = Win32Page(self.uiform._uiDriver, styleEx, self.uiform._uiDriver._wndclass, "plainPage", style,
            0,
            0,
            max(formWidth*self.uiform._uiDriver.widgetWidth, self.uiform.buttonbarWidth)+8,
            formHeight*self.uiform._uiDriver.widgetHeight,
            self.pane, getNextId())

        # Only show first page
        if not self._fitted:
            newWidget.Show()
        else:
            newWidget.Hide()

        self._pageList.append(newWidget)
        self.fit()
        return newWidget


    def fit(self):
        if self._fitted: return
        self._fitted = 1

    def setPage(self, page):
        for p in self._pageList:
            if p != page:
                p.Hide()
            else:
                p.Show()

_tabStyles = {'left':commctrl.TCS_MULTILINE | commctrl.TCS_VERTICAL,
                    'right':commctrl.TCS_MULTILINE | commctrl.TCS_VERTICAL | commctrl.TCS_RIGHT,
                    'bottom':commctrl.TCS_BOTTOM,
                    'top':0,
                   }
