/**************************************************************
 * 
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 * 
 *************************************************************/


#if defined(_MSC_VER) && (_MSC_VER > 1310)
#pragma warning(disable : 4917 4555)
#endif

#include "stdafx.h"
#include <stddef.h>
#include "syswinwrapper.hxx"


HCURSOR _afxCursors[10] = { 0, };
HBRUSH _afxHalftoneBrush = 0;


// the struct below is used to determine the qualities of a particular handle
struct AFX_HANDLEINFO
{
    size_t nOffsetX;    // offset within RECT for X coordinate
    size_t nOffsetY;    // offset within RECT for Y coordinate
    int nCenterX;       // adjust X by Width()/2 * this number
    int nCenterY;       // adjust Y by Height()/2 * this number
    int nHandleX;       // adjust X by handle size * this number
    int nHandleY;       // adjust Y by handle size * this number
    int nInvertX;       // handle converts to this when X inverted
    int nInvertY;       // handle converts to this when Y inverted
};

// this array describes all 8 handles (clock-wise)
const AFX_HANDLEINFO _afxHandleInfo[] =
{
    // corner handles (top-left, top-right, bottom-right, bottom-left
    { offsetof(RECT, left), offsetof(RECT, top),        0, 0,  0,  0, 1, 3 },
    { offsetof(RECT, right), offsetof(RECT, top),       0, 0, -1,  0, 0, 2 },
    { offsetof(RECT, right), offsetof(RECT, bottom),    0, 0, -1, -1, 3, 1 },
    { offsetof(RECT, left), offsetof(RECT, bottom),     0, 0,  0, -1, 2, 0 },

    // side handles (top, right, bottom, left)
    { offsetof(RECT, left), offsetof(RECT, top),        1, 0,  0,  0, 4, 6 },
    { offsetof(RECT, right), offsetof(RECT, top),       0, 1, -1,  0, 7, 5 },
    { offsetof(RECT, left), offsetof(RECT, bottom),     1, 0,  0, -1, 6, 4 },
    { offsetof(RECT, left), offsetof(RECT, top),        0, 1,  0,  0, 5, 7 }
};

// the struct below gives us information on the layout of a RECT struct and
//  the relationship between its members
struct AFX_RECTINFO
{
    size_t nOffsetAcross;   // offset of opposite point (ie. left->right)
    int nSignAcross;        // sign relative to that point (ie. add/subtract)
};

// this array is indexed by the offset of the RECT member / sizeof(int)
const AFX_RECTINFO _afxRectInfo[] =
{
    { offsetof(RECT, right), +1 },
    { offsetof(RECT, bottom), +1 },
    { offsetof(RECT, left), -1 },
    { offsetof(RECT, top), -1 },
};


HBRUSH HalftoneBrush()
{
    if (_afxHalftoneBrush == NULL)
    {
        WORD grayPattern[8];
        for (int i = 0; i < 8; i++)
            grayPattern[i] = (WORD)(0x5555 << (i & 1));
        HBITMAP grayBitmap = CreateBitmap(8, 8, 1, 1, &grayPattern);
        if (grayBitmap != NULL)
        {
            _afxHalftoneBrush = CreatePatternBrush(grayBitmap);
            DeleteObject(grayBitmap);
        }
    }
    return _afxHalftoneBrush;
}



