/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
 *
 * The contents of this file are subject to the Netscape Public License
 * Version 1.0 (the "NPL"); you may not use this file except in
 * compliance with the NPL.  You may obtain a copy of the NPL at
 * http://www.mozilla.org/NPL/
 *
 * Software distributed under the NPL is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
 * for the specific language governing rights and limitations under the
 * NPL.
 *
 * The Initial Developer of this code under the NPL is Netscape
 * Communications Corporation.  Portions created by Netscape are
 * Copyright (C) 1998 Netscape Communications Corporation.  All Rights
 * Reserved.
 */

/* COMPBAR.CPP Contains all the code for the dialog bar portion of the compose
 * window.  This currently comprises the addressing block and attachment 
 * blocks. 
 *
 */
 
#include "stdafx.h"
#include "resource.h"
#include "compstd.h"
#include "compbar.h"
#include "compfrm.h"
#include "compfile.h"
#include "apiaddr.h"

#include "msg_srch.h"

#define TOTAL_TABS              3
#define TAB_SPACING_X           24
#define TAB_SPACING_Y           20
#define TAB_HORIZONTAL_OFFSET   2
#define TAB_ICON_SIZE           16
#define PIXEL_OFFSET_Y          4
#define PIX_X_FACTOR            20
#define PIX_Y_FACTOR            25
#define COMP_VTAB_WIDTH         9
#define COMP_LEFT_MARGIN        4
#define COMP_HTAB_HEIGHT        10
#define COMP_VTAB_TOP_HEIGHT        7
#define COMP_VTAB_BOTTOM_HEIGHT     3
#define COMP_VTAB_SECTION_HEIGHT    6

/////////////////////////////////////////////////////////////////////////////
// CComposeBar

BEGIN_MESSAGE_MAP(CComposeBar, CDialogBar)
    ON_COMMAND(IDC_BUTTON_ATTACH,OnButtonAttach)
    ON_WM_CREATE()
    ON_WM_TIMER()
    ON_WM_SIZE()
    ON_WM_PAINT()
    ON_WM_MOUSEMOVE()
    ON_WM_SETCURSOR()
    ON_WM_LBUTTONDOWN()
    ON_WM_LBUTTONUP()
    ON_WM_ERASEBKGND()
    ON_WM_DROPFILES()
    ON_BN_CLICKED(ID_ENCRYPTED,OnUpdateOptions)
    ON_BN_CLICKED(ID_SIGNED,OnUpdateOptions)
 	ON_MESSAGE(WM_LEAVINGLASTFIELD,OnLeavingLastField)

END_MESSAGE_MAP()

extern "C" char * wfe_ExpandForNameCompletion(char * pString);
extern "C" char * wfe_ExpandName(char * pString);

CComposeBar::CComposeBar () :
    CDialogBar ()
{
	m_iBoxHeight = 0;
    m_pAttachmentList = NULL;       // widget for attachment list
    m_bSizing =         FALSE;      // for resizing dialog bar (needs work)
    // start off with the address block displayed
    m_iSelectedTab =    IDX_COMPOSEADDRESS;
    m_pSubjectEdit =    NULL;       // text for subject field
    m_pPriority    =    NULL;       // message priority
    m_bClosed =         FALSE;      // dialog bar is collapsed or expanded
    m_bHidden =         FALSE;      // dialog bar is "hidden" (collapsed with no widget) or showing full size
    m_pComposeEdit =    NULL;       // pointer to the composition editor
    m_pWidget =         NULL;
    m_iPriorityIdx =    2;			// 0 based index; 0-lowest 1-low 2-normal 3-high 4-highest
    m_bCanSize =        FALSE;
    m_iTotalAttachments = 0;
	m_iHeight			= 0;
    m_iPrevHeight       = 0;
    m_iMinSize          = 0;
    m_iMaxSize          = 0;
    m_pReturnReceipt =  NULL;
    m_pEncrypted =      NULL;
    m_pSigned =         NULL;
    m_bReceipt =        FALSE;
    m_bSigned =         FALSE;
    m_bEncrypted =      FALSE;
    m_pDropTarget =     NULL;
    m_pMessageFormat =  NULL;
    m_pMessageFormatText = NULL;
    m_pszMessageFormat = NULL;
//    m_bUse8Bit =        FALSE;
    m_bUseUUENCODE =    FALSE;
//    m_pUse8Bit =        NULL;
    m_pUseUUENCODE =    NULL;
	m_pUnkImage = NULL;
    m_pUnkAddressControl = NULL;
	ApiApiPtr(api);
	m_pUnkImage = api->CreateClassInstance(
		APICLASS_IMAGEMAP,NULL,(APISIGNATURE)IDB_COMPOSETABS);
	m_pUnkImage->QueryInterface(IID_IImageMap,(LPVOID*)&m_pIImage);
	ASSERT(m_pIImage);
	if (!m_pIImage->GetResourceID())
		m_pIImage->Initialize(IDB_COMPOSETABS,16,16);
}

CComposeBar::~CComposeBar ( )
{
    // free up any allocated resources and release any used apis
   if (m_pszMessageFormat)
      free(m_pszMessageFormat);
   if (m_pUnkImage) {
      if (m_pIImage)
         m_pUnkImage->Release();
   }
   if (m_pUnkAddressControl)
      m_pUnkAddressControl->Release();
   delete m_pToolTip;
   if (m_pDropTarget)
   {
      m_pDropTarget->Revoke();
      delete m_pDropTarget;
   }
}

/////////////////////////////////////////////////////////////////////////////
// GetAddressWidget() returns a pointer to the NSAddressList object.

LPADDRESSCONTROL CComposeBar::GetAddressWidgetInterface()
{
    ASSERT(m_pIAddressList);
    return(m_pIAddressList);
}

/////////////////////////////////////////////////////////////////////////////
// TabControl() controls the tabbing order between the controls in
// the composition window.  The controls are parented at different
// levels which make focus issues a little confusing. This function
// returns TRUE if it knew where to put focus, if it couldn't figure 
// out where it should go, FALSE is returned.

BOOL CComposeBar::TabControl(BOOL bShift, BOOL bControl, CWnd * pWnd)
{
    // get a pointer to the parent frame (FIXME JRE).  The child
    // really shouldn't need to know anything about the parent.
	CComposeFrame *pCompose = (CComposeFrame *)GetParent();
    CListBox * pListBox = NULL;

    switch (m_iSelectedTab)
    {
        case IDX_COMPOSEADDRESS:
            pListBox = m_pIAddressList->GetListBox();
            break;
        case IDX_COMPOSEATTACH:
            pListBox = (CListBox*)m_pAttachmentList;
            break;
    }
	if (pWnd == (CWnd*)TABCTRL_HOME)    // this value position to address list
    {
    	pListBox->SetFocus();
        pCompose->SetFocusField(pListBox);
    	return TRUE;
    }
    else if (bControl)
    {
      TabChanging(m_iSelectedTab);
      switch (m_iSelectedTab)
      {
         case IDX_COMPOSEADDRESS:
            TabChanged(bShift ? IDX_COMPOSEOPTIONS : IDX_COMPOSEATTACH);
            break;
         case IDX_COMPOSEATTACH:
            TabChanged(bShift ? IDX_COMPOSEADDRESS: IDX_COMPOSEOPTIONS);
            break;
         case IDX_COMPOSEOPTIONS:
            TabChanged(bShift ? IDX_COMPOSEATTACH : IDX_COMPOSEADDRESS);
            break;
      }
      
      return TRUE;
    }
	else if (pWnd == pCompose->GetEditorWnd()) 
    {
    	// if the editor has focus and the shift-tab was hit, position to the
    	// subject field
    	if (bShift)
    	{
    	    m_pSubjectEdit->SetFocus();
            pCompose->SetFocusField(m_pSubjectEdit);
    	    return TRUE;
    	}
    }
    else if (pWnd == m_pSubjectEdit)
    {
        // if the subject field has focus, give focus to the address list
        // if shift-tab was pressed.
        if (bShift)
        {
            switch (m_iSelectedTab)
            {
                case IDX_COMPOSEATTACH:
                case IDX_COMPOSEADDRESS:
                    pListBox->SetFocus();
                    pCompose->SetFocusField(pListBox);
                    break;
                case IDX_COMPOSEOPTIONS:
                    if (pCompose->UseHtml())
                    {
                        m_pMessageFormat->SetFocus();
                        pCompose->SetFocusField(m_pMessageFormat);
                    }
                    else
                    {
                        m_pPriority->SetFocus();
                        pCompose->SetFocusField(m_pPriority);
                    }
                    break;
            }
            return TRUE;
        }
        else if (pCompose && pCompose->GetEditorWnd())
        {
            pCompose->GetEditorWnd()->SetFocus();
            pCompose->SetFocusField(pCompose->GetEditorWnd());
        }
        return TRUE;
    } 

	return FALSE;   // couldn't figure out who to give focus to
}

