// DUiWindow.cpp: implementation of the CDUiWindow class.
//
//////////////////////////////////////////////////////////////////////

#include "DUiMan.h"
#include "DirectXHelpers.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CDUiWindow::CDUiWindow()
{
    SetObjectType(DUI_WINDOW);

//    m_pWindowList = new CDUiObjectList();
//    m_pEditBoxList = new CDUiObjectList();
//    m_pListBoxList = new CDUiObjectList();
    m_pObjectList = new CDUiObjectList();
    m_dwNextTabOrder = 1;
    m_pSelectedObject = NULL;
}

CDUiWindow::~CDUiWindow()
{
//    delete m_pWindowList;
//    delete m_pEditBoxList;
//    delete m_pListBoxList;
    delete m_pObjectList;
}

DWORD CDUiWindow::Display(BOOL bRefresh)
{
    HRESULT     hr;
    DWORD       dwRetVal = 0;
    DDBLTFX     ddbltfx;
    RECT        rSource;
    RECT        rTemp;
    BOOL        bIsSelected = FALSE;
    CDUiObjectList *pList;

    if (!m_bVisible)
        return dwRetVal;

    rSource.left = m_xPos;
    rSource.top = m_yPos;
    rSource.right = m_xPos + m_dwWidth;
    rSource.bottom = m_yPos + m_dwHeight;

    memset(&ddbltfx,0,sizeof(DDBLTFX));
    ddbltfx.dwSize = sizeof(DDBLTFX);
    ddbltfx.dwFillColor = m_dwBackgroundColor;
    hr = m_pddsMain->Blt(&rSource, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);

    CDUiObject *pTemp;

    //check to see if this window is part of the focus path
    //if its the root window it must be part of the focus path
    if (!m_pParent || ((m_pParent->GetObjectType() == DUI_WINDOW) &&
        (((CDUiWindow *)m_pParent)->GetSelectedObject() == this)))
    {
        bIsSelected = TRUE;
    }

    pList = m_pObjectList;
    pList->Reset();
    while (pTemp = pList->GetNextObject())
    {
        if (pTemp->GetVisible())
        {
            if (bIsSelected && (pTemp == m_pSelectedObject) && 
                (pTemp->GetObjectType() != DUI_WINDOW) &&
                pTemp->GetTabOrder())
            {
                //draw the outline around the box
                GetOutlineRect(pTemp,&rTemp);
                ddbltfx.dwFillColor = pTemp->GetSelectOutlineColor();
                hr = m_pddsMain->Blt(&rTemp, NULL, NULL, DDBLT_COLORFILL | DDBLT_WAIT, &ddbltfx);
            }
            pTemp->Display();
        }
    }

    return dwRetVal;
}

DWORD CDUiWindow::DisplayText(BOOL bRefresh)
{
    DWORD dwRetVal = 0;
    CDUiObject *pTemp;

    m_pObjectList->Reset();
    while (pTemp = m_pObjectList->GetNextObject())
    {
        pTemp->DisplayText();
    }

    return dwRetVal;
}

