#include "stdafx.h"
#include "SKOKO.h"
#include "UserTree.h"

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

//
// CUserTreeNode
//

CUserTreeNode::CUserTreeNode( void ) : m_pObject(0), m_iconId(-1)
{
}

CUserTreeNode::~CUserTreeNode( void )
{
  for (int i = 0; i < m_children.size(); ++i)
    delete m_children[i];
  m_pObject = 0; // calls release
}

void CUserTreeNode::setObject( BGDNet::NDSObject* pObj, int iconId )
{
  m_pObject = pObj;
  m_fullName = GetFullUserName(pObj, true);
  m_dn = pObj->dn();
  m_baseClass = pObj->baseClass();
  m_iconId = iconId;
}

void CUserTreeNode::addChild( CUserTreeNode* pChild )
{
  m_children.add(pChild);
}

//
// CUserTree
//

CUserTree::CUserTree( const BGDNet::Context& ctx ) :
  m_ctx(ctx),
  m_pRoot(0)
{
  m_pRoot = new CUserTreeNode;
  try
  {
    m_pRoot->setObject(
      new BGDNet::NDSObject(m_ctx, "[Root]"),
      CSKOKOApp::ICON_ROOT);
    InsertUsers(m_pRoot);
  }
  catch (...)
  {
    delete m_pRoot;
    throw;
  }
}

CUserTree::~CUserTree( void )
{
  delete m_pRoot;
}

bool CUserTree::InsertUsers( CUserTreeNode* pParent )
{
  const BGDNet::NDSObject* pContainer = pParent->obj();
  
  bool containsUsers = false;
  BGDNet::NDSObjects subordinates;
  pContainer->getSubordinates(&subordinates);
  for (int i = 0; i < subordinates.size(); ++i)
  {
    BGDNet::NDSObject* pObj = subordinates[i];

    BGDNet::String className = pObj->baseClass();
    int iconId = -1;
    if (className == countryClassName)
      iconId = CSKOKOApp::ICON_COUNTRY;
    if (className == orgClassName)
      iconId = CSKOKOApp::ICON_ORG;
    else if (className == orgUnitClassName)
      iconId = CSKOKOApp::ICON_OU;
    else if (className == userClassName)
    {
      iconId = CSKOKOApp::ICON_USER;
      containsUsers = true;
    }

    CUserTreeNode* pNode = 0;
    try
    {
      if (iconId >= 0)
      {
        pNode = new CUserTreeNode;
        pObj->addRef();
        pNode->setObject(pObj, iconId);
        if (pObj->isContainerEntry())
        {
          if (InsertUsers(pNode))
            containsUsers = true;
          else
          {
            delete pNode;
            pNode = 0;
          }
        }
      }
    }
    catch (...)
    {
      if (pNode)
        delete pNode;
      throw;
    }

    if (pNode)
      pParent->addChild(pNode);
  }

  return containsUsers;
}