void DrawDragRect(
    HDC hDC,LPRECT lpRect,SIZE size,
    LPRECT lpRectLast,SIZE sizeLast,
    HBRUSH hBrush = NULL,HBRUSH hBrushLast = NULL)
{
    // first, determine the update region and select it
    HRGN rgnNew;
    HRGN rgnOutside,rgnInside;
    rgnOutside = CreateRectRgnIndirect(lpRect);
    RECT rect = *lpRect;
    InflateRect(&rect,-size.cx, -size.cy);
    IntersectRect(&rect,&rect,lpRect);
    rgnInside = CreateRectRgnIndirect(&rect);
    rgnNew = CreateRectRgn(0, 0, 0, 0);
    CombineRgn(rgnNew,rgnOutside,rgnInside,RGN_XOR);

    HBRUSH hBrushOld = NULL;
    if (hBrush == NULL)
        hBrush = HalftoneBrush();
    if (hBrushLast == NULL)
        hBrushLast = hBrush;

    HRGN rgnLast(NULL);
    HRGN rgnUpdate(NULL);
    if (lpRectLast != NULL)
    {
        // find difference between new region and old region
        rgnLast = CreateRectRgn(0, 0, 0, 0);
        SetRectRgn(
            rgnOutside,
            lpRectLast->left,
            lpRectLast->top,
            lpRectLast->right,
            lpRectLast->bottom);
        rect = *lpRectLast;
        InflateRect(&rect,-sizeLast.cx, -sizeLast.cy);
        IntersectRect(&rect,&rect, lpRectLast);
        SetRectRgn(rgnInside,rect.left,rect.top,rect.right,rect.bottom);
        CombineRgn(rgnLast,rgnOutside,rgnInside, RGN_XOR);

// 		// only diff them if brushes are the same
        if (hBrush == hBrushLast)
        {
            rgnUpdate = CreateRectRgn(0, 0, 0, 0);
            CombineRgn(rgnUpdate,rgnLast,rgnNew, RGN_XOR);
        }
    }
    if (hBrush != hBrushLast && lpRectLast != NULL)
    {
        // brushes are different -- erase old region first
        SelectClipRgn(hDC,rgnLast);
        GetClipBox(hDC,&rect);
        hBrushOld = (HBRUSH)SelectObject(hDC,(HGDIOBJ)hBrushLast);
        PatBlt(hDC,rect.left,rect.top,(rect.right-rect.left),(rect.bottom-rect.top),PATINVERT);

        SelectObject(hDC,(HGDIOBJ)hBrushOld);
        hBrushOld = NULL;
    }

    // draw into the update/new region
    SelectClipRgn(hDC,rgnUpdate);

    GetClipBox(hDC,&rect);
    hBrushOld = (HBRUSH) SelectObject(hDC,(HGDIOBJ) hBrush);
    PatBlt(hDC,rect.left, rect.top,(rect.right-rect.left),(rect.bottom-rect.top), PATINVERT);

    // cleanup DC
    if (hBrushOld != NULL)
        SelectObject(hDC,(HGDIOBJ)hBrushOld);
    SelectClipRgn(hDC,NULL);
}


void winwrap::TransformRect(LPRECT rect,HWND pWnd,HWND pWndClipTo)
{
    POINT pt;
    pt.x = rect->left;pt.y = rect->top;
    ClientToScreen(pWnd,&pt);
    ScreenToClient(pWndClipTo,&pt);
    rect->left = pt.x; rect->top = pt.y;

    pt.x = rect->right;pt.y = rect->bottom;
    ClientToScreen(pWnd,&pt);
    ScreenToClient(pWndClipTo,&pt);
    rect->right = pt.x; rect->bottom = pt.y;
}


void NormalizeRect(LPRECT rp)
{
    if(rp->left > rp->right) {
        UINT tmp = rp->left;
        rp->left = rp->right;
        rp->right = tmp;
    }
    
    if(rp->top > rp->bottom) {
        UINT tmp = rp->top;
        rp->top = rp->bottom;
        rp->bottom = tmp;
    }
}


using namespace winwrap;


Tracker::Tracker()
{
}


Tracker::Tracker(LPCRECT lpSrcRect, UINT nStyle)
{
    Construct();
    CopyRect(&m_rect,lpSrcRect);
    m_nStyle = nStyle;
}

HBRUSH _afxHatchBrush = 0;
HPEN _afxBlackDottedPen = 0;
int _afxHandleSize = 0;


