// CTMSTreeView.cpp : implementation file
//

#include "stdafx.h"
#include "CTMS.h"
#include "CTMSTreeView.h"
#include "MainFrm.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// CCTMSTreeView

IMPLEMENT_DYNCREATE(CCTMSTreeView, CTreeView)

/////////////////////////////////////////////////////////////////////////////
// CCTMSTreeView::CCTMSTreeView()
// 
// 
/////////////////////////////////////////////////////////////////////////////
CCTMSTreeView::CCTMSTreeView()
{

  //attach the images to the treeview
  m_oTreeImages.Create( IDB_TREEVIEW, 16, 12, 0x00ff00ff);

  //set the default style of the treeview, so we like if
  m_dwDefaultStyle |= TVS_HASLINES | TVS_LINESATROOT | TVS_HASBUTTONS; // | TVS_EDITLABELS;
}

/////////////////////////////////////////////////////////////////////////////
// CCTMSTreeView::~CCTMSTreeView()
// 
// 
/////////////////////////////////////////////////////////////////////////////
CCTMSTreeView::~CCTMSTreeView()
{
}


BEGIN_MESSAGE_MAP(CCTMSTreeView, CTreeView)
	//{{AFX_MSG_MAP(CCTMSTreeView)
	ON_NOTIFY_REFLECT(TVN_SELCHANGED, OnSelchanged)
	ON_WM_ERASEBKGND()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CCTMSTreeView drawing

/////////////////////////////////////////////////////////////////////////////
// void CCTMSTreeView::OnDraw(CDC* pDC)
// 
// 
/////////////////////////////////////////////////////////////////////////////
void CCTMSTreeView::OnDraw(CDC* /*pDC*/)
{
  //CDocument* pDoc = GetDocument();
  // TODO: add draw code here
}

/////////////////////////////////////////////////////////////////////////////
// CCTMSTreeView diagnostics

#ifdef _DEBUG
void CCTMSTreeView::AssertValid() const
{
	CTreeView::AssertValid();
}

