// MainFrm.cpp : implementation of the CMainFrame class
//

#include "stdafx.h"
#include "SKOKO.h"
#include "SKOKODoc.h"
#include "SKOKOView.h"
#include "ErrView.h"
#include "SettingsDlg.h"
#include "NovellUserSelDlg.h"
#include "MainFrm.h"

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

/////////////////////////////////////////////////////////////////////////////
// CMainFrame

IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)

BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
  //{{AFX_MSG_MAP(CMainFrame)
  ON_WM_CREATE()
  ON_COMMAND(ID_VIEW_SETTINGS, OnViewSettings)
	ON_COMMAND(ID_USER_INFO, OnUserInfo)
	//}}AFX_MSG_MAP
  ON_UPDATE_COMMAND_UI(IDC_COMBO_OWNERS, OnUpdateComboOwners)
END_MESSAGE_MAP()

static UINT indicators[] =
{
  //ID_SEPARATOR,           // status line indicator
  ID_INDICATOR_COUNT,
  ID_INDICATOR_SIZE,
  ID_INDICATOR_OWNERS,
  ID_INDICATOR_ERR
};

/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction

CMainFrame::CMainFrame()
{
  // TODO: add member initialization code here
  
}

CMainFrame::~CMainFrame()
{
}

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
  if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
    return -1;
  
  if (!m_wndToolBar.CreateEx(this, TBSTYLE_FLAT, WS_CHILD | WS_VISIBLE | CBRS_TOP
    | CBRS_GRIPPER | CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC) ||
    !m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
  {
    TRACE0("Failed to create toolbar\n");
    return -1;      // fail to create
  }

  if (!m_wndStatusBar.Create(this) ||
    !m_wndStatusBar.SetIndicators(indicators,
      sizeof(indicators)/sizeof(UINT)))
  {
    TRACE0("Failed to create status bar\n");
    return -1;      // fail to create
  }

  if (!m_wndDialogBar.Create(this, IDD_OWNER_SEL_BAR, CBRS_TOP, IDD_OWNER_SEL_BAR))
  {
    TRACE0("Failed to create dialog bar\n");
    return -1;      // fail to create
  }

  EnableDocking(CBRS_ALIGN_ANY);

  m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
  m_wndDialogBar.EnableDocking(CBRS_ALIGN_ANY);
  DockControlBar(&m_wndToolBar, AFX_IDW_DOCKBAR_TOP);
  DockControlBar(&m_wndDialogBar, AFX_IDW_DOCKBAR_TOP);

  UpdateOwnerIndicator();

  return 0;
}

BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
  if( !CFrameWnd::PreCreateWindow(cs) )
    return FALSE;
  // TODO: Modify the Window class or styles here by modifying
  //  the CREATESTRUCT cs

  return TRUE;
}

/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics

#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
  CFrameWnd::AssertValid();
}

void CMainFrame::Dump(CDumpContext& dc) const
{
  CFrameWnd::Dump(dc);
}

#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers


void CMainFrame::SetCountIndicator( UINT selected, UINT total )
{
  CString text;
  if (total > 0)
  {
    if (selected > 0)
      text.Format(_T("Выделено файлов: %u/%u"), selected, total);
    else
      text.Format(_T("Всего файлов: %u"), total);
  }
  else
    text = _T("");
  CStatusBarCtrl& ctrl = m_wndStatusBar.GetStatusBarCtrl();
  const int idx = m_wndStatusBar.CommandToIndex(ID_INDICATOR_COUNT);
  ctrl.SetText(text, idx, 0);
}

void CMainFrame::SetErrIndicator( UINT errCount )
{
  CString text;
  if (errCount > 0)
    text.Format(_T("Всего ошибок: %d"), errCount);
  else
    text = _T("");
  CStatusBarCtrl& ctrl = m_wndStatusBar.GetStatusBarCtrl();
  const int idx = m_wndStatusBar.CommandToIndex(ID_INDICATOR_ERR);
  ctrl.SetText(text, idx, 0);
}