void Tracker::Construct()
{
    static BOOL bInitialized = false;
    if (!bInitialized)
    {
        if (_afxHatchBrush == NULL)
        {
            // create the hatch pattern + bitmap
            WORD hatchPattern[8];
            WORD wPattern = 0x1111;
            for (int i = 0; i < 4; i++)
            {
                hatchPattern[i] = wPattern;
                hatchPattern[i+4] = wPattern;
                wPattern <<= 1;
            }
            HBITMAP hatchBitmap = CreateBitmap(8, 8, 1, 1,&hatchPattern);
            
            // create black hatched brush
            _afxHatchBrush = CreatePatternBrush(hatchBitmap);
            DeleteObject(hatchBitmap);
        }
        
        if (_afxBlackDottedPen == NULL)
        {
            // create black dotted pen
            _afxBlackDottedPen = CreatePen(PS_DOT, 0, RGB(0, 0, 0));
        }
        
        // get default handle size from Windows profile setting
        static const TCHAR szWindows[] = TEXT("windows");
        static const TCHAR szInplaceBorderWidth[] =
            TEXT("oleinplaceborderwidth");
        _afxHandleSize = GetProfileInt(szWindows, szInplaceBorderWidth, 4);
        bInitialized = TRUE;
        
        _afxCursors[0] = _afxCursors[2] = LoadCursor(0,IDC_SIZENWSE);
        _afxCursors[4] = _afxCursors[6] = LoadCursor(0,IDC_SIZENS);
        _afxCursors[1] = _afxCursors[3] = LoadCursor(0,IDC_SIZENESW);
        _afxCursors[5] = _afxCursors[7] = LoadCursor(0,IDC_SIZEWE);
        _afxCursors[8] = LoadCursor(0,IDC_SIZEALL);
    }
    
    m_nStyle = 0;
    m_nHandleSize = _afxHandleSize;
    m_sizeMin.cy = m_sizeMin.cx = m_nHandleSize*2;
    
    SetRectEmpty(&m_rectLast);
    m_sizeLast.cx = m_sizeLast.cy = 0;
    m_bErase = FALSE;
    m_bFinalErase =  FALSE;
}

Tracker::~Tracker()
{
}


int Tracker::HitTest(POINT point) const
{
    TrackerHit hitResult = hitNothing;
    
    RECT rectTrue;
    GetTrueRect(&rectTrue);
    NormalizeRect(&rectTrue);
    if (PtInRect(&rectTrue,point))
    {
        if ((m_nStyle & (resizeInside|resizeOutside)) != 0)
            hitResult = (TrackerHit)HitTestHandles(point);
        else
            hitResult = hitMiddle;
    }
    return hitResult;
}


BOOL Tracker::SetCursor(HWND pWnd, UINT nHitTest) const
{
    // trackers should only be in client area
    if (nHitTest != HTCLIENT)
        return FALSE;
    
    // convert cursor position to client co-ordinates
    POINT point;
    GetCursorPos(&point);
    ScreenToClient(pWnd,&point);
    
    // do hittest and normalize hit
    int nHandle = HitTestHandles(point);
    if (nHandle < 0)
        return FALSE;
    
    // need to normalize the hittest such that we get proper cursors
    nHandle = NormalizeHit(nHandle);
    
    // handle special case of hitting area between handles
    //  (logically the same -- handled as a move -- but different cursor)
    if (nHandle == hitMiddle && !PtInRect(&m_rect,point))
    {
        // only for trackers with hatchedBorder (ie. in-place resizing)
        if (m_nStyle & hatchedBorder)
            nHandle = (TrackerHit)9;
    }
    
    ::SetCursor(_afxCursors[nHandle]);	
    return TRUE;
}



BOOL Tracker::Track(HWND hWnd,POINT point,BOOL bAllowInvert,
                    HWND hWndClipTo)
{
    // perform hit testing on the handles
    int nHandle = HitTestHandles(point);
    if (nHandle < 0)
    {
        // didn't hit a handle, so just return FALSE
        return FALSE;
    }
    
    // otherwise, call helper function to do the tracking
    m_bAllowInvert = bAllowInvert;
    SetCursor(hWnd,nHandle);
    return TrackHandle(nHandle, hWnd, point, hWndClipTo);
}


