/*********************************************************
** Copyright (c) 2005
** University of Washington
** Licensed under the terms set forth by University of
** Washington. If you did not sign such a license, you
** are using this software/code illegally and you do not
** have permission to use, modify, or redistribute
** this or any files in this software package.
**
** File: ClusterNode.h
**
**********************************************************/
#ifndef __CLUSTERNODE_H__
#define __CLUSTERNODE_H__

#ifndef NULL
#define NULL 0
#endif

#include <utility>
#include <map>
#include "ClusterNodeVector.h"

using namespace std;

class CClusterNode;
class CClusterNodeVector;
class CClusterNodeFunction;

typedef CClusterNodeVector NodeVector;
typedef pair<CClusterNode*, CClusterNode*> TLeafPair;
typedef map<double, TLeafPair > TCostPairMap;

class CClusterNode
{
 public:
  CClusterNode(void* pData, int index);
  CClusterNode(void* pData, int index, CClusterNode* pLeft, CClusterNode* pRight);
  ~CClusterNode();
  void RecursiveDelete();

  CClusterNode* GetParent();
  void SetParent(CClusterNode* pParent);
  CClusterNode* GetLeftChild();
  CClusterNode* GetRightChild();
  int GetIndex();
  void* GetData();
  bool IsLeaf();
  bool IsLeftLeaf(CClusterNode* child);
  bool IsRightLeaf(CClusterNode* child);
  inline NodeVector* GetLeftLeaves() { return m_pLeftLeaves; }
  inline NodeVector* GetRightLeaves() { return m_pRightLeaves; }
  int GetLeafCount();

  void SwapLeaves();

  void WalkLeaves(CClusterNodeFunction *pFunc);
  void WalkTree(CClusterNodeFunction *pFunc);

  //  TCostPairMap* GetCostPairMap() { return &m_M; }
  //void InsertIntoCostPairMap(double cost, CClusterNode* u, CClusterNode* w);

 private:
  CClusterNode() {}

  CClusterNode* m_pParent;
  CClusterNode* m_pLeft;
  CClusterNode* m_pRight;
  void* m_pData;
  NodeVector* m_pLeftLeaves;
  NodeVector* m_pRightLeaves;

  bool IsDescendant(CClusterNode* child);
  bool VectorContains(NodeVector* pVec, CClusterNode* pTree);

  int m_index; // index into the trees array

};

class CClusterNodeFunction
{
 public:
  CClusterNodeFunction() {}
  virtual ~CClusterNodeFunction() {}
  virtual void Go(CClusterNode* pNode) = 0;
};

#endif
