/******************************************************************************
** Copyright (C) 2001, University of Alabama in Huntsville. All rights 
** reserved.
**
** File   : ConGraTDoc.cpp
**
** Author : Satish Hota & Edwin Chan (with help from MFC)
**
** Description:
**    This file provides implementation for CConGraTDoc class.
**
** History:
** 09-Nov-01 Satish Hota & Edwin Chan
**     File Created
** 24-Nov-01 Satish Hota
**     Added GetSize method
** 25-Nov-01 Satish Hota
**     * Added Draw method.
**     * Added temporary code in the constructor to add two drawable objects
**       to the m_pTempList vector.
**     * Added temporary code in the destructor to delete the drawable objects
**       created in the constructor.
** 26-Nov-01 Edwin Chan
**     Added new method ObjectAt
** 28-Nov-01 Satish Hota
**     Made the CDrawable class CDrawableElement and created a CDrawable
**     super-class.  Hence, replaced usage of CDrawable with CDrawableElement.
** 30-Nov-01 Satish Hota
**     Added a KnowledgeBase member and initializing it with a temporary 
**     driver in the constructor.  Modified the Draw method to draw from the
**     KB.  Modified the ObjectAt method to search for an object in the
**     appropriate piece of the KB.  Added GetFromLocation and GetToLocation
**     methods to get the location and size of the document.
** 01-Dec-01 Edwin Chan
**     Removed the hardcoded ViewType assignments
** 01-Dec-01 Saranyu Tantipongsakul, Satish Hota
**     Commented out temporary driver in constructor.  Calling the parser
**     in the OnOpenDocument method.
******************************************************************************/

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

#include "ConGraTDoc.h"

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

/////////////////////////////////////////////////////////////////////////////
// CConGraTDoc

IMPLEMENT_DYNCREATE(CConGraTDoc, CDocument)

BEGIN_MESSAGE_MAP(CConGraTDoc, CDocument)
	//{{AFX_MSG_MAP(CConGraTDoc)
		// NOTE - the ClassWizard will add and remove mapping macros here.
		//    DO NOT EDIT what you see in these blocks of generated code!
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CConGraTDoc construction/destruction

CConGraTDoc::CConGraTDoc()
{
	// TODO: add one-time construction code here
    m_pKnowledgeBase = NULL;

    /********************** Temporary code ****************************
    CDrawableRectangle *pTempRect = new CDrawableRectangle;
    CDrawableRoundedRectangle *pTempRoundRect = new CDrawableRoundedRectangle;
    CDrawableLine *pTempLine = new CDrawableLine;

    pTempRect->SetFromLocation(20, 20);
    pTempRect->SetToLocation(100,60);
    //pTempRect->Select();

    pTempRoundRect->SetFromLocation(40, 80);
    pTempRoundRect->SetToLocation(140, 100);
    pTempRoundRect->SetRoundness(20, 20);
    //pTempRoundRect->Select();

    pTempLine->SetFromLocation(150, 150);
    pTempLine->SetToLocation(200, 200);
    pTempLine->SetLineType(CDrawableLine::LineType_Dashed);
    pTempLine->SetLineEndType(CDrawableLine::LineEndType_ArrowsAtBothEnds);

    m_pTempObjList.push_back((CDrawableElement*)pTempRect);
    m_pTempObjList.push_back((CDrawableElement*)pTempRoundRect);
    m_pTempObjList.push_back((CDrawableElement*)pTempLine);

    CDrawableCGFactory oDrawableCGFactory;
    ACCGFactory *pFactory = dynamic_cast<ACCGFactory*> (&oDrawableCGFactory);
    TempDriver(pFactory, &m_pKnowledgeBase);
    ********************** Temporary code ****************************/
}

CConGraTDoc::~CConGraTDoc()
{
    if(m_pKnowledgeBase)
    {
        delete m_pKnowledgeBase;
    }

    /********************** Temporary code ****************************/
    for(int i=0;i<m_pTempObjList.size();i++)
    {
        delete m_pTempObjList[i];
    }
    /********************** Temporary code ****************************/
}

BOOL CConGraTDoc::OnNewDocument()
{
	if (!CDocument::OnNewDocument())
		return FALSE;

	// TODO: add reinitialization code here
	// (SDI documents will reuse this document)

	return TRUE;
}



/////////////////////////////////////////////////////////////////////////////
// CConGraTDoc serialization

void CConGraTDoc::Serialize(CArchive& ar)
{
	if (ar.IsStoring())
	{
		// TODO: add storing code here
	}
	else
	{
		// TODO: add loading code here
	}
}

/////////////////////////////////////////////////////////////////////////////
// CConGraTDoc diagnostics

#ifdef _DEBUG
void CConGraTDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CConGraTDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CConGraTDoc commands