BOOL Tracker::TrackHandle(int nHandle,HWND hWnd,POINT point,HWND hWndClipTo)
{
    // don't handle if capture already set
    if (GetCapture() != NULL)
        return FALSE;
    
    // save original width & height in pixels
    int nWidth = m_rect.right - m_rect.left;
    int nHeight = m_rect.bottom - m_rect.top;
    
    // set capture to the window which received this message
    SetCapture(hWnd);
    UpdateWindow(hWnd);
    if (hWndClipTo != NULL)
        UpdateWindow(hWndClipTo);
    RECT rectSave = m_rect;
    
	// find out what x/y coords we are supposed to modify
    int *px, *py;
    int xDiff, yDiff;
    GetModifyPointers(nHandle, &px, &py, &xDiff, &yDiff);
    xDiff = point.x - xDiff;
    yDiff = point.y - yDiff;
    
    // get DC for drawing
    HDC hDrawDC;
    if (hWndClipTo != NULL)
    {
        // clip to arbitrary window by using adjusted Window DC
        hDrawDC = GetDCEx(hWndClipTo,NULL, DCX_CACHE);
    }
    else
    {
        // otherwise, just use normal DC
        hDrawDC = GetDC(hWnd);
    }
    
    RECT rectOld;
    BOOL bMoved = FALSE;
    
    // get messages until capture lost or cancelled/accepted
    for (;;)
    {
        MSG msg;
        GetMessage(&msg, NULL, 0, 0);
        
        if (GetCapture() != hWnd)
            break;
        
        switch (msg.message)
        {
            // handle movement/accept messages
        case WM_LBUTTONUP:
        case WM_MOUSEMOVE:
            rectOld = m_rect;
            // handle resize cases (and part of move)
            if (px != NULL)
                *px = (int)(short)LOWORD(msg.lParam) - xDiff;
            if (py != NULL)
                *py = (int)(short)HIWORD(msg.lParam) - yDiff;
            
            // handle move case
            if (nHandle == hitMiddle)
            {
                m_rect.right = m_rect.left + nWidth;
                m_rect.bottom = m_rect.top + nHeight;
            }
            // allow caller to adjust the rectangle if necessary
            AdjustRect(nHandle,&m_rect);
            
            // only redraw and callback if the rect actually changed!
            m_bFinalErase = (msg.message == WM_LBUTTONUP);
            if (!EqualRect(&rectOld,&m_rect) || m_bFinalErase)
            {
                if (bMoved)
                {
                    m_bErase = TRUE;
                    DrawTrackerRect(&rectOld,hWndClipTo,hDrawDC,hWnd);
                }
                OnChangedRect(rectOld);
                if (msg.message != WM_LBUTTONUP)
                    bMoved = TRUE;
            }
            if (m_bFinalErase)
                goto ExitLoop;
            
            if (!EqualRect(&rectOld,&m_rect))
            {
                m_bErase = FALSE;
                DrawTrackerRect(&m_rect,hWndClipTo,hDrawDC,hWnd);
            }
            break;
            
            // handle cancel messages
        case WM_KEYDOWN:
            if (msg.wParam != VK_ESCAPE)
                break;
        case WM_RBUTTONDOWN:
            if (bMoved)
            {
                m_bErase = m_bFinalErase = TRUE;
                DrawTrackerRect(&m_rect, hWndClipTo, hDrawDC, hWnd);
            }
            m_rect = rectSave;
            goto ExitLoop;
            
            // just dispatch rest of the messages
        default:
            DispatchMessage(&msg);
            break;
        }
    }
    
  ExitLoop:
    if (hWndClipTo != NULL)
        ReleaseDC(hWndClipTo,hDrawDC);
    else
        ReleaseDC(hWnd,hDrawDC);
    ReleaseCapture();
    
    // restore rect in case bMoved is still FALSE
    if (!bMoved)
        m_rect = rectSave;
    m_bFinalErase = FALSE;
    m_bErase = FALSE;
    
    // return TRUE only if rect has changed
    return !EqualRect(&rectSave,&m_rect);
}


void Tracker::OnChangedRect(const RECT& /*rectOld*/)
{    
}