void CCTMSTreeView::Dump(CDumpContext& dc) const
{
	CTreeView::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CCTMSTreeView message handlers

/////////////////////////////////////////////////////////////////////////////
// void CCTMSTreeView::OnInitialUpdate() 
// 
// 
/////////////////////////////////////////////////////////////////////////////
void CCTMSTreeView::OnInitialUpdate() 
{

	CTreeView::OnInitialUpdate();
	
	// TODO: Add your specialized code here and/or call the base class
  TV_INSERTSTRUCT is = { TVI_ROOT, TVI_LAST};

  //default item list
  GetTreeCtrl().SetImageList( &m_oTreeImages, TVSIL_NORMAL);

  //root of tree, this is default view for communication
  is.item.mask    = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  is.item.iImage  = 0;
  is.item.iSelectedImage  = 1;
  is.item.pszText = "TM Simulation"; //root item
  is.hParent = GetTreeCtrl().InsertItem( &is);
  GetTreeCtrl().SetItemData( is.hParent, 0xff00);

  //walk through th eini file and add TM's
  //the TM numbers can be: 00 - 99
  int alive;
  CString section;
  char buf[20];
  CString tmId;

  for (int i = 0; i <= 99; i++)
  {

    section.Format("TM%02d", i);
    //section += buf;
    strcpy( buf, "AliveTime");
    alive = ((CCTMSApp *)AfxGetApp())->theINIFile.GetInteger( buf, (LPCTSTR)section, -1, true);
  
    //add the first TM
    if (alive > 0)
    {

      //add TM to internal array
      tmId.Format( "%02d", i);
      int idx = ((CCTMSApp *)AfxGetApp())->AddTDI( section);

      //add panel for TM
      AddTM( GetTreeCtrl().GetRootItem( ), TVI_LAST, (LPCTSTR)section, idx);
    }
  }

  //if it is the first TDI, expand the root item
  ExpandRoot();
}


HTREEITEM CCTMSTreeView::AddTM(HTREEITEM hParent, HTREEITEM hInsertAfter, LPCTSTR Title, int Index)
{

  int idx = (Index << 8) + TREEID_TM;
  
  //Add the TM
  HTREEITEM item = AddItem( hParent, hInsertAfter, idx, Title, 2);
  
  //add the child items, first overview

  //AddItem( item, TVI_LAST, idx, _T("Protocol"), 4);
  idx = (Index << 8) + TREEID_COMMAND;
  AddItem( item, TVI_LAST, idx, _T("Commands"), 8);
  
  idx = (Index << 8) + TREEID_STAT;
  AddItem( item, TVI_LAST, idx, _T("Status"), 8);
  
  idx = (Index << 8) + TREEID_INFO_B;
  AddItem( item, TVI_LAST, idx, _T("Statistical boolean"), 4);
  idx = (Index << 8) + TREEID_INFO_I;
  AddItem( item, TVI_LAST, idx, _T("Statistical integer"), 4);
  idx = (Index << 8) + TREEID_INFO_L;
  AddItem( item, TVI_LAST, idx, _T("Statistical long"), 4);
  idx = (Index << 8) + TREEID_INFO_R;
  AddItem( item, TVI_LAST, idx, _T("Statistical real"), 4);
  idx = (Index << 8) + TREEID_INFO_S;
  AddItem( item, TVI_LAST, idx, _T("Statistical string"), 4);

  idx = (Index << 8) + TREEID_PARA_B;
  AddItem( item, TVI_LAST, idx, _T("Parameters bool"), 10);
  idx = (Index << 8) + TREEID_PARA_I;
  AddItem( item, TVI_LAST, idx, _T("Parameters integer"), 10);
  idx = (Index << 8) + TREEID_PARA_L;
  AddItem( item, TVI_LAST, idx, _T("Parameters long"), 10);
  idx = (Index << 8) + TREEID_PARA_R;
  AddItem( item, TVI_LAST, idx, _T("Parameters real"), 10);
  idx = (Index << 8) + TREEID_PARA_S;
  AddItem( item, TVI_LAST, idx, _T("Parameters string"), 10);
  idx = (Index << 8) + TREEID_EXCEPT;
  AddItem( item, TVI_LAST, idx, _T("Exceptions"), 6);

  return item;
}

/////////////////////////////////////////////////////////////////////////////
// HTREEITEM CCTMSTreeView::AddItem( HTREEITEM hParent, HTREEITEM hInsertAfter,
//                                   int Id, LPTSTR Title)
// 
// Add item to treelist
/////////////////////////////////////////////////////////////////////////////
HTREEITEM CCTMSTreeView::AddItem( HTREEITEM hParent, HTREEITEM hInsertAfter, 
                                  int Id, LPCTSTR Title, int Image)
{

  TV_INSERTSTRUCT is = { hParent,hInsertAfter};


  //insert the subitems, first the TDI itself
  is.item.mask    = TVIF_TEXT | TVIF_IMAGE | TVIF_SELECTEDIMAGE;
  is.item.iImage  = Image++;
  is.item.iSelectedImage  = Image;
  is.item.pszText = (char *)Title;

  HTREEITEM item  = GetTreeCtrl().InsertItem( &is);
  GetTreeCtrl().SetItemData( item, Id);
  return item;
}

/////////////////////////////////////////////////////////////////////////////
// HTREEITEM CCTMSTreeView::AddTDI( HTREEITEM hParent, HTREEITEM hInsertAfter, LPTSTR Title)
// 
// Add TDI to the tree list, a TDI consist of several (child) items:
// Road View, Alarms, Cluster (which has many child items), 
/////////////////////////////////////////////////////////////////////////////
HTREEITEM CCTMSTreeView::AddTDI( HTREEITEM hParent, HTREEITEM /*hInsertAfter*/, 
                                 LPCTSTR Title, int Index)
{

  CString buf;
//  int i;


  //Add the TM
//  Index = Index << 16;
//  HTREEITEM item = AddItem( hParent, TVI_LAST, TREEID_TDI | Index, Title, 2);

  //add the child items, first overview
//  AddItem( item, TVI_LAST, TREEID_ROAD | Index, _T("Toerit"), 4);
//  AddItem( item, TVI_LAST, TREEID_ALARM | Index, _T("Alarmen"), 6);

  HTREEITEM cluster = AddItem( hParent, TVI_LAST, TREEID_TDI | Index, Title, 8);
  //add cluster numbers
//  for (i = 0; i < 48; i++)
//  {
    
    //find description for cluster
//    buf.Format( "Cluster%d", i);
//    CString temp( ((CCTMSApp *)AfxGetApp())->theINIFile.GetString( (LPCTSTR)buf, "Cluster", buf));

//    AddItem( cluster, TVI_LAST, TREEID_CLUSTER | Index | (i << 8), (LPCTSTR)temp, 0);
//  }

  return cluster;
}

/////////////////////////////////////////////////////////////////////////////
// void CCTMSTreeView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) 
// 
// 
/////////////////////////////////////////////////////////////////////////////
void CCTMSTreeView::OnSelchanged(NMHDR* pNMHDR, LRESULT* pResult) 
{
	NM_TREEVIEW* pNMTreeView = (NM_TREEVIEW*)pNMHDR;
	// TODO: Add your control notification handler code here
	CMainFrame *m = (CMainFrame *)AfxGetMainWnd();

  //find the resource integer
  int idx = GetTreeCtrl().GetItemData( pNMTreeView->itemNew.hItem);
  int id;

  switch (GetTreeCtrl().GetItemData( pNMTreeView->itemNew.hItem) & 0x00ff)
  {

    case TREEID_TM: m->ReplaceView( RUNTIME_CLASS(CTDIView), (idx >> 8) & 0x00ff); break;
//    case TREEID_ALARM: m->ReplaceView( RUNTIME_CLASS(CAEChart)); break;
//    case TREEID_TDI:     m->ReplaceView( RUNTIME_CLASS(CTDIView), (idx >> 8) & 0x00ff); break;
    case TREEID_EXCEPT: m->ReplaceView( RUNTIME_CLASS(CExceptView), (idx >> 8) & 0x00ff); break;

    case TREEID_INFO_B:
      id = ((idx >> 8) & 0x00ff) | ((INFO_BOOL <<8) & 0xff00);
      m->ReplaceView( RUNTIME_CLASS(CClusterView), id); 
      break;

    case TREEID_INFO_I:
      id = ((idx >> 8) & 0x00ff) | ((INFO_INT <<8) & 0xff00);
      m->ReplaceView( RUNTIME_CLASS(CClusterView), id); 
      break;

    case TREEID_INFO_L:
      id = ((idx >> 8) & 0x00ff) | ((INFO_LONG <<8) & 0xff00);
      m->ReplaceView( RUNTIME_CLASS(CClusterView), id); 
      break;

    case TREEID_INFO_R:
      id = ((idx >> 8) & 0x00ff) | ((INFO_REAL <<8) & 0xff00);
      m->ReplaceView( RUNTIME_CLASS(CClusterView), id); 
      break;

    case TREEID_INFO_S:
      id = ((idx >> 8) & 0x00ff) | ((INFO_STRING <<8) & 0xff00);
      m->ReplaceView( RUNTIME_CLASS(CClusterView), id); 
      break;

    case TREEID_PARA_B:
      id = ((idx >> 8) & 0x00ff) | ((PARA_BOOL <<8) & 0xff00);
      m->ReplaceView( RUNTIME_CLASS(CClusterView), id); 
      break;

    case TREEID_PARA_I:
      id = ((idx >> 8) & 0x00ff) | ((PARA_INT <<8) & 0xff00);
      m->ReplaceView( RUNTIME_CLASS(CClusterView), id); 
      break;

    case TREEID_PARA_L:
      id = ((idx >> 8) & 0x00ff) | ((PARA_LONG <<8) & 0xff00);
      m->ReplaceView( RUNTIME_CLASS(CClusterView), id); 
      break;

    case TREEID_PARA_R:
      id = ((idx >> 8) & 0x00ff) | ((PARA_REAL <<8) & 0xff00);
      m->ReplaceView( RUNTIME_CLASS(CClusterView), id); 
      break;

    case TREEID_PARA_S:
      id = ((idx >> 8) & 0x00ff) | ((PARA_STRING <<8) & 0xff00);
      m->ReplaceView( RUNTIME_CLASS(CClusterView), id); 
      break;

    case TREEID_COMMAND: 
      id = ((idx >> 8) & 0x00ff) | ((COMM_BOOL <<8) & 0xff00);
      m->ReplaceView( RUNTIME_CLASS(CClusterView), id); 
      break;

    case TREEID_STAT:
      id = ((idx >> 8) & 0x00ff) | ((STAT_BOOL <<8) & 0xff00);
      m->ReplaceView( RUNTIME_CLASS(CClusterView), id); 
      break;
    default:             m->ReplaceView( RUNTIME_CLASS(CCTMSView), idx); break;
  }

	*pResult = 0;
}

/////////////////////////////////////////////////////////////////////////////
// void CCTMSTreeView::ExpandRoot()
// 
// Expand treeview from the root-item
/////////////////////////////////////////////////////////////////////////////
void CCTMSTreeView::ExpandRoot()
{

  //just expand the root item, that's all
  //GetTreeCtrl().Expand( GetTreeCtrl().GetRootItem(), TVE_COLLAPSE);
  GetTreeCtrl().Expand( GetTreeCtrl().GetRootItem(), TVE_EXPAND);
}

/////////////////////////////////////////////////////////////////////////////
// void CCTMSTreeView::ReindexTDI(HTREEITEM hParent, int Index)
// 
// Set a new index on the specified TDI in the treeview
/////////////////////////////////////////////////////////////////////////////
void CCTMSTreeView::ReindexTDI(HTREEITEM hParent, int Index)
{


  //first the TDI itself
  int Id = (Index << 16) | TREEID_CLUSTERVIEW;
  GetTreeCtrl().SetItemData( hParent, Id);

  //now do all the cluster items
  HTREEITEM hItem = GetTreeCtrl().GetChildItem( hParent);
  int i;

  for (i = 0; i < 48; i++)
  {
    
    Id = (Index << 16) | TREEID_CLUSTER | (i << 8);
    GetTreeCtrl().SetItemData( hItem, Id);
    
    //get the next item
    hItem = GetTreeCtrl().GetNextItem( hItem, TVGN_NEXT);
  }
}

/////////////////////////////////////////////////////////////////////////////
// BOOL CCTMSTreeView::OnEraseBkgnd(CDC* pDC) 
// 
// Do not erase the background if we don't need it, this stops 'flickering'
/////////////////////////////////////////////////////////////////////////////
BOOL CCTMSTreeView::OnEraseBkgnd(CDC* pDC) 
{
	// TODO: Add your message handler code here and/or call default
    pDC = NULL;
	return FALSE;
	//return CTreeView::OnEraseBkgnd(pDC);
}

