// SKOKO.cpp : Defines the class behaviors for the application.
//

#include "stdafx.h"
#include "SKOKO.h"
#include "MainFrm.h"
#include "SKOKODoc.h"
#include "SKOKOView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CSKOKOApp

BEGIN_MESSAGE_MAP(CSKOKOApp, CWinApp)
  //{{AFX_MSG_MAP(CSKOKOApp)
  ON_COMMAND(ID_APP_ABOUT, OnAppAbout)
    // NOTE - the ClassWizard will add and remove mapping macros here.
    //    DO NOT EDIT what you see in these blocks of generated code!
  //}}AFX_MSG_MAP
  // Standard file based document commands
  ON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)
  ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CSKOKOApp construction

CSKOKOApp::CSKOKOApp()
{
  // TODO: add construction code here,
  // Place all significant initialization in InitInstance
  m_bIsAdminMode = false;
}

CSKOKOApp::~CSKOKOApp()
{
  if (m_pUserTree)
    delete m_pUserTree;
}

/////////////////////////////////////////////////////////////////////////////
// The one and only CSKOKOApp object

CSKOKOApp theApp;

/////////////////////////////////////////////////////////////////////////////
// CSKOKOApp initialization

BOOL CSKOKOApp::InitInstance()
{
  // Инициализируем ImageList
  UINT aIcons[ICON_COUNT] =
  {
    IDI_ICON_NETWORK,
    IDI_ICON_NET_DRIVE,
    IDI_ICON_SERVER,
    IDI_ICON_VOLUME,
    IDI_ICON_DIR,
    IDI_ICON_FILE,
    IDI_ICON_ERROR,
    IDI_ICON_ROOT,
    IDI_ICON_COUNTRY,
    IDI_ICON_ORG,
    IDI_ICON_OU,
    IDI_ICON_USER,
    IDI_ICON_NO_OWNER
  };
  int cx = GetSystemMetrics(SM_CXSMICON);
  int cy = GetSystemMetrics(SM_CYSMICON);
  m_imageList.Create(cx, cy, ILC_COLOR | ILC_MASK, ICON_COUNT, 0);
  for (int i = 0; i < ICON_COUNT; ++i )
    m_imageList.Add(LoadIcon(aIcons[i]));

  // Standard initialization
  // If you are not using these features and wish to reduce the size
  //  of your final executable, you should remove from the following
  //  the specific initialization routines you do not need.

#ifdef _AFXDLL
  Enable3dControls();      // Call this when using MFC in a shared DLL
#else
  Enable3dControlsStatic();  // Call this when linking to MFC statically
#endif

  if (!AfxInitRichEdit())
    return FALSE;

  // Change the registry key under which our settings are stored.
  // TODO: You should modify this string to be something appropriate
  // such as the name of your company or organization.
  //SetRegistryKey(_T("Local AppWizard-Generated Applications"));

  LoadStdProfileSettings();  // Load standard INI file options (including MRU)

  m_tempDir = AfxGetApp()->GetProfileString(
    _T("Settings"),
    _T("TempDir"),
    _tgetenv(_T("TEMP")));

  BGDNet::Context tempCtx;
  tempCtx.dckFlags(tempCtx.dckFlags() & ~DCV_CANONICALIZE_NAMES);
  m_userName = BGDNet::NDS::whoAmI(tempCtx);

  CString adminGroupName;
  int orgPos = m_userName.Find(_T("O="));
  if (orgPos < 0)
    adminGroupName = _T("SKOKO_ADMIN");
  else
  {
    adminGroupName = _T(".CN=SKOKO_ADMIN");
    adminGroupName += _T('.');
    adminGroupName += m_userName.Mid(orgPos);
  }

  m_bIsAdminMode = false;
  try
  {
    const BGDNet::String me = BGDNet::NDS::whoAmI(m_ctx);
    BGDNet::NDSObject adminGroup(m_ctx, adminGroupName);
    BGDNet::Strings members;
    if (adminGroup.attr("Member", &members))
    {
      if (members.size() > 0)
      {
        for (int i = 0; i < members.size(); ++i)
        {
          if (members[i] == me)
          {
            m_bIsAdminMode = true;
            break;
          }
        }
      }
    }
  }
  catch (...)
  {
  }

  m_userName.Insert(0, '.');

  if (!m_bIsAdminMode)
    m_bIsAdminMode = IsAdmin(m_userName);

  //CString cmdLine = GetCommandLine();
  //cmdLine.MakeUpper();
  //
  //// !!!!!MUZA!!!!!!!!!!!!!!
  //CString sKey = _T("/ADMIN");
  //// !!!!!!!!!!!!!!!!!!!
  //
  //return (cmdLine.Find(sKey) < 0) ?
  //  InitUserMode() : InitAdminMode();
  return InitAdminMode();
}


/////////////////////////////////////////////////////////////////////////////
// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
  CAboutDlg();