void Tracker::AdjustRect(int nHandle, LPRECT)
{
    if(nHandle == hitMiddle)
        return;
    
    // convert the handle into locations within m_rect
    int *px, *py;
    GetModifyPointers(nHandle, &px, &py, NULL, NULL);
    
    // enforce minimum width
    int nNewWidth = m_rect.right - m_rect.left;
    int nAbsWidth = m_bAllowInvert ? abs(nNewWidth) : nNewWidth;
    if (px != NULL && nAbsWidth < m_sizeMin.cx)
    {
        nNewWidth = nAbsWidth != 0 ? nNewWidth / nAbsWidth : 1;
        const AFX_RECTINFO* pRectInfo =
            &_afxRectInfo[(int*)px - (int*)&m_rect];
        *px = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) +
            nNewWidth * m_sizeMin.cx * -pRectInfo->nSignAcross;
    }
    
    // enforce minimum height
    int nNewHeight = m_rect.bottom - m_rect.top;
    int nAbsHeight = m_bAllowInvert ? abs(nNewHeight) : nNewHeight;
    if (py != NULL && nAbsHeight < m_sizeMin.cy)
    {
        nNewHeight = nAbsHeight != 0 ? nNewHeight / nAbsHeight : 1;
        const AFX_RECTINFO* pRectInfo =
            &_afxRectInfo[(int*)py - (int*)&m_rect];
        *py = *(int*)((BYTE*)&m_rect + pRectInfo->nOffsetAcross) +
            nNewHeight * m_sizeMin.cy * -pRectInfo->nSignAcross;
    }
}


void Tracker::DrawTrackerRect(
    LPRECT lpRect,HWND pWndClipTo,HDC pDC,HWND pWnd)
{
    // first, normalize the rectangle for drawing
    RECT rect = *lpRect;
    NormalizeRect(&rect);
    
    // convert to client coordinates
    if (pWndClipTo != NULL)
        TransformRect(&rect,pWnd,pWndClipTo);
    
    SIZE size;
    size.cx = 0; size.cy = 0;
    if (!m_bFinalErase)
    {
        // otherwise, size depends on the style
        if (m_nStyle & hatchedBorder)
        {
            size.cx = size.cy = max(1,GetHandleSize(&rect)-1);
            InflateRect(&rect,size.cx,size.cy);
        }
        else
        {
            size.cx = 1; // CX_BORDER;
            size.cy = 1; // CY_BORDER;
        }
    }
    
    // and draw it
    if (m_bFinalErase || !m_bErase)        
        DrawDragRect(pDC,&rect,size,&m_rectLast,m_sizeLast);
    
    // remember last rectangles
    m_rectLast = rect;
    m_sizeLast = size;
}