BOOL CComposeBar::OnEraseBkgnd(CDC* pDC)
{
    CRect WinRect, rect;
    GetClientRect(WinRect);
    GetWidgetRect(WinRect,rect);
    rect.InflateRect(-2,-2);
    CBrush brush(GetSysColor(COLOR_BTNFACE)), *pOldBrush;
    CPen pen(PS_SOLID,1,GetSysColor(COLOR_BTNFACE)), *pOldPen;
    pOldBrush = pDC->SelectObject(&brush);
    pOldPen = pDC->SelectObject(&pen);

    if ((m_iSelectedTab != IDX_COMPOSEOPTIONS) && !m_bClosed)
    {
        CRect fillrect;
        fillrect = WinRect;
        fillrect.right = rect.left + 2;
        pDC->Rectangle(fillrect);
        fillrect = WinRect;
        fillrect.left = rect.right;
        pDC->Rectangle(fillrect);
        fillrect = WinRect;
        fillrect.bottom = rect.top;
        pDC->Rectangle(fillrect);
        fillrect = WinRect;
        fillrect.top = rect.bottom;
        pDC->Rectangle(fillrect);
    }
    else
        pDC->Rectangle(WinRect);


    pDC->SelectObject(pOldBrush);
    pDC->SelectObject(pOldPen);
    return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// OnLeavingLastField() is a responded to the WM_LEAVINGLASTFIELD message
// which is generated by the address list widget.  When the focus is on
// the last valid entry in the address list and tab is pressed, this
// message is sent.

LONG CComposeBar::OnLeavingLastField(UINT, LONG)
{
    // when leaving the last field of the address widget, give focus to
    // the subject field
	if (m_pSubjectEdit)
    {
    	CComposeFrame *pCompose = (CComposeFrame *)GetParent();
		m_pSubjectEdit->SetFocus();
        pCompose->SetFocusField(m_pSubjectEdit);
    }
	return 0;
}

void CComposeBar::OnLButtonUp( UINT nFlags, CPoint point )
{
    ReleaseCapture();
    m_bSizing = FALSE;
    CDialogBar::OnLButtonUp(nFlags,point);
}

void CComposeBar::OnLButtonDown( UINT nFlags, CPoint point )
{
    if (m_bCanSize && !m_bClosed)
    {
        SetCapture();
        m_iY = point.y;
        m_bSizing = TRUE;
    }
    else if (!m_bClosed && !collapser.ButtonPress(point))
    {
       for (int i = 0; i < MAX_TIPS; i++)
       {
           if (m_ToolTipInfo[i].m_rect.PtInRect(point))
           {
               if (i != m_iSelectedTab)
               {
                   SendMessage(WM_COMMAND,(WPARAM)m_ToolTipInfo[i].m_idCommand);
                   Invalidate();
                   break;
               }
           }
       }
    }
    CDialogBar::OnLButtonDown(nFlags,point);
}

BOOL CComposeBar::OnSetCursor( CWnd* pWnd, UINT nHitTest, UINT message )
{
    if (!m_bClosed)
    {
    	CRect WinRect;
        POINT point;
        GetCursorPos(&point);
        ScreenToClient(&point);
        GetClientRect(WinRect);
        CRect rect;
        if (m_pWidget)
        {
            m_pWidget->GetWindowRect(rect);
            ScreenToClient(rect);
            WinRect.top = rect.bottom;
            WinRect.bottom = WinRect.top + GetSystemMetrics(SM_CYFRAME)*2;
            if ( nHitTest == HTCLIENT && PtInRect( &WinRect, point ))
            {
                SetCursor( theApp.LoadCursor ( AFX_IDC_VSPLITBAR ) );
                m_bCanSize = TRUE;
                return TRUE;
            }
        }
        m_bCanSize = FALSE;
    }
	return CDialogBar::OnSetCursor( pWnd, nHitTest, message );
}

void CComposeBar::OnMouseMove( UINT nFlags, CPoint point )
{
    if (m_bSizing) 
    {
        if (m_iY != point.y)
        {
    	    m_iHeight += (point.y - m_iY);
    	    m_iHeight = max(m_iHeight,m_iMinSize);
    	    m_iHeight = min(m_iHeight,m_iMaxSize);
	        m_iY = point.y;
	        GetParentFrame()->RecalcLayout();
	        CalcFieldLayout();
	        Invalidate();
	        UpdateWindow();
        }
    }
    CDialogBar::OnMouseMove(nFlags,point);
    if (!m_bClosed)
        collapser.MouseAround(point);
}

static SIZE sizeSelTab = { 2, 2 };

BOOL CComposeBar::IsAttachmentsMailOnly(void)
{
	CComposeFrame *pCompose = (CComposeFrame *)GetParent();
   if (pCompose->GetMsgPane())
   {
      const MSG_AttachmentData * pDataList = MSG_GetAttachmentList(pCompose->GetMsgPane());
      if(pDataList) 
      {
	      for (int i = 0; pDataList[i].url!=NULL; i++) 
	         if (strncmp(pDataList[i].url,"mailbox:",8))
    		      return FALSE;
      }
      return TRUE;
   }
   return FALSE;
}


void CComposeBar::DrawVerticalTab(CDC & dc, int index, CRect &rect)
{
    int x = m_cxChar + COMP_VTAB_WIDTH + COMP_LEFT_MARGIN;
    int y = PIXEL_OFFSET_Y + 5;
    BOOL bSelected = m_iSelectedTab == index;

    rect.SetRect(
    	x,
    	y+(index*TAB_SPACING_Y),
    	0,0);
    rect.right = rect.left + TAB_SPACING_X - 1;
    rect.bottom = rect.top + TAB_SPACING_Y;

    HPEN hPenHilite, hPenShadow, hPenDark;
    hPenHilite = ::CreatePen( PS_SOLID, 1, GetSysColor ( COLOR_BTNHIGHLIGHT ) );
    hPenShadow = ::CreatePen( PS_SOLID, 1, GetSysColor ( COLOR_BTNSHADOW ) );
#ifdef XP_WIN32
    hPenDark = ::CreatePen( PS_SOLID, 1, GetSysColor ( COLOR_3DDKSHADOW ) );    
    HPEN hPenLite = ::CreatePen( PS_SOLID, 1, GetSysColor ( COLOR_3DLIGHT ) );
#else
    hPenDark = ::CreatePen( PS_SOLID, 1, GetSysColor ( COLOR_BTNTEXT ) );       
    HPEN hPenLite = ::CreatePen( PS_SOLID, 1, GetSysColor ( COLOR_BTNHIGHLIGHT ) );
#endif

    if (bSelected)
	{
	    InflateRect(&rect, sizeSelTab.cx, sizeSelTab.cy);
		rect.right++;
    	rect.bottom -= 2;
	}

    HBRUSH hBrush = (HBRUSH)(COLOR_BTNFACE + 1);
    ::FillRect(dc.GetSafeHdc(), &rect, hBrush);

    rect.right -= 2;
    rect.bottom += 2;

    HPEN hOldPen = (HPEN)dc.SelectObject(hPenDark);
    dc.MoveTo(rect.right - (bSelected ? 2 : 0),rect.bottom-1);
    dc.LineTo(rect.left+2,rect.bottom-1);
    dc.LineTo(rect.left,rect.bottom-3);
    dc.SelectObject(hPenHilite);
    dc.LineTo(rect.left,rect.top+2);
    dc.LineTo(rect.left+2,rect.top);
    dc.LineTo(rect.right + ((bSelected&&!index) ? 2 : 0 ),rect.top);

    dc.SelectObject(hPenShadow);
    dc.MoveTo(rect.right - (bSelected ? 1 : 0),rect.bottom-2);
    dc.LineTo(rect.left+2,rect.bottom-2);
    dc.LineTo(rect.left+1,rect.bottom-3);
    dc.SelectObject(hPenLite);
    dc.LineTo(rect.left+1,rect.top+2);
    dc.LineTo(rect.left+2,rect.top+1);
    if (!bSelected && index)
    	dc.LineTo(rect.right + ((bSelected&&!index) ? 2 : 0),rect.top+1);

    //update the attachment count here since the attachments may have come
    //from the command line and need a way of notifying the control.
    if (GetTotalAttachments() && !m_iTotalAttachments)
        m_iTotalAttachments = GetTotalAttachments();

    int idxImage = index;
    if (index == IDX_COMPOSEATTACH)
    {
    	if (m_iTotalAttachments > 0)
    	{
    	    if (IsAttachmentsMailOnly())
        		idxImage = IDX_COMPOSEATTACHMAIL;
    	    else
	        	idxImage = IDX_COMPOSEATTACHFILE;
    	}
    }
    m_pIImage->DrawImage(
    	idxImage,
    	rect.left + (TAB_SPACING_X-TAB_ICON_SIZE)/2,
    	rect.top + (TAB_SPACING_Y-TAB_ICON_SIZE)/2,
    	dc.GetSafeHdc(), TRUE);

	if (hOldPen != NULL)
		dc.SelectObject(hOldPen);

    ::DeleteObject((HGDIOBJ) hPenHilite);
    ::DeleteObject((HGDIOBJ) hPenShadow);
    ::DeleteObject((HGDIOBJ) hPenDark);
    ::DeleteObject((HGDIOBJ) hPenLite);
}

void CComposeBar::GetWidgetRect(CRect &WinRect, CRect &rect)
{
	 int y = PIXEL_OFFSET_Y;
    int x = TAB_SPACING_X + 6 + COMP_VTAB_WIDTH + COMP_LEFT_MARGIN;
    int iHeight = (WinRect.Height() - (m_iBoxHeight * 3)/2) - 5;
    rect.SetRect(
		x, y, 
		WinRect.Width()-4, 
		iHeight);
}

void CComposeBar::Draw3DStaticEdgeSimulation(CDC & dc, CRect &rect, BOOL bReverse)
{
    CPen ShadowPen (PS_SOLID, 1, GetSysColor(COLOR_BTNSHADOW));
    CPen HilitePen (PS_SOLID, 1, GetSysColor(COLOR_BTNHIGHLIGHT));
    CPen * pOldPen = dc.SelectObject(bReverse ? &HilitePen : &ShadowPen);

    dc.MoveTo(rect.left,rect.bottom-1);
    dc.LineTo(rect.left,rect.top);
    dc.LineTo(rect.right-1,rect.top);
    dc.SelectObject(bReverse ? &ShadowPen : &HilitePen);
    dc.LineTo(rect.right-1,rect.bottom-1);
    dc.LineTo(rect.left-1,rect.bottom-1);

    dc.SelectObject(pOldPen);
}

void CComposeBar::OnPaint()
{
   CPaintDC dc(this);

   // draw shadow around address widget and line at top
   // of compose bar
   CRect WinRect, rect;
   GetClientRect(&WinRect);

   GetWidgetRect(WinRect,rect);
   if (!m_bClosed)
   {
      rect.left = COMP_VTAB_WIDTH + 2;
      rect.InflateRect(2,2);
      Draw3DStaticEdgeSimulation(dc, rect, TRUE);
   }

   if (m_pSubjectEdit && m_pSubjectEdit->IsWindowVisible())
   {
      m_pSubjectEdit->GetWindowRect(rect);
      ScreenToClient(rect);
      rect.InflateRect(1,1);
      Draw3DStaticEdgeSimulation(dc, rect);
   }

   if (!m_bClosed)
   {
	   GetWidgetRect(WinRect,rect);
	   rect.InflateRect(-1,-1);
	   rect.left = COMP_VTAB_WIDTH + 3;
	   Draw3DStaticEdgeSimulation(dc, rect);
   }

   if (!m_bClosed)
   {
      HPEN hPenHilite = ::CreatePen( PS_SOLID, 1, GetSysColor ( COLOR_BTNHIGHLIGHT ) );
      HPEN hPenShadow = ::CreatePen( PS_SOLID, 1, GetSysColor ( COLOR_BTNSHADOW ) );
      HPEN hOldPen = (HPEN)dc.SelectObject(hPenShadow);
	   GetWidgetRect(WinRect,rect);
      rect.InflateRect(2,0);
      rect.top++ ;
      rect.bottom -= 2;
      dc.MoveTo(rect.left,rect.top);
      dc.LineTo(rect.left,rect.bottom);
      dc.SelectObject(hPenHilite);
      dc.MoveTo(rect.left + 2,rect.top);
      dc.LineTo(rect.left + 2,rect.bottom);
      CPoint point1(rect.left+1,rect.top);
      CPoint point2(rect.left+1,rect.bottom);
      dc.SetPixel(point1, GetSysColor(COLOR_BTNFACE));
      dc.SetPixel(point2, GetSysColor(COLOR_BTNFACE));
      if (hOldPen != NULL)
		   dc.SelectObject(hOldPen);
      ::DeleteObject((HGDIOBJ) hPenHilite);
      ::DeleteObject((HGDIOBJ) hPenShadow);

      // paint the tabs here
      for (int i =0; i< TOTAL_TABS; i++)
      {
         if (i != m_iSelectedTab)
         {
            DrawVerticalTab(dc,i, rect);
            rect.InflateRect(0,-3);
            m_ToolTipInfo[i].m_rect = rect;

         }
      }
      DrawVerticalTab(dc,m_iSelectedTab,rect);
      rect.InflateRect(0,-3);
      m_ToolTipInfo[m_iSelectedTab].m_rect = rect;
   }
   else
   {
      for (int i =0; i< TOTAL_TABS; i++)
      {
         m_ToolTipInfo[i].m_rect.SetRect(0,0,0,0);
      }
   }

   int iHeight = (WinRect.Height() - (m_iBoxHeight * 3)/2) - 3;

   if (!m_bClosed){
      collapser.DrawCollapseWidget(dc, collapse_open, FALSE, WinRect.Height() - iHeight);
      collapser.GetRect(m_ToolTipInfo[IDX_TOOL_COLLAPSE].m_rect);
   }
}

void CComposeBar::ShowTab(int idx)
{
}

int CComposeBar::GetTab()
{
    return m_iSelectedTab;
}

void CComposeBar::Cleanup(void)
{
    TabChanging(m_iSelectedTab);
    if (m_pAttachmentList && ::IsWindow(m_pAttachmentList->m_hWnd))
    {
        m_pAttachmentList->DestroyWindow();
        delete m_pAttachmentList;
    }
    DestroyStandardFields();
}

void CComposeBar::TabChanging(int tab)
{
    switch (tab)
    {
        case IDX_COMPOSEADDRESS:
            DestroyAddressPage();
            break;
        case IDX_COMPOSEATTACH:
            DestroyAttachmentsPage();
            break;
        case IDX_COMPOSEOPTIONS:
            DestroyOptionsPage();
            break;
        default:
            ASSERT(0);
   }

}

void CComposeBar::TabChanged(int tab)
{
    m_pIAddressList->EnableParsing(tab == IDX_COMPOSEADDRESS);
   m_iSelectedTab = tab;
   switch (m_iSelectedTab) 
   {
       case IDX_COMPOSEADDRESS:
    	   CreateAddressPage();
           m_pWidget->SetFocus();
    	   break;
       case IDX_COMPOSEATTACH:
    	   CreateAttachmentsPage();
    	   m_pWidget->SetFocus();
    	   break;
       case IDX_COMPOSEOPTIONS:
    	   CreateOptionsPage();
           m_pReturnReceipt->SetFocus();
    	   m_pWidget = NULL;
    	   break;
       default:
	       ASSERT(0);
   }

   GetParentFrame()->RecalcLayout();
   
   if (!m_pSubjectEdit)
      CreateStandardFields();
      
   Invalidate();
}

void CComposeBar::OnAddressTab(void)
{
    if (m_iSelectedTab != IDX_COMPOSEADDRESS)
    {
    	TabChanging(m_iSelectedTab);
    	TabChanged(IDX_COMPOSEADDRESS);
    }
}

void CComposeBar::OnAttachTab(void)
{
    if (m_iSelectedTab != IDX_COMPOSEATTACH)
    {
    	TabChanging(m_iSelectedTab);
    	TabChanged(IDX_COMPOSEATTACH);
    }
}

void CComposeBar::OnOptionsTab(void)
{
    if (m_iSelectedTab != IDX_COMPOSEOPTIONS)
    {
    	TabChanging(m_iSelectedTab);
    	TabChanged(IDX_COMPOSEOPTIONS);
    }
}

void CComposeBar::OnToggleShow(void)
{
    if (m_bHidden)
    {
        m_bHidden = FALSE;
        // Always uncollapse when showing
        if (m_bClosed)
        {
            OnCollapse();
        } 
        else if (m_pWidget && ::IsWindow(m_pWidget->m_hWnd))
        {
        	m_pWidget->ShowWindow(SW_NORMAL);
        }
    } else {
        m_bHidden = TRUE;

        // Always collapse when hidding
        if (!m_bClosed) {
            OnCollapse();
        } 
        else if (m_pWidget && ::IsWindow(m_pWidget->m_hWnd))
        {
        	m_pWidget->ShowWindow(SW_HIDE);
        	Invalidate();
        }
        // The only difference between Hiding and collapsing is the 
        //  removal of the collapsed tab
        CGenericFrame * pFrame = (CGenericFrame*)GetParent();
        CCustToolbar * pToolbar = pFrame->GetChrome()->GetCustomizableToolbar();
        if( pToolbar ){
            pToolbar->RemoveExternalTab(1);
        }
       	GetParentFrame()->RecalcLayout();
    }
}

void CComposeBar::OnCollapse(void)
{
    if (!m_bClosed)
    {
    	m_iPrevHeight = m_iHeight;
    	m_bClosed = TRUE;
    	if (m_pWidget && ::IsWindow(m_pWidget->m_hWnd))
    	    m_pWidget->ShowWindow(SW_HIDE);
    	m_iHeight = m_iBoxHeight + /*COMP_HTAB_HEIGHT +*/ 13;
    	if (m_iSelectedTab == IDX_COMPOSEOPTIONS)
    	    DestroyOptionsPage();

        CGenericFrame * pFrame = (CGenericFrame*)GetParent();
        CCustToolbar * pToolbar = pFrame->GetChrome()->GetCustomizableToolbar();
        if( pToolbar ){
            pToolbar->AddExternalTab(pFrame, eLARGE_HTAB, IDS_COMPOSECLOSE,  1);
        }
    	GetParentFrame()->RecalcLayout();
    	Invalidate();
    }
    else 
    {
    	m_bClosed = FALSE;
    	m_iHeight = m_iPrevHeight;
    	GetParentFrame()->RecalcLayout();
    	if (m_iSelectedTab == IDX_COMPOSEADDRESS || m_iSelectedTab == IDX_COMPOSEATTACH)
    	    m_pWidget->ShowWindow(SW_NORMAL);
    	if (m_iSelectedTab == IDX_COMPOSEOPTIONS)
    	    CreateOptionsPage();
    	Invalidate();
    }
}

#define BORDER_WIDTH 5

int CComposeBar::GetTotalAttachments(void)
{
	CComposeFrame *pCompose = (CComposeFrame *)GetParent();
	if (pCompose->GetMsgPane())
	{
		const MSG_AttachmentData * pDataList = MSG_GetAttachmentList(pCompose->GetMsgPane());
		if(pDataList) 
		{
		for (int i = 0; pDataList[i].url!=NULL; i++) 
			;
		return i;
		}
	}
    return 0;
}

void CComposeBar::OnSize( UINT nType, int cx, int cy )
{
	CDialogBar::OnSize( nType, cx, cy );
    if (m_pSubjectEdit)
	CalcFieldLayout();
}

void CComposeBar::OnButtonAttach(void)
{
    CWnd * pWnd = GetFocus();
    GetParent()->SendMessage(WM_COMMAND,ID_FILE_ATTACH);
    if (pWnd)
       pWnd->SetFocus();
}

void CComposeBar::OnTimer( UINT  nIDEvent )
{
   if( !m_bClosed )
       collapser.TimerEvent(nIDEvent);
   else 
      KillTimer(nIDEvent);

   CDialogBar::OnTimer(nIDEvent);
}

int CComposeBar::OnCreate( LPCREATESTRUCT lpCreateStruct )
{
    int retval = CDialogBar::OnCreate ( lpCreateStruct );

    CComposeFrame *pCompose = (CComposeFrame *)GetParent();
    collapser.Initialize(this,IDC_COLLAPSE);

    m_pszMessageFormat = strdup(szLoadString(pCompose->UseHtml() ? IDS_FORMAT_ASKME : IDS_FORMAT_PLAIN));

	ApiApiPtr(api);
    m_pUnkAddressControl = api->CreateClassInstance(
	    APICLASS_ADDRESSCONTROL, NULL, (APISIGNATURE)pCompose);
    m_pUnkAddressControl->QueryInterface(IID_IAddressControl,(LPVOID*)&m_pIAddressList);
    m_pIAddressList->SetControlParent(this);

    // Static text is translated to many languages
    // That's why we choose font name based on resource definition.
	CClientDC dc(this);

	LOGFONT lf;
    memset(&lf,0,sizeof(LOGFONT));
    lf.lfCharSet = DEFAULT_CHARSET;
    lf.lfPitchAndFamily = FF_SWISS | VARIABLE_PITCH;
    strcpy(lf.lfFaceName, szLoadString(IDS_FONT_PROPNAME));
    lf.lfHeight = -MulDiv(8, dc.GetDeviceCaps(LOGPIXELSY), 72);
    lf.lfQuality = PROOF_QUALITY;    
	m_cfStaticFont = theApp.CreateAppFont( lf );

	SetCSID(INTL_DefaultWinCharSetID(0)); 

    m_ToolTipInfo[IDX_TOOL_ADDRESS].Initialize(IDS_ADDRESSMESSAGE,CRect(0,0,0,0),IDC_ADDRESSTAB);
    m_ToolTipInfo[IDX_TOOL_ATTACH].Initialize(IDS_ATTACHFILE,CRect(0,0,0,0),IDC_ATTACHTAB);
    m_ToolTipInfo[IDX_TOOL_OPTIONS].Initialize(IDS_COMPOSEOPTIONS,CRect(0,0,0,0),IDC_OPTIONSTAB);
    m_ToolTipInfo[IDX_TOOL_COLLAPSE].Initialize(IDS_COMPOSEOPEN,CRect(0,0,0,0),IDC_COLLAPSE);
    
    m_pToolTip = new CNSToolTip2;
    m_pToolTip->Create(this, TTS_ALWAYSTIP);
    m_pToolTip->SetDelayTime(250);
    m_pToolTip->Activate(TRUE);

    EnableToolTips(TRUE);

   UpdateFixedSize();
   if(!m_pDropTarget) {
       m_pDropTarget = new CNSAttachDropTarget;
       m_pDropTarget->Register(this);
   }
   DragAcceptFiles();
   return retval;
}
    
void CComposeBar::SetCSID(int iCSID)
{
   CClientDC pdc ( this );
   LOGFONT lf;

   if (m_cfTextFont) {
      theApp.ReleaseAppFont(m_cfTextFont);
   }
   if (m_cfSubjectFont) {
      theApp.ReleaseAppFont(m_cfSubjectFont);
   }
   memset(&lf,0,sizeof(LOGFONT));
   if (iCSID == CS_LATIN1)
      strcpy(lf.lfFaceName, "MS Sans Serif");
   else
      strcpy(lf.lfFaceName, IntlGetUIPropFaceName(iCSID));
   lf.lfCharSet = IntlGetLfCharset(iCSID);
   lf.lfHeight = -MulDiv(8,pdc.GetDeviceCaps(LOGPIXELSY), 72);
   lf.lfQuality = PROOF_QUALITY;    

   lf.lfPitchAndFamily = FF_SWISS;
	m_cfTextFont = theApp.CreateAppFont( lf );

   XP_MEMSET(&lf,0,sizeof(LOGFONT));
   lf.lfPitchAndFamily = FF_MODERN | FIXED_PITCH;
   strcpy(lf.lfFaceName, IntlGetUIFixFaceName(iCSID));
   lf.lfCharSet = IntlGetLfCharset(iCSID); 
   lf.lfHeight = -MulDiv(9,pdc.GetDeviceCaps(LOGPIXELSY), 72);
   lf.lfQuality = PROOF_QUALITY;    
	m_cfSubjectFont = theApp.CreateAppFont( lf );

	CClientDC dc(this);
	CFont * pOldFont = dc.SelectObject(CFont::FromHandle(m_cfSubjectFont));
   TEXTMETRIC tm;
   dc.GetTextMetrics(&tm);
   m_iBoxHeight = tm.tmHeight + tm.tmExternalLeading;
   m_cxChar = tm.tmAveCharWidth;
   CString cs;
   cs.LoadString(IDS_COMPOSE_SUBJECT);
   m_iFirstX = dc.GetTextExtent(cs,cs.GetLength()).cx + (m_cxChar * 2);
   dc.SelectObject(pOldFont);
   
	if (m_pSubjectEdit) {
		::SendMessage(m_pSubjectEdit->GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfSubjectFont, FALSE);
		CalcFieldLayout();
	}
	if (m_pIAddressList) {
		m_pIAddressList->SetCSID(iCSID);
		CListBox * pListBox = m_pIAddressList->GetListBox();
		if (pListBox && pListBox->m_hWnd)
		{
			m_iMinSize = pListBox->GetItemHeight(0)*4;
			m_iMinSize += (14 + PIXEL_OFFSET_Y + m_iBoxHeight);
			if (m_iHeight < m_iMinSize) {
				m_iHeight = m_iMinSize;
			}
		}
	}
	UpdateFixedSize();
}

void CComposeBar::UpdateAttachmentInfo(int total)
{
    if (total != m_iTotalAttachments)
    {
        m_iTotalAttachments = total;
        Invalidate();
    }
}



void CComposeBar::UpdateFixedSize ( void )    
{

}

CSize CComposeBar::CalcFixedLayout(BOOL bStretch, BOOL bHorz)   
{
	CSize size;
	size.cx = (bStretch && bHorz ? 32767 : 8 );
	size.cy = GetHeightNeeded ( );
	return size;
}

void CComposeBar::UpdateHeaderInfo ( void )
{
	CComposeFrame *pCompose = (CComposeFrame *)GetParent();
    MSG_Pane *pComposePane = pCompose->GetMsgPane();
    ASSERT(pComposePane);
    UpdateOptionsInfo();
    if (m_pIAddressList->IsCreated())
    {
        MSG_HeaderEntry * entry = NULL;
        CListBox * pTypeList = m_pIAddressList->GetAddressTypeComboBox();

        // read all the entries (minus hidden fields) from the list
        CListBox * pListBox = m_pIAddressList->GetListBox();
        int count = pListBox->GetCount();
        int iTotalFields = count;
        int iTypeCount = pTypeList->GetCount();
        int i;

        for (i = 0; i < iTypeCount; i++)
        {
            int32 bHidden;
            char * pszValue;
            m_pIAddressList->GetTypeInfo(i,ADDRESS_TYPE_FLAG_HIDDEN, (void**)&bHidden);
            m_pIAddressList->GetTypeInfo(i,ADDRESS_TYPE_FLAG_VALUE,  (void**)&pszValue);
   	        if (bHidden && pszValue)
               iTotalFields++;
        }
        if (count)
	        entry = (MSG_HeaderEntry*)XP_ALLOC(sizeof(MSG_HeaderEntry)*iTotalFields);
        MSG_ClearComposeHeaders(pComposePane);
        if (entry == NULL)
	        return;
        int iRealCount = 0;
        for (i=0; i<count; i++)
        {
            char * szName, * szType;
	        if(m_pIAddressList->GetEntry(i,&szType, &szName))
	        {
		        entry[iRealCount].header_value = XP_STRDUP(szName);
		        if (!strcmp(szType,szLoadString(IDS_ADDRESSTO)))
			        entry[iRealCount].header_type = MSG_TO_HEADER_MASK;
		        else if(!strcmp(szType,szLoadString(IDS_ADDRESSCC)))
			        entry[iRealCount].header_type = MSG_CC_HEADER_MASK;
		        else if(!strcmp(szType,szLoadString(IDS_ADDRESSBCC)))
			        entry[iRealCount].header_type = MSG_BCC_HEADER_MASK;
		        else if(!strcmp(szType,szLoadString(IDS_ADDRESSNEWSGROUP)))
			        entry[iRealCount].header_type = MSG_NEWSGROUPS_HEADER_MASK;
		        else if(!strcmp(szType,szLoadString(IDS_ADDRESSFOLLOWUPTO)))
			        entry[iRealCount].header_type = MSG_FOLLOWUP_TO_HEADER_MASK;
		        else if(!strcmp(szType,szLoadString(IDS_ADDRESSREPLYTO)))
			        entry[iRealCount].header_type = MSG_REPLY_TO_HEADER_MASK;
		        iRealCount++;
	        }
        }

        // read all hidden fields from the list
        for (int j = 0; j < iTypeCount; j++)
        {
            int32 bHidden;
            char * pszValue;
            MSG_HEADER_SET header_set;
            m_pIAddressList->GetTypeInfo(j,ADDRESS_TYPE_FLAG_HIDDEN,(void**)&bHidden);
            m_pIAddressList->GetTypeInfo(j,ADDRESS_TYPE_FLAG_VALUE, (void**)&pszValue);
            m_pIAddressList->GetTypeInfo(j,ADDRESS_TYPE_FLAG_USER,  (void**)&header_set);
   	        if (bHidden && pszValue)
	        {
		        entry[iRealCount].header_type = header_set;
		        entry[iRealCount].header_value = XP_STRDUP(pszValue);
		        iRealCount++;
	        }
        }

        MSG_HeaderEntry * list;     
        count = MSG_CompressHeaderEntries(entry,iRealCount,&list);
        MSG_SetHeaderEntries(pComposePane,list,count);

        if (m_pSubjectEdit)
        {
	        CString cs;
	        m_pSubjectEdit->GetWindowText(cs);
	        MSG_SetCompHeader(pComposePane,MSG_SUBJECT_HEADER_MASK,cs);
        }

		char untranslatedPriority[32];
		MSG_GetUntranslatedPriorityName((MSG_PRIORITY) (m_iPriorityIdx+2),
										  untranslatedPriority, 32);
        MSG_SetCompHeader(pComposePane, MSG_PRIORITY_HEADER_MASK, untranslatedPriority);
        MSG_SetCompBoolHeader(pComposePane, MSG_RETURN_RECEIPT_BOOL_HEADER_MASK, m_bReceipt);
        MSG_SetCompBoolHeader(pComposePane, MSG_ENCRYPTED_BOOL_HEADER_MASK, m_bEncrypted);
        MSG_SetCompBoolHeader(pComposePane, MSG_SIGNED_BOOL_HEADER_MASK, m_bSigned);
      	MSG_SetCompBoolHeader(pComposePane, MSG_UUENCODE_BINARY_BOOL_HEADER_MASK, m_bUseUUENCODE);
        MSG_SetCompBoolHeader(pComposePane, MSG_ATTACH_VCARD_BOOL_HEADER_MASK, m_bAttachVCard);

	    if (!strcmp(m_pszMessageFormat,szLoadString(IDS_FORMAT_ASKME)))
            MSG_SetHTMLAction(pComposePane,MSG_HTMLAskUser);
        else if (!strcmp(m_pszMessageFormat,szLoadString(IDS_FORMAT_PLAIN)))
            MSG_SetHTMLAction(pComposePane,MSG_HTMLConvertToPlaintext);
        else if (!strcmp(m_pszMessageFormat,szLoadString(IDS_FORMAT_HTML)))
            MSG_SetHTMLAction(pComposePane,MSG_HTMLSendAsHTML);
        else if (!strcmp(m_pszMessageFormat,szLoadString(IDS_FORMAT_BOTH)))
            MSG_SetHTMLAction(pComposePane,MSG_HTMLUseMultipartAlternative);
        else
            ASSERT(0);
    }
}

void CComposeBar::DisplayHeaders ( MSG_HEADER_SET headers )
{
    DestroyAttachmentsPage();
    DestroyAddressPage();
	::SendMessage(GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfTextFont, FALSE);
    CreateStandardFields();
    CreateAddressPage();
    GetParentFrame()->PostMessage(WM_IDLEUPDATECMDUI);
}

int CComposeBar::GetHeightNeeded ( void )
{
    return m_iHeight;
}                 

void CComposeBar::DestroyAttachmentsPage()
{
    if (m_pAttachmentList && ::IsWindow(m_pAttachmentList->m_hWnd))
        m_pAttachmentList->ShowWindow(SW_HIDE);
    m_pWidget = NULL;
}

void CComposeBar::DestroyAddressPage()
{
    CListBox * pListBox = m_pIAddressList->GetListBox();
    if (pListBox && ::IsWindow(pListBox->m_hWnd))
    	pListBox->ShowWindow(SW_HIDE);
    m_pWidget = NULL;
}

void CComposeBar::DestroyStandardFields()
{
    if (m_pSubjectEdit && ::IsWindow(m_pSubjectEdit->m_hWnd))
    {
        m_pSubjectEdit->DestroyWindow();
        delete m_pSubjectEdit;
        m_pSubjectEdit = NULL;
    }
    if (m_pSubjectEditText && ::IsWindow(m_pSubjectEditText->m_hWnd))
    {
        m_pSubjectEditText->DestroyWindow();
        delete m_pSubjectEditText;
        m_pSubjectEditText = NULL;
    }
}

void CComposeBar::CreateOptionsPage()
{
    CString cs;

    // create the options on the left
    m_pEncrypted = new CButton;
    m_pEncrypted->Create(
        szLoadString(IDS_ENCRYPTED),WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTOCHECKBOX,
        CRect(0,0,0,0),this,ID_ENCRYPTED);
	::SendMessage(m_pEncrypted->GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfStaticFont, FALSE);
    m_pEncrypted->SetCheck(m_bEncrypted);

    m_pSigned = new CButton;
    m_pSigned->Create(
        szLoadString(IDS_SIGNED),WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTOCHECKBOX,
        CRect(0,0,0,0),this,ID_SIGNED);
	::SendMessage(m_pSigned->GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfStaticFont, FALSE);
    m_pSigned->SetCheck(m_bSigned);

    m_pUseUUENCODE = new CButton;
    m_pUseUUENCODE->Create(
        szLoadString(IDS_USEUUENCODE),WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTOCHECKBOX,
        CRect(0,0,0,0),this,1013);
	::SendMessage(m_pUseUUENCODE->GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfStaticFont, FALSE);
    m_pUseUUENCODE->SetCheck(m_bUseUUENCODE);

    m_pReturnReceipt = new CButton;
    m_pReturnReceipt->Create(
        szLoadString(IDS_RETURNRECEIPT),WS_CHILD|WS_VISIBLE|WS_TABSTOP|BS_AUTOCHECKBOX,
        CRect(0,0,0,0),this,1010);
	::SendMessage(m_pReturnReceipt->GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfStaticFont, FALSE);
    m_pReturnReceipt->SetCheck(m_bReceipt);

    // create priority combo box
    m_pPriorityText = new CStatic;
    cs.LoadString(IDS_COMPOSE_PRIORITY);
    m_pPriorityText->Create( cs, WS_CHILD | WS_VISIBLE, CRect(0,0,0,0),this,1500);
	::SendMessage(m_pPriorityText->GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfStaticFont, FALSE);
    m_pPriority = new CComboBox;
    m_pPriority->Create(
        CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP,
        CRect(0,0,0,0), this, 1501);
	::SendMessage(m_pPriority->GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfTextFont, FALSE);

	char priStr[32];
	MSG_GetPriorityName(MSG_LowestPriority, priStr, 32);
    m_pPriority->AddString (priStr);
	MSG_GetPriorityName(MSG_LowPriority, priStr, 32);
    m_pPriority->AddString (priStr);
	MSG_GetPriorityName(MSG_NormalPriority, priStr, 32);
    m_pPriority->AddString (priStr);
	MSG_GetPriorityName(MSG_HighPriority, priStr, 32);
    m_pPriority->AddString (priStr);
	MSG_GetPriorityName(MSG_HighestPriority, priStr, 32);
    m_pPriority->AddString (priStr);
    m_pPriority->SetCurSel(m_iPriorityIdx);

	CComposeFrame *pCompose = (CComposeFrame *)GetParent();
    m_pMessageFormatText = new CStatic;
    cs.LoadString(IDS_MESSAGEFORMAT);
    m_pMessageFormatText->Create( cs, WS_CHILD | WS_VISIBLE, CRect(0,0,0,0),this,1504);
	::SendMessage(m_pMessageFormatText->GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfStaticFont, FALSE);
    m_pMessageFormat = new CComboBox;
    m_pMessageFormat->Create(
        CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP,
        CRect(0,0,0,0), this, 1505);
	::SendMessage(m_pMessageFormat->GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfTextFont, FALSE);
    m_pMessageFormat->AddString(szLoadString(IDS_FORMAT_ASKME));
    m_pMessageFormat->AddString(szLoadString(IDS_FORMAT_PLAIN));
    m_pMessageFormat->AddString(szLoadString(IDS_FORMAT_HTML));
    m_pMessageFormat->AddString(szLoadString(IDS_FORMAT_BOTH ));
    int idx = m_pMessageFormat->FindString(0,m_pszMessageFormat);
    if (idx == LB_ERR)
        m_pMessageFormat->SetCurSel(pCompose->UseHtml() ? 0 : 1);     // default to askme
    else
        m_pMessageFormat->SetCurSel(idx);

    if (!pCompose->UseHtml())
        m_pMessageFormat->EnableWindow(FALSE);
    CalcFieldLayout();
}

void CComposeBar::UpdateOptionsInfo()
{
    if (m_pReturnReceipt && ::IsWindow(m_pReturnReceipt->m_hWnd))
        m_bReceipt = m_pReturnReceipt->GetCheck();
    if (m_pPriority && ::IsWindow(m_pPriority->m_hWnd))
    {
        m_iPriorityIdx = m_pPriority->GetCurSel();
		if (m_iPriorityIdx < 0)
		  m_iPriorityIdx = 2;
    }
    if (m_pMessageFormat && ::IsWindow(m_pMessageFormat->m_hWnd))
    {
        CString cs;
        int idx = m_pMessageFormat->GetCurSel();
        m_pMessageFormat->GetLBText(idx, cs);
        if (m_pszMessageFormat)
            free(m_pszMessageFormat);
        m_pszMessageFormat = strdup(cs);
    }
    if (m_pSigned && ::IsWindow(m_pSigned->m_hWnd))
        m_bSigned = m_pSigned->GetCheck();
    if (m_pEncrypted && ::IsWindow(m_pEncrypted->m_hWnd))
        m_bEncrypted = m_pEncrypted->GetCheck();
    if (m_pUseUUENCODE && ::IsWindow(m_pUseUUENCODE->m_hWnd))
        m_bUseUUENCODE = m_pUseUUENCODE->GetCheck();
}

void CComposeBar::DestroyOptionsPage()
{
    UpdateOptionsInfo();
    if (m_pPriorityText && ::IsWindow(m_pPriorityText->m_hWnd))
    {
        m_pPriorityText->DestroyWindow();
        delete m_pPriorityText;
        m_pPriorityText = NULL;
    }
    if (m_pPriority && ::IsWindow(m_pPriority->m_hWnd))
    {
        m_pPriority->DestroyWindow();
        delete m_pPriority;
        m_pPriority = NULL;
    }
    if (m_pReturnReceipt && ::IsWindow(m_pReturnReceipt->m_hWnd))
    {
        m_pReturnReceipt->DestroyWindow();
        delete m_pReturnReceipt;
        m_pReturnReceipt = NULL;
    }
    if (m_pEncrypted && ::IsWindow(m_pEncrypted->m_hWnd))
    {
        m_pEncrypted->DestroyWindow();
        delete m_pEncrypted;
        m_pEncrypted = NULL;
    }
    if (m_pUseUUENCODE && ::IsWindow(m_pUseUUENCODE->m_hWnd))
    {
        m_pUseUUENCODE->DestroyWindow();
        delete m_pUseUUENCODE;
        m_pUseUUENCODE = NULL;
    }
    if (m_pSigned && ::IsWindow(m_pSigned->m_hWnd))
    {
        m_pSigned->DestroyWindow();
        delete m_pSigned;
        m_pSigned = NULL;
    }
    if (m_pMessageFormat && ::IsWindow(m_pMessageFormat->m_hWnd))
    {
        m_pMessageFormat->DestroyWindow();
        delete m_pMessageFormat;
        m_pMessageFormat = NULL;
    }
    if (m_pMessageFormatText && ::IsWindow(m_pMessageFormatText->m_hWnd))
    {
        m_pMessageFormatText->DestroyWindow();
        delete m_pMessageFormatText;
        m_pMessageFormatText = NULL;
    }
}

void CComposeBar::CreateAttachmentsPage()
{
    CString cs;                                                                                                                                                 
    // the attachment control
    MSG_Pane *pComposePane = ((CComposeFrame *)GetParent())->GetMsgPane();
    if (!m_pAttachmentList)
    {
        m_pAttachmentList = new CNSAttachmentList(pComposePane);
        m_pAttachmentList->Create(this,1550);
    }
    else if (!m_pAttachmentList->IsWindowVisible())
        m_pAttachmentList->ShowWindow(SW_SHOW);

    m_pWidget = (CWnd *)m_pAttachmentList;
    CalcFieldLayout();
}

void CComposeBar::CreateAddressPage()
{
    CreateAddressingBlock();
    CalcFieldLayout();
}


void CComposeBar::Enable3d(BOOL bEnable)
{

}

void CComposeBar::CreateAddressingBlock(void)
{
    Enable3d(FALSE);
    CListBox * pListBox = m_pIAddressList->GetListBox();
	if (!m_pIAddressList->IsCreated()) 
	{
    	m_pIAddressList->Create(this,IDC_ADDRESSLIST);
    	m_pIAddressList->AddAddressType(szLoadString(IDS_ADDRESSTO),IDB_PERSON);
    	m_pIAddressList->AddAddressType(szLoadString(IDS_ADDRESSCC),IDB_PERSON);
    	m_pIAddressList->AddAddressType(szLoadString(IDS_ADDRESSBCC),IDB_PERSON);
    	m_pIAddressList->AddAddressType(szLoadString(IDS_ADDRESSNEWSGROUP),IDB_NEWSART, FALSE);
    	m_pIAddressList->AddAddressType(szLoadString(IDS_ADDRESSREPLYTO),IDB_PERSON, FALSE, TRUE, TRUE,(DWORD)MSG_REPLY_TO_HEADER_MASK);
    	m_pIAddressList->AddAddressType(szLoadString(IDS_ADDRESSFOLLOWUPTO), IDB_PERSON, FALSE, TRUE, TRUE, (DWORD)MSG_FOLLOWUP_TO_HEADER_MASK);
		CComposeFrame *pCompose = (CComposeFrame *)GetParentFrame();
		m_pIAddressList->SetCSID(pCompose->m_iCSID);
	}
    else if (!pListBox->IsWindowVisible())
    	pListBox->ShowWindow(SW_SHOW);
    pListBox->Invalidate();
    pListBox->UpdateWindow();
	m_iMinSize = pListBox->GetItemHeight(0)*4;
	m_iMinSize += (14 + PIXEL_OFFSET_Y + m_iBoxHeight);
	if (m_iHeight < m_iMinSize)
	{
		m_iHeight = m_iMinSize;
	}
    m_pWidget = (CWnd *)pListBox;
    Enable3d(TRUE);
}



void CComposeBar::AddedItem (HWND hwnd, LONG id,int index)
{
    char * szName = NULL;
    BOOL bRetVal = m_pIAddressList->GetEntry(index, NULL, &szName);
	if (bRetVal)
	{
		char * pszFullName = NULL;
    	ChangedItem(szName, index, hwnd, &pszFullName);
		if (pszFullName != NULL)
		{
			m_pIAddressList->SetItemName(index,pszFullName);
			free(pszFullName);
		}
	}
}

int CComposeBar::ChangedItem(char * pString, int, HWND, char** ppszFullName, unsigned long* entryID, UINT* bitmapID)
{
	(*ppszFullName) = wfe_ExpandName(pString);
	return TRUE;
}

void CComposeBar::DeletedItem (HWND hwnd, LONG id,int index)
{
}

char * CComposeBar::NameCompletion(char * pString)
{
	return wfe_ExpandForNameCompletion(pString);
}

void CComposeBar::CreateStandardFields(void)
{
    // create subject edit field
    m_pSubjectEditText = new CStatic;
    CString cs;
    cs.LoadString(IDS_COMPOSE_SUBJECT);
    m_pSubjectEditText->Create( cs, WS_CHILD | WS_VISIBLE, CRect(0,0,0,0), this, 1500 );
	::SendMessage(m_pSubjectEditText->GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfStaticFont, FALSE);

    m_pSubjectEdit = new CComposeSubjectEdit;
    m_pSubjectEdit->Create(
    	WS_CHILD | WS_VISIBLE | WS_TABSTOP | ES_AUTOHSCROLL, 
    	CRect(0,0,0,0), (CWnd *) this, IDC_SUBJECT_EDIT );
	::SendMessage(m_pSubjectEdit->GetSafeHwnd(), WM_SETFONT, (WPARAM)m_cfSubjectFont, FALSE);
#ifdef XP_WIN32
	if (sysInfo.m_bWin4)
	{
		::SendMessage(m_pSubjectEdit->m_hWnd, EM_SETMARGINS, EC_LEFTMARGIN, 0L);
		::SendMessage(m_pSubjectEdit->m_hWnd, EM_SETMARGINS, EC_RIGHTMARGIN, 0L);
	}
#endif
    m_pSubjectEdit->SetWindowText( "" );
}

// This function recalculates the field layout based on the window width
// for the subject, priority, address widget, and buttons...
// This function assumes that the fields are created already.

#define FIELD_PIXEL_OFFSET  3
#define TEXT_PIXEL_OFFSET   4

void CComposeBar::CalcFieldLayout(void)
{
    CRect WinRect, rect;
    GetClientRect(WinRect);
    int x = WinRect.Width();
    int controlWidth;
    
    CDC * pDC = m_pSubjectEditText->GetDC();
    CString cs;
    m_pSubjectEditText->GetWindowText(cs);
#ifdef _WIN32
    controlWidth = pDC->GetTextExtent(cs).cx - 16;
#else
    controlWidth = pDC->GetTextExtent(LPCTSTR(cs), cs.GetLength()).cx - 16;
#endif
    ReleaseDC(pDC);

    pDC = GetDC();
    int pix_per_inch_x = pDC->GetDeviceCaps(LOGPIXELSX);
    int pix_per_inch_y = pDC->GetDeviceCaps(LOGPIXELSY);
    ReleaseDC(pDC);

    GetWidgetRect(WinRect,rect);
    rect.bottom = WinRect.Height() - 2;
    CRect rect2 = rect;
    rect2.bottom -= 2;
    rect2.left = COMP_VTAB_WIDTH + COMP_LEFT_MARGIN;
    rect2.right = rect2.left + controlWidth;
    rect2.top = rect2.bottom - m_iBoxHeight;

    m_pSubjectEditText->MoveWindow(rect2);

    rect2.left = rect2.right + 4;
    rect2.right = rect.right;
    rect2.top--;
    m_pSubjectEdit->MoveWindow(rect2);
    
    // resize and position the buttons.
    BOOL bHasButtons = FALSE;

    x = m_cxChar + TAB_SPACING_X + 4;
    int y = PIXEL_OFFSET_Y + 2;
    int iButtonWidth = 0;

    CRect parentRect;
    GetParentFrame()->GetWindowRect(parentRect);
    m_iMaxSize = parentRect.Height()-(m_iBoxHeight*3);
    if (m_iMaxSize <= 0)
       m_iMaxSize = m_iBoxHeight*3;

    if (m_pWidget)
    {
    	ASSERT(::IsWindow(m_pWidget->m_hWnd));
		GetWidgetRect(WinRect,rect);
		int pix_x = 2; //pix_per_inch_x/PIX_X_FACTOR;
		int pix_y = 2; //pix_per_inch_y/PIX_Y_FACTOR;
		rect.InflateRect(-pix_x,-pix_y);
		rect.left += pix_x;
		m_pWidget->MoveWindow(rect);
    }

    // options page
    if (m_iSelectedTab == IDX_COMPOSEOPTIONS && 
       m_pPriority && ::IsWindow(m_pPriority->m_hWnd))
    {
	    // allign the text
	    rect.top = (PIXEL_OFFSET_Y+TEXT_PIXEL_OFFSET);
	    rect.bottom = rect.top + m_iBoxHeight;
	    rect.left = x + m_cxChar * 3;
	    rect.right = (WinRect.Width()/2) + 24;
	    m_pEncrypted->MoveWindow(rect);

	    rect.top = rect.bottom + 1;
	    rect.bottom = rect.top + m_iBoxHeight;
	    m_pSigned->MoveWindow(rect);

	    rect.top = rect.bottom + 1;
	    rect.bottom = rect.top + m_iBoxHeight;
	    m_pUseUUENCODE->MoveWindow(rect);

	    ASSERT(::IsWindow(m_pPriorityText->m_hWnd));
	    pDC = m_pPriorityText->GetDC();
	    m_pPriorityText->GetWindowText(cs);
#ifdef _WIN32
	    controlWidth = pDC->GetTextExtent(cs).cx - 16;
#else
	    controlWidth = pDC->GetTextExtent(LPCTSTR(cs), cs.GetLength()).cx - 16;
#endif
        m_pMessageFormatText->GetWindowText(cs);
#ifdef _WIN32
	    controlWidth = max(controlWidth,pDC->GetTextExtent(cs).cx - 16);
#else
	    controlWidth = max(controlWidth,pDC->GetTextExtent(LPCTSTR(cs), cs.GetLength()).cx - 16);
#endif
	    ReleaseDC(pDC);

       CRect rect3;
 		 GetWidgetRect(WinRect,rect3);
	    rect.top = (PIXEL_OFFSET_Y+TEXT_PIXEL_OFFSET);
	    rect.bottom = rect.top + m_iBoxHeight;
	    rect.left = rect.right + 2;
       rect.right = rect3.right - 2;
       m_pReturnReceipt->MoveWindow(rect);

	    rect.right = rect.left + controlWidth;
	    rect.top = rect.bottom + 7;
	    rect.bottom = rect.top + m_iBoxHeight;
       rect2 = rect;

	    m_pPriorityText->MoveWindow(rect);

	    CDC * pDC = m_pPriority->GetDC();
	    int i, maxwidth = 0;
	    CString cs;
	    // find the longest string in the priority box
	    for (i=0; i<m_pPriority->GetCount(); i++)
	    {
	        m_pPriority->GetLBText(i,cs);
#ifdef _WIN32
            CSize size = pDC->GetTextExtent(cs);
#else
            CSize size = pDC->GetTextExtent(LPCTSTR(cs), cs.GetLength());
#endif
	        maxwidth = max(size.cx,maxwidth);
	    }

	    for (i=0; i<m_pMessageFormat->GetCount(); i++)
	    {
            m_pMessageFormat->GetLBText(i,cs);
#ifdef _WIN32
            CSize size = pDC->GetTextExtent(cs);
#else
            CSize size = pDC->GetTextExtent(LPCTSTR(cs), cs.GetLength());
#endif
	        maxwidth = max(size.cx,maxwidth);
	    }

        ReleaseDC(pDC);

        // right allign it    
        rect2.top -= TEXT_PIXEL_OFFSET;
        rect2.bottom = rect2.top + (m_iBoxHeight+2)*8;
        rect2.left = rect2.right;
        rect2.right = rect2.left + maxwidth + GetSystemMetrics(SM_CXHSCROLL) + 2;
        int iOldHeight = rect2.Height();
        m_pPriority->MoveWindow(rect2);

        rect.top = rect.bottom + TEXT_PIXEL_OFFSET + 4;
        rect.bottom = rect.top + m_iBoxHeight;
        m_pMessageFormatText->MoveWindow(rect);

        rect2.top = rect.top - TEXT_PIXEL_OFFSET;
        rect2.bottom = rect2.top + (m_iBoxHeight+2)*8;
        m_pMessageFormat->MoveWindow(rect2);

    }
}

int CComposeBar::OnToolHitTest( CPoint point, TOOLINFO* pTI ) const
{
    if (pTI != NULL)
    {
	    for (int i = 0; i < MAX_TIPS; i++)
	    {
	        if (m_ToolTipInfo[i].m_rect.PtInRect(point))
	        {

		    pTI->hwnd = m_hWnd;
		    pTI->rect = m_ToolTipInfo[i].m_rect;
		    if (i == IDX_TOOL_COLLAPSE && m_bClosed == TRUE)
		    {
		        CString cs;
		        cs.LoadString(IDS_COMPOSECLOSE);
		        pTI->lpszText = strdup(cs);
		    }
		    else
		        pTI->lpszText = strdup(m_ToolTipInfo[i].m_csToolTip);
		    pTI->uId = i;
		    return 1;
	        }
	    }
    }
#ifdef XP_WIN32
    return CDialogBar::OnToolHitTest(point,pTI);
#else
    return FALSE;
#endif
}

void CComposeBar::UpdateRecipientInfo ( char *pTo, char *pCc, char *pBcc )
{
}

void CComposeBar::AttachFile(void)
{
    ASSERT(m_pAttachmentList);
    m_pAttachmentList->AttachFile();
}

void CComposeBar::AttachUrl(void)
{
   CComposeFrame *pCompose = (CComposeFrame *)GetParent();
   MSG_Pane *pComposePane = pCompose->GetMsgPane();
   ASSERT(m_pAttachmentList);
   char * pUrl =  (char*)MSG_GetAssociatedURL(pComposePane);
   m_pAttachmentList->AttachUrl(pUrl);
}
    
extern "C" char * wfe_ExpandForNameCompletion(char * pString)
{
    ABID entryID = -1;
    ABID field = -1;
	DIR_Server* pab  = NULL;

	DIR_GetComposeNameCompletionAddressBook (theApp.m_directories, &pab);
    if (pab != NULL && theApp.m_pABook)
    {
	AB_GetIDForNameCompletion(
	    theApp.m_pABook,
	    pab, 
	    &entryID,&field,(LPCTSTR)pString);
	if (entryID != -1)
	{
		    if (field == ABNickname) {
			    char szNickname[kMaxNameLength];
			    AB_GetNickname(
				    pab, 
				    theApp.m_pABook, entryID, szNickname);
			    if (strlen(szNickname))
				    return strdup(szNickname);
		    }
	    else {
			    char szFullname[kMaxFullNameLength];
			    AB_GetFullName(pab, theApp.m_pABook, 
				    entryID, szFullname);
			    if (strlen(szFullname))
				    return strdup(szFullname);
		    }
	    }
    }

	return NULL;
}

extern "C" char * wfe_ExpandName(char * pString)
{
	ABID entryID = -1;
	ABID field = -1;
	char * fullname = NULL;

	DIR_Server* pab  = NULL;

	DIR_GetComposeNameCompletionAddressBook (theApp.m_directories, &pab);
    if (pab != NULL && theApp.m_pABook)
    {
	    AB_GetIDForNameCompletion(
		    theApp.m_pABook,
		    pab,
		    &entryID, &field,pString);
	    if (entryID != -1)
	    {
		    AB_GetExpandedName(
			    pab, 
			    theApp.m_pABook, entryID, &fullname);
		    if (fullname)
			    return fullname;
    	}
    }
	return NULL;
}


void CComposeBar::OnDropFiles( HDROP hDropInfo )
{
   UINT wNumFilesDropped = ::DragQueryFile(hDropInfo,(UINT)-1,NULL,0);
   if (wNumFilesDropped > 0)
   {
      OnAttachTab();
      UpdateWindow();
      if (m_pAttachmentList && ::IsWindow(m_pAttachmentList->m_hWnd))
         m_pAttachmentList->OnDropFiles(hDropInfo);
   }
}

BOOL CComposeBar::ProcessVCardData(COleDataObject * pDataObject, CPoint &point)
{
   UINT clipFormat;
   BOOL retVal;
   CWnd * pWnd = GetFocus();
   if(pDataObject->IsDataAvailable(
      clipFormat = ::RegisterClipboardFormat(vCardClipboardFormat))) 
   {
      HGLOBAL hAddresses = pDataObject->GetGlobalData(clipFormat);
      LPSTR pAddresses = (LPSTR)GlobalLock(hAddresses);
      ASSERT(pAddresses);
      XP_List * pEntries;
      int32 iEntries;
		CComposeFrame *pCompose = (CComposeFrame *)GetParentFrame();
   	ApiApiPtr(api);
	   LPUNKNOWN pUnk = api->CreateClassInstance(
 		   APICLASS_ADDRESSCONTROL, NULL, (APISIGNATURE)pCompose);
 		LPADDRESSCONTROL pIAddressControl = NULL;
   	if (pUnk)
   	{
   		HRESULT hRes = pUnk->QueryInterface(IID_IAddressControl,(LPVOID*)&pIAddressControl);
   		ASSERT(hRes==NOERROR);
   	}
      if (pIAddressControl)
      {
         int itemNum = pIAddressControl->GetItemFromPoint(&point);
         char * szType = NULL;
         char * szName = NULL;
         CListBox * pListBox = pIAddressControl->GetListBox();
         if (itemNum <= pListBox->GetCount())
            pIAddressControl->GetEntry (itemNum, &szType, &szName); 
         char * pszType = strdup(szType);
         if (!AB_ConvertVCardsToExpandedName(theApp.m_pABook,pAddresses,&pEntries,&iEntries))
         {
            XP_List * node = pEntries;
            if (pListBox->GetCount() == 1 && (!szName || !strlen(szName)))
               pListBox->ResetContent();
            else
               if (!szName || !strlen(szName))
                  pIAddressControl->DeleteEntry(itemNum);
            for (int32 i = 0; i < iEntries+1; i++)
            {
               char * pString = (char *)node->object;
               if (pString != NULL)
                  pIAddressControl->AppendEntry(FALSE, pszType,pString,IDB_PERSON);
               node = node->next;
               if (!node)
                  break;
            }
            XP_ListDestroy(pEntries);
         }
         if (pUnk)
            pUnk->Release();
         if (pszType)
            free(pszType);
         GlobalUnlock(hAddresses);
         retVal = TRUE;
      }
   }
   if (pWnd && ::IsWindow(pWnd->m_hWnd))
      pWnd->SetFocus();
   return retVal;
}


//////////////////////////////////////////////////////////////////////////////
// CNSCollapser

#define IDT_CNSCOLLAPSER 16425

CNSCollapser::CNSCollapser()
{
   m_hVertSectionBitmap =  NULL;
   m_hHTabBitmap =         NULL;
   m_bHilite =             FALSE;
}

CNSCollapser::~CNSCollapser()
{
   if (m_hVertSectionBitmap)
      VERIFY(::DeleteObject( (HGDIOBJ) m_hVertSectionBitmap ));
   if (m_hHTabBitmap)
      VERIFY(::DeleteObject( (HGDIOBJ) m_hHTabBitmap ));
}

void CNSCollapser::Initialize(CWnd * pWnd, UINT nCmdId)
{
   m_pWnd = pWnd;
   m_cmdId = nCmdId;
}

void CNSCollapser::DrawCollapseWidget(CDC &dc, COLLAPSE_STATE state, BOOL bHilite, int iSubtract)
{
   // this is the flippy thing
   if ( !m_hVertSectionBitmap ) 
   {
   	m_hVertSectionBitmap = WFE_LoadSysColorBitmap( 
   	    AfxGetResourceHandle(), 
          MAKEINTRESOURCE(IDB_VERTICALTAB));
   }
   if ( !m_hHTabBitmap ) 
   {
   	m_hHTabBitmap = WFE_LoadSysColorBitmap( 
   	    AfxGetResourceHandle(), 
          MAKEINTRESOURCE(IDB_LARGE_HFTAB));
   }

   m_cState = state;
   m_iSubtract = iSubtract;
   CDC dcVSection;
   dcVSection.CreateCompatibleDC(&dc);
   HBITMAP hOldBitmap = (HBITMAP)dcVSection.SelectObject(
      state == collapse_closed ? m_hHTabBitmap : m_hVertSectionBitmap);

   CRect rect, WinRect;
   m_pWnd->GetClientRect(&WinRect);

   rect.left   = 0;
   rect.top    = 2;
   rect.right  = COMP_VTAB_WIDTH;
   rect.bottom = WinRect.Height() - iSubtract;

   if (state == collapse_closed)
   {
      BITMAP bm;
      ::GetObject(m_hHTabBitmap,sizeof(BITMAP),(LPVOID)&bm);
      rect.right = bm.bmWidth;
      rect.bottom = 2 + COMP_HTAB_HEIGHT;
   }
   
   m_rect = rect;

   if (state == collapse_closed)
   {
      int ySrc = bHilite ? COMP_HTAB_HEIGHT : 0;
      dc.BitBlt( 
      	rect.left, rect.top, rect.Width(), COMP_HTAB_HEIGHT,
      	&dcVSection, 0, ySrc, SRCCOPY );
   }
   else 
   {
      int xSrc = bHilite ? COMP_VTAB_WIDTH : 0;
      dc.BitBlt( 
   	   rect.left, rect.top, COMP_VTAB_WIDTH, COMP_VTAB_TOP_HEIGHT,
   	   &dcVSection, xSrc, 0, SRCCOPY );
      int iMidSectionHeight = rect.Height()-(COMP_VTAB_TOP_HEIGHT+COMP_VTAB_BOTTOM_HEIGHT);
      int iRemainingHeight = iMidSectionHeight%COMP_VTAB_SECTION_HEIGHT;
      rect.top += COMP_VTAB_TOP_HEIGHT;
      if (iMidSectionHeight > COMP_VTAB_SECTION_HEIGHT)
      {
         int iSections = iMidSectionHeight/COMP_VTAB_SECTION_HEIGHT;
         for (int i = 0; i < iSections; i++)
         {
            dc.BitBlt( 
               rect.left, rect.top, COMP_VTAB_WIDTH, COMP_VTAB_SECTION_HEIGHT,
    	         &dcVSection, xSrc, COMP_VTAB_TOP_HEIGHT+1, SRCCOPY );
            rect.top += COMP_VTAB_SECTION_HEIGHT;            
         }
      }
      if (iRemainingHeight)
      {
         dc.BitBlt( 
            rect.left, rect.top, COMP_VTAB_WIDTH, iRemainingHeight,
    	      &dcVSection, xSrc, COMP_VTAB_TOP_HEIGHT + 1, SRCCOPY );
         rect.top += iRemainingHeight;
      }

      dc.BitBlt( 
         rect.left, rect.top, COMP_VTAB_WIDTH, COMP_VTAB_BOTTOM_HEIGHT,
    	   &dcVSection, xSrc, COMP_VTAB_TOP_HEIGHT + COMP_VTAB_SECTION_HEIGHT + 2, SRCCOPY );
   }

   dcVSection.SelectObject(hOldBitmap);
   VERIFY(dcVSection.DeleteDC());
}

void CNSCollapser::TimerEvent(UINT nIDEvent)
{
	CRect rect;
	m_pWnd->GetWindowRect(&rect);
	POINT pt;
	GetCursorPos(&pt);

	if(nIDEvent == IDT_CNSCOLLAPSER)
	{
		if(!rect.PtInRect(pt))
		{
         m_bHilite = FALSE;
			m_pWnd->KillTimer(m_nTimer);
         CDC * pDC = m_pWnd->GetDC();
         DrawCollapseWidget(*pDC, m_cState, FALSE, m_iSubtract);
         m_pWnd->ReleaseDC(pDC);
		}
	}
}

BOOL CNSCollapser::ButtonPress(POINT & point)
{
   if (m_rect.PtInRect(point))
   {
      m_pWnd->SendMessage(WM_COMMAND, m_cmdId);
      return TRUE;
   }
   return FALSE;
}

void CNSCollapser::MouseAround(POINT & point)
{
   if (m_rect.PtInRect(point))
   {
      if (!m_bHilite)
      {
         m_bHilite = TRUE;
			m_nTimer = m_pWnd->SetTimer(IDT_CNSCOLLAPSER, 100, NULL);
         CDC * pDC = m_pWnd->GetDC();
         DrawCollapseWidget(*pDC, m_cState, m_bHilite, m_iSubtract);
         m_pWnd->ReleaseDC(pDC);
      }
   }
   else
   {
      if (m_bHilite)
      {
         m_bHilite = FALSE;
         CDC * pDC = m_pWnd->GetDC();
         DrawCollapseWidget(*pDC, m_cState, m_bHilite, m_iSubtract);
         m_pWnd->ReleaseDC(pDC);
      }
   }
}



void CComposeBar::OnUpdateOptions(void)
{
   UpdateOptionsInfo();
}

void CComposeBar::UpdateSecurityOptions(void)
{
    if (m_iSelectedTab == IDX_COMPOSEOPTIONS)
    {
        if (m_pEncrypted && ::IsWindow(m_pEncrypted->m_hWnd))
           m_pEncrypted->SetCheck(m_bEncrypted);
        if (m_pSigned && ::IsWindow(m_pSigned->m_hWnd))
            m_pSigned->SetCheck(m_bSigned);
    }

}
