+            # Add the padding to the tab width
+            # Tab width:
+            # +-----------------------------------------------------------+
+            # | PADDING | IMG | IMG_PADDING | TEXT | PADDING | x |PADDING |
+            # +-----------------------------------------------------------+
+
+            tabWidth = self.CalcTabWidth(pageContainer, i, tabHeight)
+            posx = vTabsInfo[cur].x
+
+            # By default we clean the tab region
+            # incase we use the VC8 style which requires
+            # the region, it will be filled by the function
+            # drawVc8Tab
+            pc._pagesInfoVec[i].GetRegion().Clear()
+            
+            # Clean the 'x' buttn on the tab 
+            # 'Clean' rectanlge is a rectangle with width or height
+            # with values lower than or equal to 0
+            pc._pagesInfoVec[i].GetXRect().SetSize(wx.Size(-1, -1))
+
+            # Draw the tab
+            # Incase we are drawing the active tab
+            # we need to redraw so it will appear on top
+            # of all other tabs
+
+            # when using the vc8 style, we keep the position of the active tab so we will draw it again later
+            if i == pc.GetSelection() and pc.HasFlag(FNB_VC8):
+            
+                activeTabPosx = posx
+                activeTabWidth = tabWidth
+                activeTabHeight = tabHeight
+            
+            else:
+            
+                self.DrawTab(pc, dc, posx, i, tabWidth, tabHeight, pc._nTabXButtonStatus)
+            
+            # Restore the text forground
+            dc.SetTextForeground(pc._activeTextColor)
+
+            # Update the tab position & size
+            pc._pagesInfoVec[i].SetPosition(wx.Point(posx, VERTICAL_BORDER_PADDING))
+            pc._pagesInfoVec[i].SetSize(wx.Size(tabWidth, tabHeight))
+        
+        # Incase we are in VC8 style, redraw the active tab (incase it is visible)
+        if pc.GetSelection() >= pc._nFrom and pc.GetSelection() < pc._nFrom + len(vTabsInfo):
+        
+            self.DrawTab(pc, dc, activeTabPosx, pc.GetSelection(), activeTabWidth, activeTabHeight, pc._nTabXButtonStatus)
+        
+        # Update all tabs that can not fit into the screen as non-visible
+        for xx in xrange(pc._nFrom + len(vTabsInfo), len(pc._pagesInfoVec)):
+        
+            pc._pagesInfoVec[xx].SetPosition(wx.Point(-1, -1))
+            pc._pagesInfoVec[xx].GetRegion().Clear()
+        
+        # Draw the left/right/close buttons 
+        # Left arrow
+        self.DrawLeftArrow(pc, dc)
+        self.DrawRightArrow(pc, dc)
+        self.DrawX(pc, dc)
+        self.DrawDropDownArrow(pc, dc)
+
+
+    def DrawTab(self, pageContainer, dc, posx, tabIdx, tabWidth, tabHeight, btnStatus):
+        """ Draws a tab using VC8 style. """
+
+        pc = pageContainer
+        borderPen = wx.Pen(pc._pParent.GetBorderColour())
+        tabPoints = [wx.Point() for ii in xrange(8)]
+
+        # If we draw the first tab or the active tab, 
+        # we draw a full tab, else we draw a truncated tab
+        #
+        #             X(2)                  X(3)
+        #        X(1)                            X(4)
+        #                                          
+        #                                           X(5)
+        #                                           
+        # X(0),(7)                                  X(6)
+        #
+        #
+
+        tabPoints[0].x = (pc.HasFlag(FNB_BOTTOM) and [posx] or [posx+self._factor])[0]
+        tabPoints[0].y = (pc.HasFlag(FNB_BOTTOM) and [2] or [tabHeight - 3])[0]
+
+        tabPoints[1].x = tabPoints[0].x + tabHeight - VERTICAL_BORDER_PADDING - 3 - self._factor
+        tabPoints[1].y = (pc.HasFlag(FNB_BOTTOM) and [tabHeight - (VERTICAL_BORDER_PADDING+2)] or [(VERTICAL_BORDER_PADDING+2)])[0]
+
+        tabPoints[2].x = tabPoints[1].x + 4
+        tabPoints[2].y = (pc.HasFlag(FNB_BOTTOM) and [tabHeight - VERTICAL_BORDER_PADDING] or [VERTICAL_BORDER_PADDING])[0]
+
+        tabPoints[3].x = tabPoints[2].x + tabWidth - 2
+        tabPoints[3].y = (pc.HasFlag(FNB_BOTTOM) and [tabHeight - VERTICAL_BORDER_PADDING] or [VERTICAL_BORDER_PADDING])[0]
+
+        tabPoints[4].x = tabPoints[3].x + 1
+        tabPoints[4].y = (pc.HasFlag(FNB_BOTTOM) and [tabPoints[3].y - 1] or [tabPoints[3].y + 1])[0]
+
+        tabPoints[5].x = tabPoints[4].x + 1
+        tabPoints[5].y = (pc.HasFlag(FNB_BOTTOM) and [(tabPoints[4].y - 1)] or [tabPoints[4].y + 1])[0]
+
+        tabPoints[6].x = tabPoints[2].x + tabWidth
+        tabPoints[6].y = tabPoints[0].y
+
+        tabPoints[7].x = tabPoints[0].x
+        tabPoints[7].y = tabPoints[0].y
+
+        pc._pagesInfoVec[tabIdx].SetRegion(tabPoints)
+
+        # Draw the polygon
+        br = dc.GetBrush()
+        dc.SetBrush(wx.Brush((tabIdx == pc.GetSelection() and [pc._activeTabColor] or [pc._colorTo])[0]))
+        dc.SetPen(wx.Pen((tabIdx == pc.GetSelection() and [wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW)] or [pc._colorBorder])[0]))
+        dc.DrawPolygon(tabPoints)
+
+        # Restore the brush
+        dc.SetBrush(br)
+        rect = pc.GetClientRect()
+
+        if tabIdx != pc.GetSelection() and not pc.HasFlag(FNB_BOTTOM):
+        
+            # Top default tabs
+            dc.SetPen(wx.Pen(pc._pParent.GetBorderColour()))
+            lineY = rect.height
+            curPen = dc.GetPen()
+            curPen.SetWidth(1)
+            dc.SetPen(curPen)
+            dc.DrawLine(posx, lineY, posx+rect.width, lineY)
+        
+        # Incase we are drawing the selected tab, we draw the border of it as well
+        # but without the bottom (upper line incase of wxBOTTOM)
+        if tabIdx == pc.GetSelection():
+        
+            borderPen = wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW))
+            dc.SetPen(borderPen)
+            dc.SetBrush(wx.TRANSPARENT_BRUSH)
+            dc.DrawPolygon(tabPoints)
+
+            # Delete the bottom line (or the upper one, incase we use wxBOTTOM) 
+            dc.SetPen(wx.WHITE_PEN)
+            dc.DrawLine(tabPoints[0].x, tabPoints[0].y, tabPoints[6].x, tabPoints[6].y)
+
+        self.FillVC8GradientColour(pc, dc, tabPoints, tabIdx == pc.GetSelection(), tabIdx)
+
+        # Draw a thin line to the right of the non-selected tab
+        if tabIdx != pc.GetSelection():
+        
+            dc.SetPen(wx.Pen(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE)))
+            dc.DrawLine(tabPoints[4].x-1, tabPoints[4].y, tabPoints[5].x-1, tabPoints[5].y)
+            dc.DrawLine(tabPoints[5].x-1, tabPoints[5].y, tabPoints[6].x-1, tabPoints[6].y)
+        
+        # Text drawing offset from the left border of the 
+        # rectangle
+        
+        # The width of the images are 16 pixels
+        vc8ShapeLen = tabHeight - VERTICAL_BORDER_PADDING - 2
+        if pc.TabHasImage(tabIdx):
+            textOffset = 2*pc._pParent.GetPadding() + 16 + vc8ShapeLen 
+        else:
+            textOffset = pc._pParent.GetPadding() + vc8ShapeLen
+
+        # Draw the image for the tab if any
+        imageYCoord = (pc.HasFlag(FNB_BOTTOM) and [6] or [8])[0]
+
+        if pc.TabHasImage(tabIdx):
+        
+            imageXOffset = textOffset - 16 - pc._pParent.GetPadding()
+            pc._ImageList.Draw(pc._pagesInfoVec[tabIdx].GetImageIndex(), dc,
+                                     posx + imageXOffset, imageYCoord,
+                                     wx.IMAGELIST_DRAW_TRANSPARENT, True)        
+
+        boldFont = wx.SystemSettings_GetFont(wx.SYS_DEFAULT_GUI_FONT)
+            
+        # if selected tab, draw text in bold
+        if tabIdx == pc.GetSelection():
+            boldFont.SetWeight(wx.FONTWEIGHT_BOLD)
+        
+        dc.SetFont(boldFont)
+        dc.DrawText(pc.GetPageText(tabIdx), posx + textOffset, imageYCoord)
+
+        # draw 'x' on tab (if enabled)
+        if pc.HasFlag(FNB_X_ON_TAB) and tabIdx == pc.GetSelection():
+
+            textWidth, textHeight = dc.GetTextExtent(pc.GetPageText(tabIdx))
+            tabCloseButtonXCoord = posx + textOffset + textWidth + 1
+
+            # take a bitmap from the position of the 'x' button (the x on tab button)
+            # this bitmap will be used later to delete old buttons
+            tabCloseButtonYCoord = imageYCoord
+            x_rect = wx.Rect(tabCloseButtonXCoord, tabCloseButtonYCoord, 16, 16)
+            self._tabXBgBmp = self._GetBitmap(dc, x_rect, self._tabXBgBmp)
+            # Draw the tab
+            self.DrawTabX(pc, dc, x_rect, tabIdx, btnStatus)
+
+
+    def FillVC8GradientColour(self, pageContainer, dc, tabPoints, bSelectedTab, tabIdx):
+        """ Fills a tab with a gradient shading. """
+
+        # calculate gradient coefficients
+        pc = pageContainer
+
+        if self._first:
+            self._first = False
+            pc._colorTo   = LightColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE), 0) 
+            pc._colorFrom = LightColour(wx.SystemSettings_GetColour(wx.SYS_COLOUR_3DFACE), 60)
+        
+        col2 = pc._pParent.GetGradientColourTo()
+        col1 = pc._pParent.GetGradientColourFrom()
+
+        # If colorful tabs style is set, override the tab color
+        if pc.HasFlag(FNB_COLORFUL_TABS):
+        
+            if not pc._pagesInfoVec[tabIdx].GetColour():
+            
+                # First time, generate color, and keep it in the vector
+                tabColor = RandomColour()
+                pc._pagesInfoVec[tabIdx].SetColour(tabColor)
+            
+            if pc.HasFlag(FNB_BOTTOM):
+            
+                col2 = LightColour(pc._pagesInfoVec[tabIdx].GetColour(), 50)
+                col1 = LightColour(pc._pagesInfoVec[tabIdx].GetColour(), 80)
+            
+            else:
+            
+                col1 = LightColour(pc._pagesInfoVec[tabIdx].GetColour(), 50)
+                col2 = LightColour(pc._pagesInfoVec[tabIdx].GetColour(), 80)
+            
+        size = abs(tabPoints[2].y - tabPoints[0].y) - 1
+
+        rf, gf, bf = 0, 0, 0
+        rstep = float(col2.Red() - col1.Red())/float(size)
+        gstep = float(col2.Green() - col1.Green())/float(size)
+        bstep = float(col2.Blue() - col1.Blue())/float(size)
+        
+        y = tabPoints[0].y 
+
+        # If we are drawing the selected tab, we need also to draw a line 
+        # from 0.tabPoints[0].x and tabPoints[6].x . end, we achieve this
+        # by drawing the rectangle with transparent brush
+        # the line under the selected tab will be deleted by the drwaing loop
+        if bSelectedTab:
+            self.DrawTabsLine(pc, dc)
+
+        while 1:
+        
+            if pc.HasFlag(FNB_BOTTOM):
+            
+                if y > tabPoints[0].y + size:
+                    break
+            
+            else:
+            
+                if y < tabPoints[0].y - size:
+                    break
+            
+            currCol = wx.Colour(col1.Red() + rf, col1.Green() + gf, col1.Blue() + bf)
+
+            dc.SetPen((bSelectedTab and [wx.Pen(pc._activeTabColor)] or [wx.Pen(currCol)])[0])
+            startX = self.GetStartX(tabPoints, y, pc.GetParent().GetWindowStyleFlag()) 
+            endX = self.GetEndX(tabPoints, y, pc.GetParent().GetWindowStyleFlag())
+            dc.DrawLine(startX, y, endX, y)
+
+            # Draw the border using the 'edge' point
+            dc.SetPen(wx.Pen((bSelectedTab and [wx.SystemSettings_GetColour(wx.SYS_COLOUR_BTNSHADOW)] or [pc._colorBorder])[0]))
+            
+            dc.DrawPoint(startX, y)
+            dc.DrawPoint(endX, y)
+            
+            # Progress the color 
+            rf += rstep
+            gf += gstep
+            bf += bstep
+
+            if pc.HasFlag(FNB_BOTTOM):
+                y = y + 1
+            else:
+                y = y - 1
+
+
+    def GetStartX(self, tabPoints, y, style):
+        """ Returns the x start position of a tab. """
+
+        x1, x2, y1, y2 = 0.0, 0.0, 0.0, 0.0
+
+        # We check the 3 points to the left
+
+        bBottomStyle = (style & FNB_BOTTOM and [True] or [False])[0]
+        match = False
+
+        if bBottomStyle:
+        
+            for i in xrange(3):
+                
+                if y >= tabPoints[i].y and y < tabPoints[i+1].y:
+                
+                    x1 = tabPoints[i].x
+                    x2 = tabPoints[i+1].x
+                    y1 = tabPoints[i].y
+                    y2 = tabPoints[i+1].y
+                    match = True
+                    break
+                
+        else:
+        
+            for i in xrange(3):
+                
+                if y <= tabPoints[i].y and y > tabPoints[i+1].y:
+                
+                    x1 = tabPoints[i].x
+                    x2 = tabPoints[i+1].x
+                    y1 = tabPoints[i].y
+                    y2 = tabPoints[i+1].y
+                    match = True
+                    break
+                
+        if not match:
+            return tabPoints[2].x
+
+        # According to the equation y = ax + b => x = (y-b)/a
+        # We know the first 2 points
+
+        if x2 == x1:
+            return x2
+        else:
+            a = (y2 - y1)/(x2 - x1)
+
+        b = y1 - ((y2 - y1)/(x2 - x1))*x1
+
+        if a == 0:
+            return int(x1)
+
+        x = (y - b)/a
+        
+        return int(x)
+
+
+    def GetEndX(self, tabPoints, y, style):
+        """ Returns the x end position of a tab. """
+
+        x1, x2, y1, y2 = 0.0, 0.0, 0.0, 0.0
+
+        # We check the 3 points to the left
+        bBottomStyle = (style & FNB_BOTTOM and [True] or [False])[0]
+        match = False
+
+        if bBottomStyle:
+
+            for i in xrange(7, 3, -1):
+                
+                if y >= tabPoints[i].y and y < tabPoints[i-1].y:
+                
+                    x1 = tabPoints[i].x
+                    x2 = tabPoints[i-1].x
+                    y1 = tabPoints[i].y
+                    y2 = tabPoints[i-1].y
+                    match = True
+                    break
+        
+        else:
+        
+            for i in xrange(7, 3, -1):
+                
+                if y <= tabPoints[i].y and y > tabPoints[i-1].y:
+                
+                    x1 = tabPoints[i].x
+                    x2 = tabPoints[i-1].x
+                    y1 = tabPoints[i].y
+                    y2 = tabPoints[i-1].y
+                    match = True
+                    break
+
+        if not match:
+            return tabPoints[3].x
+
+        # According to the equation y = ax + b => x = (y-b)/a
+        # We know the first 2 points
+
+        # Vertical line
+        if x1 == x2:
+            return int(x1)
+        
+        a = (y2 - y1)/(x2 - x1)
+        b = y1 - ((y2 - y1)/(x2 - x1))*x1
+
+        if a == 0:
+            return int(x1)
+
+        x = (y - b)/a
+
+        return int(x)
+
+
+    def NumberTabsCanFit(self, pageContainer, fr=-1):
+        """ Returns the number of tabs that can fit in the visible area. """
+
+        pc = pageContainer
+        
+        rect = pc.GetClientRect()
+        clientWidth = rect.width
+
+        # Empty results
+        vTabInfo = []
+        tabHeight = self.CalcTabHeight(pageContainer)
+
+        # The drawing starts from posx
+        posx = pc._pParent.GetPadding()
+        
+        if fr < 0:
+            fr = pc._nFrom
+
+        for i in xrange(fr, len(pc._pagesInfoVec)):
+        
+            vc8glitch = tabHeight + FNB_HEIGHT_SPACER
+            tabWidth = self.CalcTabWidth(pageContainer, i, tabHeight)
+
+            if posx + tabWidth + vc8glitch + self.GetButtonsAreaLength(pc) >= clientWidth:
+                break
+
+            # Add a result to the returned vector
+            tabRect = wx.Rect(posx, VERTICAL_BORDER_PADDING, tabWidth, tabHeight)
+            vTabInfo.append(tabRect)
+
+            # Advance posx
+            posx += tabWidth + FNB_HEIGHT_SPACER
+        
+        return vTabInfo
+    
+
+# ---------------------------------------------------------------------------- #
+# Class FlatNotebook
+# ---------------------------------------------------------------------------- #
+
+class FlatNotebook(wx.Panel):
+    """
+    Display one or more windows in a notebook.
+    
+    B{Events}:
+        - B{EVT_FLATNOTEBOOK_PAGE_CHANGING}: sent when the active 
+            page in the notebook is changing
+        - B{EVT_FLATNOTEBOOK_PAGE_CHANGED}: sent when the active 
+            page in the notebook has changed
+        - B{EVT_FLATNOTEBOOK_PAGE_CLOSING}: sent when a page in the 
+            notebook is closing
+        - B{EVT_FLATNOTEBOOK_PAGE_CLOSED}: sent when a page in the 
+            notebook has been closed
+        - B{EVT_FLATNOTEBOOK_PAGE_CONTEXT_MENU}: sent when the user
+            clicks a tab in the notebook with the right mouse
+            button
+    """
+    
+    def __init__(self, parent, id=wx.ID_ANY, pos=wx.DefaultPosition, size=wx.DefaultSize,
+                 style=0, name="FlatNotebook"):
+        """
+        Default class constructor.