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

#include "stdafx.h"
#include "ConGraT.h"
#include "DrawableRH.h"

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

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

CDrawableRH::CDrawableRH()
{

}

CDrawableRH::~CDrawableRH()
{

}

long CDrawableRH::Draw()
{
    RelationDefMap::iterator iterRH;
    CDrawable *pDrawable;
    CRelationDefinition *pRelationDefinition, *pSubRelation;
    const CRelationDefinition::RelationDefVector *pSubClassList;
    CRelationDefinition::RelationDefVector::const_iterator iterSubClassList;
    CDrawableArc oDrawableArc;
    CDrawableElement *pDrawableElement;
    bool bFirst = true;
	
    for(iterRH = m_mapRelation.begin();iterRH != m_mapRelation.end();iterRH++)
    {
		pDrawable = dynamic_cast<CDrawable*>((*iterRH).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(iterRH = m_mapRelation.begin();iterRH != m_mapRelation.end();iterRH++)
    {
        pRelationDefinition = dynamic_cast<CRelationDefinition*>((*iterRH).second);
        if(!pRelationDefinition)
        {
            ASSERT(0);
            continue;
        }
        pSubClassList = pRelationDefinition->GetSubclassVector();
        for(iterSubClassList = pSubClassList->begin(); iterSubClassList != pSubClassList->end();iterSubClassList++)
        {
            pSubRelation = dynamic_cast<CRelationDefinition*>(*iterSubClassList);
            if(!pSubRelation)
            {
                ASSERT(0);
                continue;
            }

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

            oDrawableArc.Draw();
        }
    }

    return CG_S_OK;

}

std::vector<CDrawableElement*> CDrawableRH::ObjectsAt(int nXCoor, int nYCoor)
{
    RelationDefMap::iterator iterRH;
    CDrawableElement* pDrawableElement;
    std::vector<CDrawableElement*> vHitList;
    int nRC;

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

	return vHitList;
}