CDUiObject *CDUiWindow::CreateDUiObject(DWORD dwObjectType, WCHAR *wszWindowName, 
            DWORD x, DWORD y, DWORD dwWidth, DWORD dwHeight, DWORD dwStyle)
{
    CDUiObject *pTemp = NULL;
    CDUiListBox *pListBox;
    CDUiEditBox *pEditBox;
    CDUiButton *pButton;
    CDUiGraphic *pGraphic;
    CDUiWindow *pWindow;
    CDUiText *pText;

    switch (dwObjectType)
    {
    case DUI_WINDOW:
        pWindow = new CDUiWindow();
        pTemp = pWindow;
        pTemp->SetTabOrder(0);
        break;
    case DUI_LISTBOX:
        pListBox = new CDUiListBox();
        pListBox->SetDUiFont(g_pDUiManager->GetDefaultFont());
        pListBox->SetFontColor(g_pDUiManager->GetDefaultFontColor());
        pListBox->SetSelectedFontColor(g_pDUiManager->GetDefaultSelectedFontColor());
        pTemp = pListBox;
        pTemp->SetTabOrder(m_dwNextTabOrder++);
        break;
    case DUI_EDITBOX:
        pEditBox = new CDUiEditBox();
        pEditBox->SetDUiFont(g_pDUiManager->GetDefaultFont());
        pEditBox->SetFontColor(g_pDUiManager->GetDefaultFontColor());
        pEditBox->SetSelectedFontColor(g_pDUiManager->GetDefaultSelectedFontColor());
        pTemp = pEditBox;
        pTemp->SetTabOrder(m_dwNextTabOrder++);
        break;
    case DUI_GRAPHIC:
        pGraphic = new CDUiGraphic();
        pGraphic->SetDirectDraw(g_pDUiManager->GetDirectDraw());
        pTemp = pGraphic;
        break;
    case DUI_BUTTON:
        pButton = new CDUiButton();
        pButton->SetDUiFont(g_pDUiManager->GetDefaultFont());
        pButton->SetFontColor(g_pDUiManager->GetDefaultFontColor());
        pButton->SetSelectedFontColor(g_pDUiManager->GetDefaultSelectedFontColor());
        pButton->SetTabOrder(m_dwNextTabOrder++);
        pTemp = pButton;
        break;
    case DUI_TEXT:
        pText = new CDUiText();
        pText->SetDUiFont(g_pDUiManager->GetDefaultFont());
        pText->SetFontColor(g_pDUiManager->GetDefaultFontColor());
        pText->SetSelectedFontColor(g_pDUiManager->GetDefaultSelectedFontColor());
        pTemp = pText;
        break;
    }

    if (pTemp)
    {
        pTemp->SetXPosition(x);
        pTemp->SetYPosition(y);
        pTemp->SetHeight(dwHeight);
        pTemp->SetWidth(dwWidth);
        pTemp->SetName(wszWindowName);
        pTemp->m_pddsMain = m_pddsMain;
        pTemp->m_pParent = this;
        pTemp->SetStyle(dwStyle);
        pTemp->SetBackgroundColor(g_pDUiManager->GetDefaultBackgroundColor());
        pTemp->SetPrimaryColor(g_pDUiManager->GetDefaultPrimaryColor());
        pTemp->SetZOrder(g_pDUiManager->GetZOrderCounter());
        g_pDUiManager->SetZOrderCounter(g_pDUiManager->GetZOrderCounter()+1);
        pTemp->SetSelectOutlineColor(g_pDUiManager->GetDefaultSelectOutlineColor());

        m_pObjectList->AddObject(pTemp);
        if (!m_pSelectedObject)
            m_pSelectedObject = pTemp;
    }
    return pTemp;
}

BOOL CDUiWindow::GetNamedObject(WCHAR *wszName, CDUiObject **pObject)
{
    BOOL bRetVal = FALSE;
    CDUiObject *pTemp;
    WCHAR wszTemp[200];
    *pObject = NULL;
    m_pObjectList->Reset();
    while (pTemp = m_pObjectList->GetNextObject())
    {
        pTemp->GetName(wszTemp);
        if (wcscmp(wszTemp,wszName) == 0)
        {
            *pObject = pTemp;
            bRetVal = TRUE;
            break;
        }
    }
    return bRetVal;
}

DWORD CDUiWindow::OnKey(UINT nChar, UINT nFlags)
{
    switch (nChar)
    {
    case 0:
        break;
    default:
        //see what has focus if anythng
        if (m_pSelectedObject)
        {
            m_pSelectedObject->OnKey(nChar,nFlags);
        }
        break;
    }
    
    return 0;
}

DWORD CDUiWindow::OnChar(UINT nChar, UINT nFlags)
{
    switch (nChar)
    {
    case 0:
        break;
    default:
        //see what has focus if anythng
        if (m_pSelectedObject)
        {
            m_pSelectedObject->OnChar(nChar,nFlags);
        }
        break;
    }
    
    return 0;
}

DWORD CDUiWindow::DoFocusChange()
{
    DWORD dwRetVal = 0xFFFFFFFF;
    BOOL bFoundCurrentObject = FALSE;
    CDUiObject *pTemp;
    DWORD i,dwPos,dwCount;

    i = 0;
    if (m_pSelectedObject)
    {
        dwPos = m_pObjectList->FindObject(m_pSelectedObject);
        if (dwPos == 0xFFFFFFFF)
        {
            dwPos = 0;
        }
        else
        {
            i = 1;
        }
    }

    dwCount = m_pObjectList->GetObjectCount();
    for (; i <= dwCount; i++)
    {
        pTemp = m_pObjectList->GetObject((i+dwPos) % dwCount);
        //if we have another window we can pass focus control to
        //lets try to do that
        if (pTemp->GetObjectType() == DUI_WINDOW)
        {
            if (pTemp->DoFocusChange() == 0)
            {
                m_pSelectedObject = pTemp;
                dwRetVal = 0;
                break;
            }
        }
        else if (pTemp->GetTabOrder())
        {
            m_pSelectedObject = pTemp;
            dwRetVal = 0;
            break;
        }
    }
    if (dwRetVal != 0)
    {
        m_pSelectedObject = NULL;
    }
    return dwRetVal;
}
