// Input.cpp: implementation of the CInput class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
//#include "ComHelp.h"
//#include "GMECOM.h"
//#include "ComponentConfig.h"
//#include "RawComponent.h"
#include "Input.h"

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

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

CInput::CInput()
{
    
}

CInput::~CInput()
{

}

//Get the search criterias
void CInput::GetInput(CString strNameFirst, CString strRoleFirst, CString strKindFirst, CString strAttributeFirst,CString strNameSecond,CString strRoleSecond,CString strKindSecond,CString strAttributeSecond,
                      CString attrval, BOOL mod, BOOL atom, BOOL ref, BOOL set,BOOL connection,BOOL splSearch, BOOL full, 
                      BOOL bMatchCase, int scopedSearch,int logicalExpr)
{
    //doScopedSearch = bScopedSearch;

    m_bGetCaseIgnored = !bMatchCase;
    if( m_bGetCaseIgnored)
    {
        strNameFirst.MakeLower();
        strRoleFirst.MakeLower();
        strKindFirst.MakeLower();
        strAttributeFirst.MakeLower();

        //attrval seems not used
        attrval.MakeLower();
        //addded
        strNameSecond.MakeLower();
        strRoleSecond.MakeLower();
        strKindSecond.MakeLower();
        strAttributeSecond.MakeLower();
    }
    
    m_bFull=full;

    //get regular expression forms
    m_regNameFirst = GetRegExp(strNameFirst);
    m_regRoleFirst = GetRegExp(strRoleFirst);
    m_regKindFirst = GetRegExp(strKindFirst);

    m_regNameSecond=GetRegExp(strNameSecond);
    m_regKindSecond=GetRegExp(strKindSecond);
    m_regRoleSecond=GetRegExp(strRoleSecond);

    //get string forms

    //objVal = attrval;
    //objattribName = strAttributeFirst;
    m_strNameFirst=strNameFirst;
    m_strKindFirst=strKindFirst;
    m_strRoleFirst=strRoleFirst;
    m_strAttributeFirst=strAttributeFirst;

    m_strNameSecond=strNameSecond;
    m_strKindSecond=strKindSecond;
    m_strRoleSecond=strRoleSecond;
    m_strAttributeSecond=strAttributeSecond;
   

    //check if nothing is present in the second
    if(strNameSecond.Trim()==_T("") && strKindSecond.Trim()==_T("")&& strRoleSecond.Trim()==_T("") && strAttributeSecond.Trim()==_T(""))
    {
        m_bDoSecond=FALSE;
    }
    else m_bDoSecond=TRUE;
    //getSplSearch = spl;

    m_bGetModels = mod;
    m_bGetAtoms = atom;
    m_bGetReferences = ref;
    m_bGetSets = set;
    m_bGetConnections=connection;
    m_bGetSplSearch=splSearch;
    m_intScope=scopedSearch;
    m_intLogical=logicalExpr;
    ParseAttribute();
}

//Parses attribute expressions and keeps it in stack
//Two stacks are used for both lhs and rhs search criteria
void CInput::ParseAttribute()
{
    //prepare the stack containing expressions and operations for first attribute
    PrepareExpressionStack(m_strAttributeFirst,m_stackExpressionFirst);

    //prepare the stack containing expressions and operations for second attribute
    PrepareExpressionStack(m_strAttributeSecond,m_stackExpressionSecond);
}

void CInput::PrepareExpressionStack(const CString &atrAttributeExpression,std::vector<Attribute>& stack)
{
    //strOperation stores operators like &, |
    //strUnitExpression is the expression like age> 30, i.e. it
    //is a complete single expression without logical operator
    CString strOperation,strUnitExpression; 

    CString strAttributeExpression(atrAttributeExpression);

    //get the index of logical operator
    int index= strAttributeExpression.FindOneOf(_T("&|"));

    //if no logical operator was found push the whole expression
    if(index==-1 && strAttributeExpression!=_T(""))
    {
        stack.push_back(Attribute(strAttributeExpression.Trim()));
    }
   
    while(index!=-1)
    {
        //extract the operator
        strOperation=strAttributeExpression[index];

        //extract a single expression, the string on left of the index is a complete
        //expression
        AfxExtractSubString(strUnitExpression,strAttributeExpression,0,strAttributeExpression[index]);

        //put the expression on stack
        stack.push_back(Attribute(strUnitExpression.Trim()));

        //push the operator either &, |
        stack.push_back(Attribute(CString(strOperation)));

        //extract the remaining string on the right of index
        strAttributeExpression=strAttributeExpression.Right(strAttributeExpression.GetLength()-index-1);
        
        //again find the logical operator
        index= strAttributeExpression.FindOneOf(_T("&|"));

        //if no more found treat all remaining string as expression
        if(index==-1) stack.push_back(Attribute(strAttributeExpression.Trim()));
    }
}

//Obtain regular expression form of the string
//supplied
wregex CInput::GetRegExp(CString name)
{
    CString temp=_T("");
    if(name.IsEmpty())
    {
        return wregex(name);
    }
    if(m_bFull)
    {
        temp=_T("^");
        temp+=name;
        temp+=_T("$");
        return wregex(temp);
    }

    return wregex(name);
}
