// ResizableSplitterWnd.cpp : implementation file
//
/////////////////////////////////////////////////////////////////////////////
//
// This file is part of ResizableLib
// http://sourceforge.net/projects/resizablelib
//
// Copyright (C) 2000-2004 by Paolo Messina
// http://www.geocities.com/ppescher - mailto:ppescher@hotmail.com
//
// The contents of this file are subject to the Artistic License (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.opensource.org/licenses/artistic-license.html
//
// If you find this code useful, credits would be nice!
//
/////////////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ResizableSplitterWnd.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CResizableSplitterWnd

IMPLEMENT_DYNAMIC(CResizableSplitterWnd, CSplitterWnd)

CResizableSplitterWnd::CResizableSplitterWnd()
{
}

CResizableSplitterWnd::~CResizableSplitterWnd()
{
}

BEGIN_MESSAGE_MAP(CResizableSplitterWnd, CSplitterWnd)
    //{{AFX_MSG_MAP(CResizableSplitterWnd)
    ON_WM_GETMINMAXINFO()
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CResizableSplitterWnd message handlers

void CResizableSplitterWnd::OnGetMinMaxInfo(MINMAXINFO FAR* lpMMI)
{
    if ((GetStyle() & SPLS_DYNAMIC_SPLIT) &&
        GetRowCount() == 1 && GetColumnCount() == 1)
    {
        CWnd* pPane = GetActivePane();
        if (pPane != NULL)
        {
            // get the extra size from child to parent
            CRect rectClient, rectWnd;
            GetWindowRect(rectWnd);
            pPane->GetWindowRect(rectClient);
            CSize sizeExtra = rectWnd.Size() - rectClient.Size();

            ChainMinMaxInfo(lpMMI, pPane->m_hWnd, sizeExtra);
        }
    }
    else if (!(GetStyle() & SPLS_DYNAMIC_SPLIT))
    {
        ASSERT(m_nCols > 0 && m_nRows > 0);

        CSize sizeMin(0,0), sizeMax(0,0);
        for (int col = 0; col < m_nCols; ++col)
        {
            // calc min and max width for each column
            int min = 0;
            int max = LONG_MAX;
            for (int row = 0; row < m_nRows; ++row)
            {
                CWnd* pWnd = GetPane(row, col);
                // ask the child window for track size
                MINMAXINFO mmiChild = *lpMMI;
                mmiChild.ptMinTrackSize.x = 0;
                mmiChild.ptMaxTrackSize.x = LONG_MAX;
                ::SendMessage(pWnd->GetSafeHwnd(), WM_GETMINMAXINFO, 0, (LPARAM)&mmiChild);
                max = __min(max, mmiChild.ptMaxTrackSize.x);
                min = __max(min, mmiChild.ptMinTrackSize.x);
            }
            // sum all column widths
            if (sizeMax.cx == LONG_MAX || max == LONG_MAX)
                sizeMax.cx = LONG_MAX;
            else
                sizeMax.cx += max + m_cxSplitterGap;
            sizeMin.cx += min + m_cxSplitterGap;
        }
        for (int row = 0; row < m_nRows; ++row)
        {
            // calc min and max height for each row
            int min = 0;
            int max = LONG_MAX;
            for (int col = 0; col < m_nCols; ++col)
            {
                CWnd* pWnd = GetPane(row, col);
                // ask the child window for track size
                MINMAXINFO mmiChild = *lpMMI;
                mmiChild.ptMinTrackSize.y = 0;
                mmiChild.ptMaxTrackSize.y = LONG_MAX;
                ::SendMessage(pWnd->GetSafeHwnd(), WM_GETMINMAXINFO, 0, (LPARAM)&mmiChild);
                max = __min(max, mmiChild.ptMaxTrackSize.y);
                min = __max(min, mmiChild.ptMinTrackSize.y);
            }
            // sum all row heights
            if (sizeMax.cy == LONG_MAX || max == LONG_MAX)
                sizeMax.cy = LONG_MAX;
            else
                sizeMax.cy += max + m_cySplitterGap;
            sizeMin.cy += min + m_cySplitterGap;
        }
        // adjust total size: add the client border and
        // we counted one splitter more than necessary
        sizeMax.cx += 2*m_cxBorder - m_cxSplitterGap;
        sizeMax.cy += 2*m_cyBorder - m_cySplitterGap;
        sizeMin.cx += 2*m_cxBorder - m_cxSplitterGap;
        sizeMin.cy += 2*m_cyBorder - m_cySplitterGap;
        // add non-client size
        CRect rectExtra(0,0,0,0);
        ::AdjustWindowRectEx(&rectExtra, GetStyle(), !(GetStyle() & WS_CHILD) &&
            ::IsMenu(GetMenu()->GetSafeHmenu()), GetExStyle());
        sizeMax += rectExtra.Size();
        sizeMin += rectExtra.Size();
        // set minmax info
        lpMMI->ptMinTrackSize.x = __max(lpMMI->ptMinTrackSize.x, sizeMin.cx);
        lpMMI->ptMinTrackSize.y = __max(lpMMI->ptMinTrackSize.y, sizeMin.cy);
        lpMMI->ptMaxTrackSize.x = __min(lpMMI->ptMaxTrackSize.x, sizeMax.cx);
        lpMMI->ptMaxTrackSize.y = __min(lpMMI->ptMaxTrackSize.y, sizeMax.cy);
    }
}