void Tracker::Draw(HDC hDC) const
{
    // set initial DC state
    SetMapMode(hDC,MM_TEXT);
    SetViewportOrgEx(hDC,0, 0,NULL);
    SetWindowOrgEx(hDC,0, 0,NULL);
    
    // get normalized rectangle
    RECT rect = m_rect;
    NormalizeRect(&rect);
    
    HPEN pOldPen = NULL;
    HBRUSH pOldBrush = NULL;
    HGDIOBJ pTemp;
    int nOldROP;
    
    // draw lines
    if ((m_nStyle & (dottedLine|solidLine)) != 0)
    {
        if (m_nStyle & dottedLine)
            pOldPen = (HPEN)SelectObject(hDC,_afxBlackDottedPen);
        else
            pOldPen = (HPEN)SelectObject(hDC,(HGDIOBJ)BLACK_PEN);
        pOldBrush = (HBRUSH)SelectObject(hDC,(HGDIOBJ)NULL_BRUSH);
        nOldROP = SetROP2(hDC,R2_COPYPEN);
        InflateRect(&rect,+1, +1);   // borders are one pixel outside
        Rectangle(hDC,rect.left, rect.top, rect.right, rect.bottom);
        SetROP2(hDC,nOldROP);
    }
    
    // if hatchBrush is going to be used, need to unrealize it
    if ((m_nStyle & (hatchInside|hatchedBorder)) != 0)
        UnrealizeObject((HGDIOBJ)_afxHatchBrush);
    
    // hatch inside
    if ((m_nStyle & hatchInside) != 0)
    {
        pTemp = SelectObject(hDC,(HGDIOBJ)NULL_PEN);
        if (pOldPen == NULL)
            pOldPen = (HPEN)pTemp;
        pTemp = SelectObject(hDC,(HGDIOBJ)_afxHatchBrush);
        if (pOldBrush == NULL)
            pOldBrush = (HBRUSH)pTemp;
        SetBkMode(hDC,TRANSPARENT);
        nOldROP = SetROP2(hDC,R2_MASKNOTPEN);
        Rectangle(hDC,rect.left+1, rect.top+1, rect.right, rect.bottom);
        SetROP2(hDC,nOldROP);
    }
    
    // draw hatched border
    if ((m_nStyle & hatchedBorder) != 0)
    {
        pTemp = SelectObject(hDC,(HGDIOBJ)_afxHatchBrush);
        if (pOldBrush == NULL)
            pOldBrush = (HBRUSH)pTemp;
        SetBkMode(hDC,OPAQUE);
        RECT rectTrue;
        GetTrueRect(&rectTrue);
        PatBlt(hDC,rectTrue.left, rectTrue.top, rectTrue.right-rectTrue.left,
               rect.top-rectTrue.top, 0x000F0001 /* Pn */);
        PatBlt(hDC,rectTrue.left, rect.bottom,
               rectTrue.right-rectTrue.left,
               rectTrue.bottom-rect.bottom, 0x000F0001 /* Pn */);
        PatBlt(hDC,rectTrue.left, rect.top, rect.left-rectTrue.left,
               rect.bottom-rect.top, 0x000F0001 /* Pn */);
        PatBlt(hDC,rect.right, rect.top, rectTrue.right-rect.right,
               rect.bottom-rect.top, 0x000F0001 /* Pn */);
    }
    
    // draw resize handles
    if ((m_nStyle & (resizeInside|resizeOutside)) != 0)
    {
        UINT mask = GetHandleMask();
        HBRUSH hbrush = CreateSolidBrush(RGB(0,0,0));
        for (int i = 0; i < 8; ++i)
        {
            if (mask & (1<<i))
            {
                GetHandleRect((TrackerHit)i, &rect);
                // FillSolidRect(hDC,rect, RGB(0, 0, 0));
                FillRect(hDC,&rect,hbrush);
            }
        }
        DeleteObject(hbrush);
    }
    
    // cleanup pDC state
    if (pOldPen != NULL)
        SelectObject(hDC,pOldPen);
    if (pOldBrush != NULL)
        SelectObject(hDC,pOldBrush);
    RestoreDC(hDC,-1);
}


void Tracker::GetHandleRect(int nHandle,RECT* pHandleRect) const
{
    // get normalized rectangle of the tracker
    RECT rectT = m_rect;
    NormalizeRect(&rectT);
    if ((m_nStyle & (solidLine|dottedLine)) != 0)
        InflateRect(&rectT,+1, +1);
    
    // since the rectangle itself was normalized, we also have to invert the
    //  resize handles.
    nHandle = NormalizeHit(nHandle);
    
    // handle case of resize handles outside the tracker
    int size = GetHandleSize();
    if (m_nStyle & resizeOutside)
        InflateRect(&rectT,size-1, size-1);
    
    // calculate position of the resize handle
    int nWidth = rectT.right - rectT.left;
    int nHeight = rectT.bottom - rectT.top;
    RECT rect;
    const AFX_HANDLEINFO* pHandleInfo = &_afxHandleInfo[nHandle];
    rect.left = *(int*)((BYTE*)&rectT + pHandleInfo->nOffsetX);
    rect.top = *(int*)((BYTE*)&rectT + pHandleInfo->nOffsetY);
    rect.left += size * pHandleInfo->nHandleX;
    rect.top += size * pHandleInfo->nHandleY;
    rect.left += pHandleInfo->nCenterX * (nWidth - size) / 2;
    rect.top += pHandleInfo->nCenterY * (nHeight - size) / 2;
    rect.right = rect.left + size;
    rect.bottom = rect.top + size;
    
    *pHandleRect = rect;
}


int Tracker::GetHandleSize(LPRECT lpRect) const
{
    if (lpRect == NULL)
        lpRect = (LPRECT)&m_rect;
    
    int size = m_nHandleSize;
    if (!(m_nStyle & resizeOutside))
    {
        // make sure size is small enough for the size of the rect
        int sizeMax = min(abs(lpRect->right - lpRect->left),
                          abs(lpRect->bottom - lpRect->top));
        if (size * 2 > sizeMax)
            size = sizeMax / 2;
    }
    return size;
}


