/*	Author: Magdin Stoica
	Supervisor: Dr. Ryan Leduc
	
	Project created in conformity with the requirements for the Degree of Master of Engineering in Software Engineering, 
	Computing and Software Department, 
	McMaster University
	2003 - 2007
*/

#include "HierProjectPropCheck.h"

// for debug
// #include <iostream>

namespace DESpot
{

const std::wstring HierProjectPropCheck::cHierProjectPropCheckAlgoDesc = L"HISC Project Properties Check Algorithm";

HierProjectPropCheck::HierProjectPropCheck(DesHierProject& project, bool runIncremental /*= true*/):
		m_project(project),
		m_checkInteg(true),
		m_integAlgo(runIncremental),
		m_checkIConsist(true),
		m_iConsAlgo(project, runIncremental),
		m_checkLwNonBlock(true),
		m_lwNonBlockAlgo(project, runIncremental),
		m_checkLwCtrl(true),
		m_lwCtrlAlgo(project, runIncremental),
		m_runSuccessful(false)
{
	m_runIncremental = runIncremental;
	m_description = cHierProjectPropCheckAlgoDesc;
}

//_________________________________________________________________________________________________

HierProjectPropCheck::~HierProjectPropCheck(void)
{
}

//_________________________________________________________________________________________________

void HierProjectPropCheck::checkIntegrity(bool checkInteg /*= true*/)
{
	m_checkInteg = checkInteg;
}

//_________________________________________________________________________________________________

bool HierProjectPropCheck::integrityChecked() const
{
	return m_checkInteg;
}

//_________________________________________________________________________________________________

HierProjIntegrityAlgo& HierProjectPropCheck::integAlgo()
{
	return m_integAlgo;
}

//_________________________________________________________________________________________________

void HierProjectPropCheck::checkInterfConsist(bool checkIConsist /*= true*/)
{
	m_checkIConsist = checkIConsist;
}

//_________________________________________________________________________________________________

bool HierProjectPropCheck::iConsistChecked() const
{
	return m_checkIConsist;
}

//_________________________________________________________________________________________________

IConsistAlgo& HierProjectPropCheck::interfConsistAlgo()
{
	return m_iConsAlgo;
}

//_________________________________________________________________________________________________

void HierProjectPropCheck::checkLwNonBlock(bool checkLwNonBlock /*= true*/)
{
	m_checkLwNonBlock = checkLwNonBlock;
}

//_________________________________________________________________________________________________

bool HierProjectPropCheck::lwNonBlockChecked() const
{
	return m_checkLwNonBlock;
}

//_________________________________________________________________________________________________

LwNonBlockingAlgo& HierProjectPropCheck::levelWiseNonBlockAlgo()
{
	return m_lwNonBlockAlgo;
}

//_________________________________________________________________________________________________

void HierProjectPropCheck::checkLwCtrl(bool checkLwCtrl /*= true*/)
{
	m_checkLwCtrl = checkLwCtrl;
}

//_________________________________________________________________________________________________

bool HierProjectPropCheck::lwCtrlChecked()
{
	return m_checkLwCtrl;
}

//_________________________________________________________________________________________________

LwCtrlAlgo& HierProjectPropCheck::levelWiseCtrlAlgo()
{
	return m_lwCtrlAlgo;
}

//_________________________________________________________________________________________________

bool HierProjectPropCheck::runSuccessful() const
{
	return m_runSuccessful;
}

//_________________________________________________________________________________________________

void HierProjectPropCheck::prepareRun()
{
	if (m_runIncremental == false)
	{
		//this will reset all properties to "not verified" the validity of all
		//subsystems and interfaces to false and it will clean all pre-computed
		//sync products of all subsystems and interfaces
		m_project.clean();
	}

	m_integAlgo.provideProgress(m_progress);
	m_iConsAlgo.provideProgress(m_progress);
	m_lwNonBlockAlgo.provideProgress(m_progress);
	m_lwCtrlAlgo.provideProgress(m_progress);
}

//_________________________________________________________________________________________________

bool HierProjectPropCheck::runAlgo()
{
	prepareRun();

	m_runSuccessful = true;

	if (m_checkInteg || !m_runIncremental)
	  {
	    if (m_project.getIntegrity() != eIntegYes || !m_runIncremental)
	      {
		m_runSuccessful &= m_project.checkIntegrity(m_integAlgo);
	      }
	    else
	      {
		m_integAlgo.overrideIsValid();
	      }
	  }



	bool con=false;
	bool non=false;
	bool intf=false;

	if (m_checkLwCtrl)
	{
	  if (m_project.getLwCtrlProp() != eLwCtrlYes || !m_runIncremental)
	    {
	      con=true;
	      m_lwCtrlAlgo.start();
	    }
	  else
	    {
	      m_lwCtrlAlgo.overrideLwControllable(true);
	    }
	}
	
				
	if (m_checkLwNonBlock)
	{
	  if (m_project.getLwNonBlockProp() != eLwNonBlockYes || !m_runIncremental)
	    {
	      non=true;
	      m_lwNonBlockAlgo.start();
	    }
	  else
	    {
	      m_lwNonBlockAlgo.overrideLwNonBlocking(true);
	    }
	}


	if (m_checkIConsist)
	{
	  if (m_project.getIConsistProp() != eIConsYes || !m_runIncremental)
	    {
	      intf=true;
	      m_iConsAlgo.start();
	    }
	  else
	    {
	      m_iConsAlgo.overrideInterfConsist(true);
	    }
	}
	
	
	

    if(con==true)

	{
		m_lwCtrlAlgo.wait();
		m_runSuccessful &= m_project.checkLwCtrlProp(m_lwCtrlAlgo,true);
	}


	if(non==true)
	{
		m_lwNonBlockAlgo.wait();
        m_runSuccessful &= m_project.checkLwNonBlockProp(m_lwNonBlockAlgo,true);
	}


    if(intf==true)
	{
		m_iConsAlgo.wait();
        m_runSuccessful &= m_project.checkIConsistProp(m_iConsAlgo,true);
	}


	return m_runSuccessful;
}

} //end of namespace DESpot
