/******************************************************************************
** Copyright (C) 2001, University of Alabama in Huntsville. All rights 
** reserved.
**
** File   : DrawableTH.cpp
**
** Author : Satish Hota
**
** Description:
**    This file provides implementation for CDrawableTH class.
**
** History:
** 28-Nov-01 Satish Hota
**     File Created. 
** 28-Nov-01 Satish Hota
**    Added Draw method.
** 30-Nov-01 Satish Hota
**    Modified the Draw method.  Added and implemented the ObjectsAt method.
******************************************************************************/

#include "stdafx.h"
#include "ConGraT.h"
#include "DrawableTH.h"

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

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

CDrawableTH::CDrawableTH()
{

}

CDrawableTH::~CDrawableTH()
{

}

long CDrawableTH::Draw()
{
    TypeDefMap::iterator iterTH;
    CDrawable *pDrawable;
    CTypeDefinition *pTypeDefinition, *pSubType;
    const CTypeDefinition::TypeDefVector *pSubClassList;
    CTypeDefinition::TypeDefVector::const_iterator iterSubClassList;
    CDrawableArc oDrawableArc;
    CDrawableElement *pDrawableElement;
    bool bFirst = true;
	
    for(iterTH = m_mapType.begin();iterTH != m_mapType.end();iterTH++)
    {
		pDrawable = dynamic_cast<CDrawable*>((*iterTH).second);
        if(pDrawable)
        {
            pDrawable->Draw();
            if(bFirst)
            {
                pDrawable->GetFromLocation(&m_nFromX, &m_nFromY);
                pDrawable->GetToLocation(&m_nToX, &m_nToY);
                bFirst = false;
            }
            else
            {
                CRect curRect(m_nFromX, m_nFromY, m_nToX, m_nToY);
                int x1, y1, x2, y2;
                pDrawable->GetFromLocation(&x1, &y1);
                pDrawable->GetToLocation(&x2, &y2);
                CRect newRect(x1, y1, x2, y2);
                curRect.UnionRect(curRect, newRect);
                m_nFromX = curRect.left;
                m_nFromY = curRect.top;
                m_nToX = curRect.right;
                m_nToY = curRect.bottom;
            }
        }
        else
        {
            ASSERT(0);
        }
    }

    oDrawableArc.SetLineEndType(CDrawableLine::LineEndType_StartArrow);

    for(iterTH = m_mapType.begin();iterTH != m_mapType.end();iterTH++)
    {
        pTypeDefinition = dynamic_cast<CTypeDefinition*>((*iterTH).second);
        if(!pTypeDefinition)
        {
            ASSERT(0);
            continue;
        }
		pSubClassList = pTypeDefinition->GetSubclassVector();
        for(iterSubClassList = pSubClassList->begin(); iterSubClassList != pSubClassList->end();iterSubClassList++)
        {
            pSubType = dynamic_cast<CTypeDefinition*>(*iterSubClassList);
            if(!pSubType)
            {
                ASSERT(0);
                continue;
            }

            if(pSubType->IsPrimitive())
			{
				oDrawableArc.SetLineType(CDrawableLine::LineType_Dashed);
			}
			else
			{
				oDrawableArc.SetLineType(CDrawableLine::LineType_Solid);
			}
            pDrawableElement = dynamic_cast<CDrawableElement*>(pTypeDefinition);
            oDrawableArc.SetFromObject(pDrawableElement);
            pDrawableElement = dynamic_cast<CDrawableElement*>(pSubType);
            oDrawableArc.SetToObject(pDrawableElement);

            oDrawableArc.Draw();
        }
    }

    return CG_S_OK;

}

std::vector<CDrawableElement*> CDrawableTH::ObjectsAt(int nXCoor, int nYCoor)
{
    TypeDefMap::iterator iterTH;
    CDrawableElement* pDrawableElement;
    std::vector<CDrawableElement*> vHitList;
    int nRC;

    for(iterTH = m_mapType.begin();iterTH != m_mapType.end();iterTH++)
    {
		pDrawableElement = dynamic_cast<CDrawableElement*>((*iterTH).second);
        if(pDrawableElement)
        {
            nRC = pDrawableElement->HitTest(nXCoor, nYCoor);
            if(nRC == CDrawableElement::RC_S_HitSucess)
            {
                vHitList.push_back(pDrawableElement);
            }
        }
        else
        {
            ASSERT(0);
        }
    }

    return vHitList;

}
