#if !defined(AFX_COOLTABCTRL2_H__20010513_D899_C89D_D02E_0080AD509055__INCLUDED_)
#define AFX_COOLTABCTRL2_H__20010513_D899_C89D_D02E_0080AD509055__INCLUDED_

#pragma once

/////////////////////////////////////////////////////////////////////////////
// CCoolTabCtrl2 - A extended set of Tab Controls with different appearances
//
// Written by Pascal Binggeli (pascal.binggeli@bluewin.ch)
// Copyright (c) 2001 Pascal Binggeli
//
// Written by Bjarke Viksoe (bjarke@viksoe.dk)
// Copyright (c) 2001 Bjarke Viksoe.
//
// This code may be used in compiled form in any way you desire. This
// file may be redistributed by any means PROVIDING it is 
// not sold for profit without the authors written consent, and 
// providing that this notice and the authors name is included. 
//
// This file is provided "as is" with no expressed or implied warranty.
// The author accepts no liability if it causes any damage to you or your
// computer whatsoever. It's free, so don't hassle me about it.
//
// Beware of bugs.
//
// History (Date/Author/Description):
// ----------------------------------
// 
// 11/06/2001: Pascal Binggeli (PBI)
// - Added CDotNetTabCtrl2 class.
//             


#include "CoolTabCtrl.h"