// Dialog Data
  //{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	CRichEditCtrl	m_wndRichEdit;
	//}}AFX_DATA

  // ClassWizard generated virtual function overrides
  //{{AFX_VIRTUAL(CAboutDlg)
  protected:
  virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
  //}}AFX_VIRTUAL

// Implementation
protected:
  //{{AFX_MSG(CAboutDlg)
	virtual BOOL OnInitDialog();
	//}}AFX_MSG
  DECLARE_MESSAGE_MAP()

private:
	int m_curRtfOffset;
	CByteArray m_rtfData;

  static DWORD CALLBACK RichTextStream(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb);
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
  //{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
  CDialog::DoDataExchange(pDX);
  //{{AFX_DATA_MAP(CAboutDlg)
	DDX_Control(pDX, IDC_RICHEDIT_ABOUT, m_wndRichEdit);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
  //{{AFX_MSG_MAP(CAboutDlg)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BOOL CAboutDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();

  HRSRC hRtf = FindResource(
    AfxGetInstanceHandle(),
    MAKEINTRESOURCE(IDR_RTF_ABOUT),
    _T("RTF"));
  if (hRtf != NULL)
  {
    HGLOBAL hResource = LoadResource(
      AfxGetInstanceHandle(),
      hRtf);
    LPBYTE pData = (LPBYTE)LockResource(hResource);
    DWORD dwSize = SizeofResource(
      AfxGetInstanceHandle(),
      hRtf);
    for (DWORD i = 0; i < dwSize; ++i)
      m_rtfData.Add(pData[i]);
    UnlockResource(hResource);
  }
	
  m_curRtfOffset = 0;
	EDITSTREAM es;
  es.dwCookie = (DWORD)this;
  es.dwError = 0;
  es.pfnCallback = RichTextStream;
  m_wndRichEdit.StreamIn(SF_RTF, es);

  m_wndRichEdit.SetTargetDevice(NULL, 0);
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

DWORD CALLBACK CAboutDlg::RichTextStream(DWORD dwCookie, LPBYTE pbBuff, LONG cb, LONG *pcb)
{
  CAboutDlg& self = *(CAboutDlg*)dwCookie;
  *pcb = cb < self.m_rtfData.GetSize() ?
    cb : self.m_rtfData.GetSize();
  memcpy(
    pbBuff,
    self.m_rtfData.GetData() + self.m_curRtfOffset,
    *pcb);
  self.m_curRtfOffset += *pcb;
  return 0;
}

// App command to run the dialog
void CSKOKOApp::OnAppAbout()
{
  CAboutDlg aboutDlg;
  aboutDlg.DoModal();
}

/////////////////////////////////////////////////////////////////////////////
// CSKOKOApp message handlers


int CSKOKOApp::ExitInstance() 
{
  return CWinApp::ExitInstance();
}

BOOL CSKOKOApp::InitAdminMode( void )
{
  // Register the application's document templates.  Document templates
  //  serve as the connection between documents, frame windows and views.

  CSingleDocTemplate* pDocTemplate;
  pDocTemplate = new CSingleDocTemplate(
    IDR_MAINFRAME,
    RUNTIME_CLASS(CSKOKODoc),
    RUNTIME_CLASS(CMainFrame),       // main SDI frame window
    RUNTIME_CLASS(CSKOKOView));
  AddDocTemplate(pDocTemplate);

  // Parse command line for standard shell commands, DDE, file open
  CCommandLineInfo cmdInfo;
  ParseCommandLine(cmdInfo);

  // Dispatch commands specified on the command line
  if (!ProcessShellCommand(cmdInfo))
    return FALSE;

  // The one and only window has been initialized, so show and update it.
  m_pMainWnd->ShowWindow(SW_SHOW);
  m_pMainWnd->UpdateWindow();

  // Правильно расположить панели:
  ((CMainFrame*)m_pMainWnd)->UpdateBars();

  return TRUE;
}

bool CSKOKOApp::IsAdmin( const CString& userName )
{
  return (userName.Find(_T("Admin")) >= 0);
}

bool CSKOKOApp::IsAdminMode( void )
{
  return m_bIsAdminMode;
}

CString GetFullUserName(const BGDNet::NDSObject *pObj, bool returnRDN)
{
  CString name;
  name = returnRDN ? pObj->rdn() : pObj->dn();
  if (pObj->baseClass() == userClassName)
  {
    try
    {
      BGDNet::String surname;
      pObj->attr("Surname", &surname);
      if (surname.length() > 0)
      {
        name += _T(" (");
        name += surname;
        name += _T(")");
      }
    }
    catch (const BGDNet::Exception&)
    {
    }
  }
  //name.OemToAnsi();
  return name;
}

CString GetFullUserName(const char* name, bool returnRDN)
{
  try
  {
    BGDNet::NDSObject obj(theApp.m_ctx, name);
    return GetFullUserName(&obj, returnRDN);
  }
  catch (const BGDNet::Exception&)
  {
    return name;
  }
}
