/**------------------------------------------------------------------------
 * @file
 *
 * Copyright 2001 by the University of Toronto (UT).
 *
 *                       All Rights Reserved
 * 
 * Permission to copy and modify this software and its documentation 
 * only for internal use in your organization is hereby granted, 
 * provided that this notice is retained thereon and on all copies.  
 * UT makes no representations as to the suitability and operability 
 * of this software for any purpose.  It is provided "as is" without 
 * express or implied warranty.
 *
 * UT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
 * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT
 * SHALL UT BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA
 * OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 * PERFORMANCE OF THIS SOFTWARE.
 *
 * No other rights, including for example, the right to redistribute 
 * this software and its documentation or the right to prepare 
 * derivative works, are granted unless specifically provided in a 
 * separate license agreement.
 *
 * Author: Diego Macrini
 *
 * $Log: ShapeMatcher.h,v $
 *
 * Revision 1.1.1.1  2002/03/10 07:38:08  dmac
 * Imported sources
 *
 *-----------------------------------------------------------------------*/

#ifndef _SHAPE_MATCHER_H_
#define _SHAPE_MATCHER_H_
 
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <algorithm>
#include <string>

#include <DirWalker.h>

#include <ShockGraph.h>
#include <GestureGraph.h>
#include <BoneGraph.h>

#include <DAGDatabase.h>

#include <Exceptions.h>
#include <HelperFunctions.h>
//#include <UnixFuncPrototypes.h>

#include "CmdLineParser.h"

#include "ViewSubsampler.h"
#include "Stats.h"

#include "InfoStructures.h"

using namespace dml;

class ShapeMatcher : public CmdLineParser
{
	typedef bool (ShapeMatcher::*DAG_ACTION)();

	typedef std::map<std::string, int> StrIntMap;

	ShapeMatchingParams m_matchInfo;
	ShapeRepresentationParams m_shapeInfo;

	double m_maxOcclusionRate, m_dNeigRange;
	int m_iterations, m_maxdags, m_imgstep, m_from, m_to, m_nNumSplitParts;
	int m_nVerbose, m_saveSubsamplingInfo, m_nSplitProportion, m_nSplitByObject;
	int m_xpos, m_ypos, m_sourceDB;

	int m_firstDBId, m_lastDBId;

	int m_experimentId, m_experimentStep, m_experimentFirstParam, m_experimentLastParam;
	LPCSTR m_szExperimentName;

	LPCSTR m_target, m_objName, m_delobj, m_createObj, m_viewDag, m_szMatrixFileName;
		
public:		
	DAGMatcher::MatchParams m_matchParams;

public:
	DAGDatabase m_dagDB;
	DAGDatabase m_tgtDagDB;

public:
	bool AddObjsToDB();
	bool CreateDBIndex();
	bool Match();
	bool MultiDBMatch();
	bool NodeMatch();
	bool CreateMatrix();
	bool ViewDAGs();
	bool ViewDAG();
	bool ViewDAGAndNeighbors();
	bool ListDAGs();
	bool ShowDBSize();
	bool CreateAffinityMatrix();
	bool PlotNodeInfo();
	bool SplitDB();
	bool IncrementalObjectDBSplit();
	bool IncrementalRandomDBSplit();
	bool MergeDB();
	bool UpdateDB();
	bool RecomputeGraphs();
	bool Test();
	bool ListObjectNames();
	bool DeleteObj();
	bool EnterDbgMode();
	bool DeleteDAGs();
	bool CopyDAGs();
	bool DeleteObjects();
	bool CopyObjects();
	bool ClosestNeigList();
	bool Closest9NeigList();
	bool GetNeig();
	bool ShowHelp();
	bool CheckSGGrammar();
	bool FindShapePrototypes();
	bool AddObjsUsingTraining();
	bool CompareDAGs();
	bool SaveInXMLFormat();
	bool ShowDAGTable();

	bool MatchImageFile();

	bool CreateDBParsings();
	bool MatchDBParsings();

	bool Verbose() { return m_nVerbose != 0; }

	bool RecomputeAndSaveGraphs(const char* szTgtDBFilename, bool bCheckExist);
	bool RecomputeGraph(int dagID);

	DAGDatabase* OpenSourceDatabase(DAGDatabase* pSrcDB);

	bool ShowDAG(DAGDatabase& dagBD, int nDagId) const;

	int CountNumberOfViewsPerObject(StrIntMap& objs);
	bool MatchDB(const char* queryDB, const char* modelDB);

	virtual void InitOptions();
	virtual void ShowUsageExamples();

	virtual bool ExecAction(CLP_ACTION pAction)
	{
		DAG_ACTION action = (DAG_ACTION) pAction;
		return (this->*action)();
	}

	//! Sets computation mode to sync (true) or async (false) mode
	void SetSyncMode(bool bSync) { m_matchInfo.asyncCompu = (bSync) ? 0 : 1; }

	//! Returns true if the cumputation is set to async mode
	bool AsyncMode() const { return m_matchInfo.asyncCompu != 0; }

	//! Gets the last DAG id as specified by the "-to" command line argument
	int GetLastDAGId(const int sz) const
	{
		if (m_to < 0)
			return sz - 1;
		else if (m_to < sz)
			return m_to;
		
		ShowErrorMsg("Invalid DAG ID in '-to' parameter");

		return -1;
	}

	//! Gets the last DAG id as specified by the "-to" command line argument
	int GetLastDAGId(const DAGDatabase* pDB = NULL) const
	{
		return  GetLastDAGId((pDB) ? 
			pDB->GetDAGCount() : m_dagDB.GetDAGCount());
	}
};

#endif // _SHAPE_MATCHER_H_