class CDotNetTabCtrl2 : 
   public CCustomTabCtrl<CDotNetTabCtrl2>,
   public CCustomDraw<CDotNetTabCtrl2>
{
protected:
  CImageList m_imageList;
public:
   DECLARE_WND_CLASS(_T("WTL_CoolDotNetTabCtrl2"))

   CBrush m_hbrBack;

   CImageList SetImageList(HIMAGELIST hImageList)
   {
     CImageList oldImageList = m_imageList;
     m_imageList = hImageList;
     return oldImageList;
   }
   CImageList& GetImageList()
   {
     return m_imageList;
   }



   BEGIN_MSG_MAP(CDotNetTabCtrl2)
      MESSAGE_HANDLER(WM_ERASEBKGND, OnEraseBkgnd)
      CHAIN_MSG_MAP(CCustomTabCtrl<CDotNetTabCtrl2>)
      CHAIN_MSG_MAP_ALT(CCustomDraw<CDotNetTabCtrl2>, 1)
      REFLECTED_NOTIFY_CODE_HANDLER(TCN_INITIALIZE, OnInitialize)
      DEFAULT_REFLECTION_HANDLER()
   END_MSG_MAP()

   LRESULT OnEraseBkgnd(UINT /*uMsg*/, WPARAM wParam, LPARAM /*lParam*/, BOOL& /*bHandled*/)
   {
      CDCHandle dc((HDC)wParam);
      RECT rc;
      GetClientRect(&rc);
      HBRUSH hOldBrush = dc.SelectBrush(m_hbrBack);
      dc.PatBlt(rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top, PATCOPY);
      dc.SelectBrush(hOldBrush);

      // Connect with the client area.
      DWORD dwStyle = (DWORD)::GetWindowLong(m_hWnd, GWL_STYLE);
      BOOL bHasBottomStyle = dwStyle & TCS_BOTTOM;

      if (bHasBottomStyle)
      {
        rc.bottom = rc.top + 3;
        dc.FillSolidRect(&rc, GetSysColor(COLOR_BTNFACE));
      }
      else
      {
        rc.top = rc.bottom - 3;
        dc.FillSolidRect(&rc, GetSysColor(COLOR_BTNFACE));
      }

      return 1;
   }

   LRESULT OnInitialize(int /*idCtrl*/, LPNMHDR /*pnmh*/, BOOL& /*bHandled*/)
   {
      TC_SIZES sizes;
      GetSizeSettings(&sizes);
      sizes.iIndent = 6;
      sizes.iPadding = 0;
      sizes.iMargin = 2;
      sizes.iSelMargin = 4;
      SetSizeSettings(&sizes);
      return 0;
   }

   DWORD OnPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
   {
      CDCHandle dc( lpNMCustomDraw->hdc );
      dc.SetTextColor(::GetSysColor(COLOR_BTNTEXT));
      ::SetBkMode(lpNMCustomDraw->hdc, TRANSPARENT);

      return CDRF_NOTIFYITEMDRAW;   // We need per-item notifications
   }

   DWORD OnItemPrePaint(int /*idCtrl*/, LPNMCUSTOMDRAW lpNMCustomDraw)
   {
      CDCHandle dc( lpNMCustomDraw->hdc );
      bool bSelected = lpNMCustomDraw->uItemState & CDIS_SELECTED;
      RECT &rc = lpNMCustomDraw->rc;

      DWORD dwStyle = (DWORD)::GetWindowLong(m_hWnd, GWL_STYLE);
      BOOL bHasBottomStyle = dwStyle & TCS_BOTTOM;

//      dc.FillRect(&rc, m_hbrBack);

       // Tab is selected, so paint tab folder
       RECT rcTab = rc;
       if (bHasBottomStyle)
       {
         rcTab.top += 3;
         rcTab.bottom -= 2;
       }
       else
       {
         rcTab.top += 5;
         rcTab.bottom -= 3;
       }

      if( bSelected ) {
         rcTab.right--;
         dc.FillRect(&rcTab, (HBRUSH)(COLOR_BTNFACE+1));

         if (bHasBottomStyle)
         {
           dc.SelectStockPen(BLACK_PEN);
           dc.MoveTo(rcTab.right, rcTab.top);
           dc.LineTo(rcTab.right, rcTab.bottom);
           dc.LineTo(rcTab.left, rcTab.bottom);
           dc.SelectStockPen(WHITE_PEN);
           dc.LineTo(rcTab.left, rcTab.top);
         }
         else
         {
           dc.SelectStockPen(WHITE_PEN);
           dc.MoveTo(rcTab.left, rcTab.bottom);
           dc.LineTo(rcTab.left, rcTab.top);
           dc.LineTo(rcTab.right, rcTab.top);
           dc.SelectStockPen(BLACK_PEN);
           dc.LineTo(rcTab.right, rcTab.bottom);
         }
      }

      TCITEM item = { 0 };
      TCHAR szText[128];
      item.mask = TCIF_TEXT | TCIF_IMAGE;
      item.pszText = szText;
      item.cchTextMax = sizeof(szText)/sizeof(TCHAR);
      GetItem(lpNMCustomDraw->dwItemSpec, &item);

      TC_SIZES sizes;
      GetSizeSettings(&sizes);

      LOGFONT lfFont;
      GetObject(AtlGetStockFont(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lfFont);
      _tcscpy(lfFont.lfFaceName, _T("Tahoma"));

      HFONT hOldFont = dc.SelectFont(::CreateFontIndirect(&lfFont));
      RECT rcText = rc;

      ::InflateRect(&rcText, -sizes.iPadding, 0);
      if (item.mask & TCIF_IMAGE && !m_imageList.IsNull())
      {
        // Draw the image.
        IMAGEINFO ii;
        m_imageList.GetImageInfo(item.iImage, &ii);

        DWORD dwDrawStyle = ILD_NORMAL;
        if (ii.hbmMask)
          dwDrawStyle |= ILD_MASK;

        if (ii.rcImage.right - ii.rcImage.left + sizes.iMargin * 2 < rcTab.right - rcTab.left)
          m_imageList.Draw(dc, item.iImage, rcTab.left + sizes.iMargin * 2, rcTab.top + 3, ILD_NORMAL);

        // Offset on the right.
        rcText.left += ii.rcImage.right - ii.rcImage.left + sizes.iMargin * 2;
      }
      rcText.left += sizes.iMargin * 2;
      rcText.right -= sizes.iMargin * 2;

      if (bHasBottomStyle)
        rcText.bottom -= 6;
      else
        rcText.bottom -= 5;

      if (rcText.left + 12 < rcText.right)
        dc.DrawText(item.pszText, ::lstrlen(item.pszText), &rcText, DT_LEFT | DT_BOTTOM | DT_SINGLELINE | DT_END_ELLIPSIS);
      ::DeleteObject(dc.SelectFont(hOldFont));

      return CDRF_SKIPDEFAULT;
   }

   LRESULT OnSettingChange(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& /*bHandled*/)
   {
      // Initialize font
     /*
      if( !m_font.IsNull() ) m_font.DeleteObject();
      NONCLIENTMETRICS ncm = { 0 };
      ncm.cbSize = sizeof(ncm);
      ::SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
      ncm.lfSmCaptionFont.lfWeight = FW_NORMAL;
      m_font.CreateFontIndirect(&ncm.lfSmCaptionFont);
      if (bWantBoldFont)
      {
        ncm.lfSmCaptionFont.lfWeight = FW_BOLD;
        m_fontBold.CreateFontIndirect(&ncm.lfSmCaptionFont);
//        SetFont(m_fontBold); // Bold font scales tabs correctly
      }
//      SetFont(m_font);
*/
      // Background brush
      if( !m_hbrBack.IsNull() ) m_hbrBack.DeleteObject();
      CWindowDC dc(NULL);
      int nBitsPerPixel = dc.GetDeviceCaps(BITSPIXEL);
      if( nBitsPerPixel > 8 ) {
         COLORREF clrBtnHilite = ::GetSysColor(COLOR_BTNHILIGHT);
         COLORREF clrBtnFace = ::GetSysColor(COLOR_BTNFACE);
         COLORREF clrLight = 
            RGB( GetRValue(clrBtnFace) + ((GetRValue(clrBtnHilite) - GetRValue(clrBtnFace)) / 2),
                 GetGValue(clrBtnFace) + ((GetGValue(clrBtnHilite) - GetGValue(clrBtnFace)) / 2),
                 GetBValue(clrBtnFace) + ((GetBValue(clrBtnHilite) - GetBValue(clrBtnFace)) / 2),
         );
         m_hbrBack.CreateSolidBrush(clrLight);
      }
      else {
         m_hbrBack =  CDCHandle::GetHalftoneBrush();
      }
      Invalidate();
      return 0;
   }


   // Override standard behavior while resizing the control.

   void UpdateLayout()
   {
      CClientDC dc(m_hWnd);

      LOGFONT lfFont;
      GetObject(AtlGetStockFont(DEFAULT_GUI_FONT), sizeof(LOGFONT), &lfFont);
      _tcscpy(lfFont.lfFaceName, _T("Tahoma"));

      HFONT hOldFont = (HFONT)::SelectObject(dc, ::CreateFontIndirect(&lfFont));    

      RECT rcClient;
      GetClientRect(&rcClient);

      // Reposition buttons
      int cnt = m_Sizes.GetSize();
      int xpos = m_settings.iIndent;
      for( int i=0; i<cnt; i++ ) {
         LPTCITEM pItem = m_Items[i];
         RECT rc;
         rc.left = rc.right = xpos;
         if( pItem->mask & TCIF_TEXT ) {
            RECT rcText = { 0 };
            ::DrawText(dc, pItem->pszText, ::lstrlen(pItem->pszText), &rcText, DT_SINGLELINE | DT_CALCRECT);
            rc.right += (rcText.right-rcText.left) + (m_settings.iPadding*2) + m_settings.iMargin * 4;
         }
         if( pItem->mask & TCIF_IMAGE && !m_imageList.IsNull()) {
           IMAGEINFO ii;
           m_imageList.GetImageInfo(pItem->iImage, &ii);
           rc.right += ii.rcImage.right - ii.rcImage.left + m_settings.iMargin * 2;
         }
         rc.top = 0;
         rc.bottom = rcClient.bottom-rcClient.top;
         m_Sizes.SetAtIndex(i, rc);
         xpos += (rc.right-rc.left); // + m_settings.iMargin;
      }

      int cxClient = rcClient.right - rcClient.left;
      if (xpos > cxClient)
      {
        xpos = m_settings.iIndent;

        // Restart everything with same width for every item.
        int cxItem = (cxClient - xpos) / (cnt == 0 ? 1 : cnt);

        for(i=0; i<cnt; i++ ) {
           LPTCITEM pItem = m_Items[i];
           RECT rc;
           rc.left = rc.right = xpos;
           rc.right += cxItem;
           rc.top = 0;
           rc.bottom = rcClient.bottom-rcClient.top;
           m_Sizes.SetAtIndex(i, rc);
           xpos += (rc.right-rc.left); //+ m_settings.iMargin;
        }

      }
      
      ::DeleteObject(::SelectObject(dc, hOldFont));
   }

};


#endif // !defined(AFX_COOLTABCTRL2_H__20010513_D899_C89D_D02E_0080AD509055__INCLUDED_)