void CMainFrame::SetSizeIndicator( size_t selected, size_t total )
{
  CString text;
  if (total > 0)
  {
    if (selected > 0)
      text.Format(_T("Суммарный объем: %u/%u"), selected, total);
    else
      text.Format(_T("Суммарный объем: %u"), total);
  }
  else
    text = _T("");
  CStatusBarCtrl& ctrl = m_wndStatusBar.GetStatusBarCtrl();
  const int idx = m_wndStatusBar.CommandToIndex(ID_INDICATOR_SIZE);
  ctrl.SetText(text, idx, 0);
}

void CMainFrame::UpdateBars( void )
{
  // Рассчитываем положение, в которое нужно "придочить" DialogBar
  // чтобы она оказалась справа от ToolBar:
  CRect rcToolBar, rcDlgBar;
  m_wndToolBar.GetWindowRect(&rcToolBar);
  m_wndDialogBar.GetWindowRect(&rcDlgBar);
  int w = rcDlgBar.Width();
  rcDlgBar.top = rcToolBar.top;
  rcDlgBar.bottom = rcToolBar.bottom;
  rcDlgBar.left = rcToolBar.right - 5;
  rcDlgBar.right = rcDlgBar.left + w - 5;

  DockControlBar(&m_wndDialogBar, AFX_IDW_DOCKBAR_TOP, &rcDlgBar);
}

BOOL CMainFrame::OnCommand(WPARAM wParam, LPARAM lParam) 
{
  int id = LOWORD(wParam);
  int msg = HIWORD(wParam);
  if (IDC_COMBO_OWNERS == id && CBN_SELENDOK == msg)
  {
    CComboBox* pCombo = (CComboBox*)m_wndDialogBar.GetDlgItem(IDC_COMBO_OWNERS);
    ASSERT_VALID(pCombo);
    
    CString owner;
    int sel = pCombo->GetCurSel();
    if (sel >= 0)
      owner = GetUserNameAt(sel);

    CSKOKODoc* pDoc = (CSKOKODoc*)GetActiveDocument();
    ASSERT_VALID(pDoc);
    pDoc->SetOwner(owner);

    return TRUE;
  }
  else
    return CFrameWnd::OnCommand(wParam, lParam);
}

void CMainFrame::RemoveAllOwners( void )
{
  CComboBox* pCombo = (CComboBox*)m_wndDialogBar.GetDlgItem(IDC_COMBO_OWNERS);
  ASSERT_VALID(pCombo);
  pCombo->ResetContent();
  UpdateOwnerIndicator();
}

void CMainFrame::AddOwner( LPCTSTR owner )
{
  CComboBox* pCombo = (CComboBox*)m_wndDialogBar.GetDlgItem(IDC_COMBO_OWNERS);
  ASSERT_VALID(pCombo);
  pCombo->AddString(GetFullUserName(owner, false));
  UpdateOwnerIndicator();
}

void CMainFrame::OnUpdateComboOwners( CCmdUI* pCmdUI ) 
{
  CComboBox* pCombo = (CComboBox*)m_wndDialogBar.GetDlgItem(IDC_COMBO_OWNERS);
  ASSERT_VALID(pCombo);
  pCmdUI->Enable(pCombo->GetCount() > 0);
}

void CMainFrame::SelectOwner( void )
{
  CComboBox* pCombo = (CComboBox*)m_wndDialogBar.GetDlgItem(IDC_COMBO_OWNERS);
  ASSERT_VALID(pCombo);
  CSKOKODoc* pDoc = (CSKOKODoc*)GetActiveDocument();
  ASSERT_VALID(pDoc);
  if (theApp.IsAdminMode())
  {
    pCombo->SetCurSel(pCombo->FindString(-1, ALL_OWNERS));
    pDoc->SetOwner(_T(""));
  }
  else
  {
    int sel = pCombo->FindString(-1, GetFullUserName(theApp.m_userName, false));
    if (sel < 0)
    {
      pCombo->SetCurSel(pCombo->FindString(-1, ALL_OWNERS));
      pDoc->SetOwner(_T(""));
    }
    else
    {
      pCombo->SetCurSel(sel);
      pDoc->SetOwner(theApp.m_userName);
    }
  }
}

