/*****************************************************************************
* Copyright (c) 1990-98 Digi International Inc., All Rights Reserved
* 
* This software contains proprietary and confidential information of Digi
* International Inc.  By accepting transfer of this copy, Recipient agrees
* to retain this software in confidence, to prevent disclosure to others,
* and to make no use of this software other than that for which it was
* delivered.  This is an unpublished copyrighted work of Digi International
* Inc.  Except as permitted by federal law, 17 USC 117, copying is strictly
* prohibited.
* 
* Restricted Rights Legend
*
* Use, duplication, or disclosure by the Government is subject to
* restrictions set forth in sub-paragraph (c)(1)(ii) of The Rights in
* Technical Data and Computer Software clause at DFARS 252.227-7031 or
* subparagraphs (c)(1) and (2) of the Commercial Computer Software -
* Restricted Rights at 48 CFR 52.227-19, as applicable.
*
* Digi International Inc. 11001 Bren Road East, Minnetonka, MN 55343
*
*****************************************************************************/


// ConstellateDoc.cpp : implementation of the CConstellateDoc class
//

#include "stdafx.h"
#include "Constellate.h"

#include "ConstellateDoc.h"
#include "OpenBoardDlg.h"

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

/////////////////////////////////////////////////////////////////////////////
// CConstellateDoc

IMPLEMENT_DYNCREATE(CConstellateDoc, CDocument)

BEGIN_MESSAGE_MAP(CConstellateDoc, CDocument)
	//{{AFX_MSG_MAP(CConstellateDoc)
	ON_COMMAND(ID_SAMPLING_START, OnSamplingStart)
	ON_COMMAND(ID_SAMPLING_STOP, OnSamplingStop)
	ON_COMMAND(ID_BOARD_OPEN, OnBoardOpen)
	ON_COMMAND(ID_VIEW_CLEAR, OnViewClear)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CConstellateDoc construction/destruction


static UINT SamplingThreadFunction(LPVOID pParam)
{
   CConstellateDoc * pDoc = (CConstellateDoc *)pParam;
   ASSERT(pDoc != NULL);

   enum
   {
      EVENT_START_SAMPLING = 0,
      EVENT_GET_SAMPLE,
      EVENT_EXIT,
      EVENT_COUNT,
   };

   CSyncObject * apEvents[EVENT_COUNT];
   apEvents[EVENT_START_SAMPLING] = &(pDoc->m_StartSamplingEvent);
   apEvents[EVENT_GET_SAMPLE] = &(pDoc->m_GetSampleEvent);
   apEvents[EVENT_EXIT] = &(pDoc->m_ExistSampleThreadEvent);

   CMultiLock Wait(apEvents, ElementCount(apEvents));
   BOOL fKeepGoing = TRUE;

   while (fKeepGoing)
   {
      DWORD adwSamples[10];
      ULONG cbSampled = 0;
      SHIM_STATUS eShimStatus = SHIM_STATUS_SUCCESS;

      if (pDoc->m_fSampling)
      {
         pDoc->m_Adapter.GetSamples(adwSamples, sizeof(adwSamples), &cbSampled,
                                    500, pDoc->m_GetSampleEvent, &eShimStatus);
      }

      switch (Wait.Lock(2000, FALSE))
      {
         case WAIT_OBJECT_0 + EVENT_START_SAMPLING:
         {
            TRACE("SamplingThreadFunction(): Just got prodded to start sampling\n");
            break;
         }
         
         case WAIT_OBJECT_0 + EVENT_GET_SAMPLE:
         {
            TRACE("SamplingThreadFunction(): Sample event triggered\n");
            TRACE("Shim status is %d\n", eShimStatus);

            if (eShimStatus == SHIM_STATUS_SUCCESS)
            {
               ASSERT(cbSampled > 0);
               ASSERT(eShimStatus == SHIM_STATUS_SUCCESS);

               int cSamples = cbSampled / sizeof(DWORD);
               for (int i = 0; i < cSamples; i++)
               {
                  TRACE("Sample %d == 0x%08x\n", i, adwSamples[i]);

                  int x = (((signed short)HIWORD(adwSamples[i])) >> 6);
                  int y = (((signed short)LOWORD(adwSamples[i])) >> 6);

                  TRACE("Plotting sample (0x%08x, 0x%08x)\n", x, y);
                  pDoc->m_bmp.PlotPoint(CPoint(x, y));
               }
            }

            break;
         }

         case WAIT_OBJECT_0 + EVENT_EXIT:
         {
            TRACE("SamplingThreadFunction(): Exit sampling thread\n");
            fKeepGoing = FALSE;
            break;
         }

         case WAIT_TIMEOUT:
         {
            TRACE("SamplingThreadFunction(): Timed out!\n");
            break;
         }

         default:
         {
            TRACE("SamplingThreadFunction(): Huh!\n");
            ASSERT(FALSE);
            break;
         }
      }
   }

   return 0;
}

CConstellateDoc::CConstellateDoc()
{
   m_fSampling = FALSE;

   m_SamplingThread = AfxBeginThread(SamplingThreadFunction, this, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
   ASSERT(m_SamplingThread != NULL);

   m_SamplingThread->m_bAutoDelete = FALSE;
   m_SamplingThread->ResumeThread();
}

CConstellateDoc::~CConstellateDoc()
{
   TRACE("Waiting for sampling thread to exit.");
   m_ExistSampleThreadEvent.SetEvent();

   DWORD dwThreadExit = 0;
   while (GetExitCodeThread(m_SamplingThread->m_hThread, &dwThreadExit) && (dwThreadExit == STILL_ACTIVE))
      TRACE(".");

   delete m_SamplingThread;
   TRACE("\n");
}

/////////////////////////////////////////////////////////////////////////////
// CConstellateDoc diagnostics

#ifdef _DEBUG
void CConstellateDoc::AssertValid() const
{
	CDocument::AssertValid();
}

void CConstellateDoc::Dump(CDumpContext& dc) const
{
	CDocument::Dump(dc);
}
#endif //_DEBUG

/////////////////////////////////////////////////////////////////////////////
// CConstellateDoc commands

void CConstellateDoc::OnSamplingStart() 
{
   TRACE("Start sampling\n");
   m_fSampling = TRUE;
   m_Adapter.StartSampling(0, 200);
   m_StartSamplingEvent.SetEvent();
}

void CConstellateDoc::OnSamplingStop() 
{
   TRACE("Stop sampling\n");
   m_Adapter.StopSampling();
   m_fSampling = FALSE;
}

void CConstellateDoc::OnBoardOpen() 
{
   COpenBoardDlg OpenBoardDlg;
   OpenBoardDlg.DoModal();

   m_Adapter.Attach("DigiDxb5");
   m_Adapter.OpenStream(CAdapter::STREAM_EQM);
}

void CConstellateDoc::OnViewClear() 
{
   TRACE("Clearing bitmap\n");
   m_bmp.Clear();
   UpdateAllViews(NULL);
}