BOOL CConGraTDoc::OnOpenDocument(LPCTSTR lpszPathName) 
{
    /*if (!CDocument::OnOpenDocument(lpszPathName))
        return FALSE;*/
    
    // TODO: Add your specialized creation code here

    // 9Nov01 : Satish & Edwin
    // Add the code to send this file to the parser here. We may have
    // to comment the previous line CDocument::OnOpenDocument

    //88hr = m_Parser.Parse(lpszPathName, m_CGEngine);

    //88if(hr == CParser::INVALID_FILE_FORMAT)
    
    CDrawableCGFactory oDrawableCGFactory;
    ACCGFactory *pFactory = dynamic_cast<ACCGFactory*> (&oDrawableCGFactory);
	CCGIFParser oParser;
	std::string strFileName;
	strFileName = lpszPathName;
	bool bRetCode;
	bRetCode = oParser.Parse(strFileName, pFactory, &m_pKnowledgeBase);

    return bRetCode;
}

BOOL CConGraTDoc::OnSaveDocument(LPCTSTR lpszPathName) 
{
	// TODO: Add your specialized code here and/or call the base class

	// 9Nov01 : Satish & Edwin
	// Add the code to send this file to the generator here.  We may
	// have to comment the next line CDocument::OnSaveDocument
	
	return CDocument::OnSaveDocument(lpszPathName);
}

CSize CConGraTDoc::GetSize()
{
    // Compute size and return it.
    return CSize(0,0);
}

long CConGraTDoc::Draw(CDC *pDC, CConGraTView *pView, ViewType eViewType)
{
    CMFCDevConHelper devConHelper((CView *)pView, pDC);

    CDrawableElement::SetDevConHelper(&devConHelper);

    /********************** Temporary code ***************************
    CDrawableElement *pDrawable;

    for(int i=0;i<m_pTempObjList.size();i++)
    {
        pDrawable = m_pTempObjList[i];
        pDrawable->Draw();
    }
    ********************* Temporary code ****************************/

    if(m_pKnowledgeBase)
    {
        CDrawable *pDrawable;
        if(eViewType == ViewType_SheetOfAssertion)
        {
            pDrawable = dynamic_cast<CDrawable*>(m_pKnowledgeBase->GetSOA());
        }
        else if(eViewType == ViewType_CatalogOfIndividuals)
        {
            pDrawable = dynamic_cast<CDrawable*>(m_pKnowledgeBase->GetCOI());
        }
        else if(eViewType == ViewType_RelationHierarchy)
        {
            pDrawable = dynamic_cast<CDrawable*>(m_pKnowledgeBase->GetRelations());
        }
        else if(eViewType == ViewType_TypeHierarchy)
        {
            pDrawable = dynamic_cast<CDrawable*>(m_pKnowledgeBase->GetTypes());
        }

        if(!pDrawable)
        {
            ASSERT(0);
        }
        else
        {
            pDrawable->Draw();
            pDrawable->GetFromLocation(&m_nFromX, &m_nFromY);
            pDrawable->GetToLocation(&m_nToX, &m_nToY);
        }
    }

    CDrawableElement::SetDevConHelper(NULL);

    return CG_S_OK;

}

CDrawableElement* CConGraTDoc::ObjectAt(const CPoint &point, ViewType eViewType)
{
  
    /************* Temporary Code *******************************
    CRect rect(point, CSize(1, 1));

    // get a list of objects in the DOC/KB
    std::vector<CDrawableElement*>::iterator vi;

    // find any of the object intersects with the point
	for(vi=m_pTempObjList.begin();vi!=m_pTempObjList.end();vi++)
	{
        CDrawableElement* pObj = *vi;
		if (pObj->Intersects(rect))
			return pObj;
	}
    **************** Temporary Code *********************************/

    if(m_pKnowledgeBase)
    {
        std::vector<CDrawableElement*> vHitList;
        ACCDrawableComposite *pDrawableComposite;
        if(eViewType == ViewType_SheetOfAssertion)
        {
            pDrawableComposite = dynamic_cast<ACCDrawableComposite*>(m_pKnowledgeBase->GetSOA());
        }
        else if(eViewType == ViewType_CatalogOfIndividuals)
        {
            pDrawableComposite = dynamic_cast<ACCDrawableComposite*>(m_pKnowledgeBase->GetCOI());
        }
        else if(eViewType == ViewType_RelationHierarchy)
        {
            pDrawableComposite = dynamic_cast<ACCDrawableComposite*>(m_pKnowledgeBase->GetRelations());
        }
        else if(eViewType == ViewType_TypeHierarchy)
        {
            pDrawableComposite = dynamic_cast<ACCDrawableComposite*>(m_pKnowledgeBase->GetTypes());
        }

        if(!pDrawableComposite)
        {
            ASSERT(0);
        }
        else
        {
            vHitList = pDrawableComposite->ObjectsAt(point.x, point.y);
        }

        if(vHitList.size() > 0)
            return vHitList[0];
    }
    
	return NULL;
}

void CConGraTDoc::GetFromLocation(int *pnFromX, int *pnFromY)
{
    *pnFromX = m_nFromX;
    *pnFromY = m_nFromY;
}

void CConGraTDoc::GetToLocation(int *pnToX, int *pnToY)
{
    *pnToX = m_nToX;
    *pnToY = m_nToY;
}