BOOL CMainFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) 
{
  BOOL ok = m_wndSplitter.CreateStatic(this, 2, 1);
  m_wndSplitter.CreateView(
    0, 0,
    RUNTIME_CLASS(CSKOKOView),
    CSize(460, 300),
    pContext);
  m_wndSplitter.CreateView(
    1, 0,
    RUNTIME_CLASS(CErrView),
    CSize(460, 50),
    pContext);
  m_wndSplitter.SetRowInfo(1, 50, 0);
  
  return ok;
}

void CMainFrame::OnViewSettings() 
{
  CSettingsDlg dlg;
  if (IDOK == dlg.DoModal() && theApp.m_tempDir != dlg.m_tempDir)
  {
    CString s;
    int res = AfxMessageBox(
      _T("Текущие результаты будут потеряны. Продолжить?"),
      MB_ICONWARNING | MB_YESNO);
    if (IDYES == res)
    {
      CSKOKODoc* pDoc = (CSKOKODoc*)GetActiveDocument();
      ASSERT_VALID(pDoc);
      pDoc->Clear();
      RemoveAllOwners();
      theApp.m_tempDir = dlg.m_tempDir;
      theApp.WriteProfileString(
        _T("Settings"),
        _T("TempDir"),
        theApp.m_tempDir);
    }
  }
}

void CMainFrame::EnsureOwnerExists(LPCTSTR name)
{
  CComboBox* pCombo = (CComboBox*)m_wndDialogBar.GetDlgItem(IDC_COMBO_OWNERS);
  for (int i = 0; i < pCombo->GetCount(); ++i)
  {
    CString s;
    pCombo->GetLBText(i, s);
    if (!GetUserNameAt(i).CompareNoCase(name))
      return;
  }

  pCombo->AddString(GetFullUserName(name, false));
  UpdateOwnerIndicator();
}

CString CMainFrame::GetUserNameAt(int idx)
{
  CComboBox* pCombo = (CComboBox*)m_wndDialogBar.GetDlgItem(IDC_COMBO_OWNERS);
  CString fullName;
  pCombo->GetLBText(idx, fullName);
  int pos = fullName.Find(_T('('));
  fullName.Delete(pos, fullName.GetLength() - pos);
  fullName.TrimRight();
  return fullName;
}

void CMainFrame::UpdateOwnerIndicator()
{
  CComboBox* pCombo = (CComboBox*)m_wndDialogBar.GetDlgItem(IDC_COMBO_OWNERS);
  CString text;
  int n = pCombo->GetCount();
  if (n > 0)
  {
    --n; // исключая ALL
    text.Format(_T("%d пользовател%s"),
      n,
      (n%10 == 1 && n != 11) ?
        "ь" :
        ((n < 10 || n > 20) && n%10 >= 2 && n%10 <= 4) ?
          "я" :
          "ей");
  }
  CStatusBarCtrl& ctrl = m_wndStatusBar.GetStatusBarCtrl();
  const int idx = m_wndStatusBar.CommandToIndex(ID_INDICATOR_OWNERS);
  ctrl.SetText(text, idx, 0);
}

void CMainFrame::HideOwner( void )
{
  CComboBox* pCombo = (CComboBox*)m_wndDialogBar.GetDlgItem(IDC_COMBO_OWNERS);
  pCombo->SetCurSel(-1);
}

void CMainFrame::OnUserInfo() 
{
  CNovellUserSelDlg dlg;
  dlg.m_allowNoOwner = false;
  dlg.DoModal();
}