UINT Tracker::GetHandleMask() const
{
    UINT mask = 0x0F;   // always have 4 corner handles
    int size = m_nHandleSize*3;
    if (abs(m_rect.right - m_rect.left) - size > 4)
        mask |= 0x50;
    if (abs(m_rect.bottom - m_rect.top) - size > 4)
        mask |= 0xA0;
    return mask;
}


void Tracker::GetTrueRect(LPRECT lpTrueRect) const
{
    RECT rect = m_rect;
    NormalizeRect(&rect);
    int nInflateBy = 0;
    if ((m_nStyle & (resizeOutside|hatchedBorder)) != 0)
        nInflateBy += GetHandleSize() - 1;
    if ((m_nStyle & (solidLine|dottedLine)) != 0)
        ++nInflateBy;
    InflateRect(&rect,nInflateBy, nInflateBy);
    *lpTrueRect = rect;
}


int Tracker::NormalizeHit(int nHandle) const
{
    if (nHandle == hitMiddle || nHandle == hitNothing)
        return nHandle;
    const AFX_HANDLEINFO* pHandleInfo = &_afxHandleInfo[nHandle];
    if (m_rect.right - m_rect.left < 0)
    {
        nHandle = (TrackerHit)pHandleInfo->nInvertX;
        pHandleInfo = &_afxHandleInfo[nHandle];
    }
    if (m_rect.bottom - m_rect.top < 0)
        nHandle = (TrackerHit)pHandleInfo->nInvertY;
    return nHandle;
}


int Tracker::HitTestHandles(POINT point) const
{
    RECT rect;
    UINT mask = GetHandleMask();
    
    // see if hit anywhere inside the tracker
    GetTrueRect(&rect);
    if (!PtInRect(&rect,point))
        return hitNothing;  // totally missed
    
    // see if we hit a handle
    for (int i = 0; i < 8; ++i)
    {
        if (mask & (1<<i))
        {
            GetHandleRect((TrackerHit)i, &rect);
            if (PtInRect(&rect,point))
                return (TrackerHit)i;
        }
    }
    
    // last of all, check for non-hit outside of object, between resize handles
    if ((m_nStyle & hatchedBorder) == 0)
    {
        RECT rect = m_rect;
        NormalizeRect(&rect);
        if ((m_nStyle & dottedLine|solidLine) != 0)
            InflateRect(&rect,+1, +1);
        if (!PtInRect(&rect,point))
            return hitNothing;  // must have been between resize handles
    }
    return hitMiddle;   // no handle hit, but hit object (or object border)
}



void Tracker::GetModifyPointers(
    int nHandle, int** ppx, int** ppy, int* px, int* py)
{
    if (nHandle == hitMiddle)
        nHandle = hitTopLeft;   // same as hitting top-left
    
    *ppx = NULL;
    *ppy = NULL;
    
    // fill in the part of the rect that this handle modifies
    //  (Note: handles that map to themselves along a given axis when that
    //   axis is inverted don't modify the value on that axis)
    
    const AFX_HANDLEINFO* pHandleInfo = &_afxHandleInfo[nHandle];
    if (pHandleInfo->nInvertX != nHandle)
    {
        *ppx = (int*)((BYTE*)&m_rect + pHandleInfo->nOffsetX);
        if (px != NULL)
            *px = **ppx;
    }
    else
    {
        // middle handle on X axis
        if (px != NULL)
            *px = m_rect.left + (m_rect.left-m_rect.right) / 2;
    }
    if (pHandleInfo->nInvertY != nHandle)
    {
        *ppy = (int*)((BYTE*)&m_rect + pHandleInfo->nOffsetY);
        if (py != NULL)
            *py = **ppy;
    }
    else
    {
        // middle handle on Y axis
        if (py != NULL)
            *py = m_rect.top + (m_rect.top-m_rect.bottom) / 2;
    }
}

// Fix strange warnings about some 
// ATL::CAxHostWindow::QueryInterface|AddRef|Releae functions.
// warning C4505: 'xxx' : unreferenced local function has been removed
#if defined(_MSC_VER)
#pragma warning(disable: 4505)
#endif
