/*****************************************************************************
Draws "+", "-" and lines that show a tree graphic

*****************************************************************************/
void CGridTreeCellBase::TreeDrawGraphic(CDC* apDC,      // current CDC
                                    CRect aRect)    // coordinates of bounding cell rectangle
{
    ASSERT( apDC != NULL);
    ASSERT( m_pTreeColumn != NULL);
    ASSERT( m_pTreeColumn->GetAllowDraw());

    int iNbrTreeElements = m_pTreeColumn->GetRowCount() - m_pTreeColumn->GetFixedRowCount();

    // get current level
    unsigned char ucLevelCurrent = GetLevel();
    ASSERT( IsViewable() ); // can't deal with hidden rows!
    if( ucLevelCurrent <= 0)
    {
        if( m_pTreeColumn->GetTreeUsesImages())
            SetImage( TREE_IMAGE_DOCUMENT);
        return;     // no + / - box if level 0
    }

    BOOL bIsNextShowing;
    unsigned char ucLevelNext;
    int iLineStop;


    if( m_pTreeColumn->GetDefTreeIndent() < TREE_BOX_MARGIN * 3)
        return; // too small to draw the graphic

    CRect RectRel;
    TreeGetBoxRelCoords( &RectRel);      // returns: relative coordinates
    CRect RectBox( RectRel);
    RectBox.OffsetRect( aRect.left, aRect.top);

    int iXCenter = RectBox.left + ( (RectBox.right - RectBox.left) / 2);
    int iYCenter = RectBox.top + ( (RectBox.bottom - RectBox.top) / 2);

    CPen psPen(PS_SOLID, 1, m_pTreeColumn->GetTreeLineColor() );
    CPen* pOldPen = apDC->SelectObject(&psPen);

    TREE_IMAGE TreeImage = TREE_IMAGE_DOCUMENT;

    // is it the very last row?
    if( !GetForcePlus()  &&  m_iRow >= m_pTreeColumn->GetRowCount() - 1)
    {
        iXCenter -= m_pTreeColumn->GetDefTreeIndent();

        // draw |__ (with long horizontal)
        if( TryMoveTo( aRect, apDC, iXCenter, aRect.top) )
            if( TryLineTo( aRect, apDC, iXCenter, iYCenter) )
                TryLineTo( aRect, apDC, RectBox.right, iYCenter);

        apDC->SelectObject(pOldPen);
        if( m_pTreeColumn->GetTreeUsesImages())
            SetImage( TreeImage);
        return;
    }

    // is it a plus or minus?  Check up to all remaining entries for an answer
    BOOL bIsPlus;
    BOOL bIsMinus;
    BOOL bIsLastLeaf;
    CGridCtrl* pGrid = GetGrid();
    ASSERT( pGrid != NULL);

    int iVertLineBottom = aRect.bottom + 1; // if drawing a horizontal line,
                                            //  overwrite the grid line in case it is
                                            //  not displayed

    BOOL bIsBranch = m_pTreeColumn->TreeCellHasPlusMinus(
                                m_iRow,          // row of Cell to check
                                &bIsPlus,    // returns:  T=Is a plus
                                &bIsMinus,   // returns:  T=Is a minus
                                &bIsLastLeaf);// returns:  T=Is Last Leaf

    if( bIsBranch )
    {
        // returns:  T=cell has a plus or minus;  F=not

        if( bIsPlus)
            TreeImage = TREE_IMAGE_FOLDER_CLOSED;
        else
            TreeImage = TREE_IMAGE_FOLDER_OPEN;

        // draw a square box
        BOOL bCanDrawRectangle =    aRect.PtInRect( CPoint( RectBox.left, RectBox.top ))
                                    && aRect.PtInRect( CPoint( RectBox.right, RectBox.bottom ));

        if( bCanDrawRectangle )
        {
            apDC->Rectangle(    RectBox.left,
                                RectBox.top,
                                RectBox.right,
                                RectBox.bottom);
        }

        // draw a minus sign
        if( TryMoveTo( aRect, apDC, RectBox.left + TREE_BOX_MARGIN, iYCenter) )
            TryLineTo( aRect, apDC, RectBox.right - TREE_BOX_MARGIN, iYCenter);

        // draw small horizontal tick just to the left of the box if not
        //  level 1
        if( ucLevelCurrent > 1)
        {
            // draw -
            if( TryMoveTo( aRect, apDC, iXCenter - m_pTreeColumn->GetDefTreeIndent(), iYCenter) )
                TryLineTo( aRect, apDC, RectBox.left, iYCenter);
        }

        if( bIsPlus)
        {
            // ... make it into a plus sign
            if( TryMoveTo( aRect, apDC, iXCenter, RectBox.top + TREE_BOX_MARGIN) )
                TryLineTo( aRect, apDC, iXCenter, RectBox.bottom - TREE_BOX_MARGIN);
        }
        else
        {
            // it's a minus sign, so draw vertical tick below box center

            // draw |
            if( TryMoveTo( aRect, apDC, iXCenter, RectBox.bottom) )
                TryLineTo( aRect, apDC, iXCenter, iVertLineBottom);
        }

    }
    else if( ucLevelCurrent > 1)
    {
        // it's not a box, it's a leaf of the tree.  Just draw a horizontal line

        CGridTreeCellBase* pGridTreeCellBase = (CGridTreeCellBase*)pGrid->GetCell( m_iRow + 1, m_pTreeColumn->GetColumnWithTree());
        if( pGridTreeCellBase == NULL)
            return;

        bIsNextShowing = pGridTreeCellBase->IsViewable();
        ucLevelNext = pGridTreeCellBase->GetLevel();


        if( ucLevelCurrent > ucLevelNext)
        {
            bIsLastLeaf = TRUE;
        }

        // draw -
        if( TryMoveTo( aRect, apDC, iXCenter - m_pTreeColumn->GetDefTreeIndent(), iYCenter) )
            TryLineTo( aRect, apDC, iXCenter, iYCenter);
    }

    // draw nearest to text vertical lines that appear to the left of the box for all
    //  levels except level 1
    if( ucLevelCurrent > 1)
    {
        iXCenter -= m_pTreeColumn->GetDefTreeIndent();
        if( bIsLastLeaf)
            iLineStop = iYCenter;
        else
            iLineStop = iVertLineBottom;

        // draw |
        if( TryMoveTo( aRect, apDC, iXCenter, aRect.top) )
            TryLineTo( aRect, apDC, iXCenter, iLineStop);
    }

    BOOL bFoundBranch;
    unsigned char ucLevelToCheck = ucLevelCurrent;

    // draw vertical lines that appear to the left of the box for all appropriate
    //  levels except level 1
    for( int i1=ucLevelCurrent - 1; i1 > 1; i1--)
    {
        bFoundBranch = FALSE;

        int iStartPt = m_iRow + 1;

        for( int i2=iStartPt; i2 <= iNbrTreeElements; i2++)
        {
            CGridTreeCellBase* pGridTreeCellBase = (CGridTreeCellBase*)pGrid->GetCell(
                                                i2,
                                                m_pTreeColumn->GetColumnWithTree());
            if( pGridTreeCellBase == NULL)
                return;

            ucLevelNext = pGridTreeCellBase->GetLevel();

            if( ucLevelNext + 1 < ucLevelToCheck)
                break;

            if( ucLevelNext + 1 == ucLevelToCheck)
            {
                bIsNextShowing = pGridTreeCellBase->IsViewable();
                if( bIsNextShowing)
                    bFoundBranch = TRUE;
                break;
            }

        }

        iXCenter -= m_pTreeColumn->GetDefTreeIndent();

        if( bFoundBranch)
        {
            // draw |
            if( TryMoveTo( aRect, apDC, iXCenter, aRect.top) )
                TryLineTo( aRect, apDC, iXCenter, iVertLineBottom);
        }
        ucLevelToCheck--;   // each loop heads to level 1
    }

    // cleanup
    apDC->SelectObject(pOldPen);

    if( m_pTreeColumn->GetTreeUsesImages())
        SetImage( TreeImage);

}