// TimeView.cpp : implementation file
//

#include "stdafx.h"
#include "TimeView.h"

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

/////////////////////////////////////////////////////////////////////////////
// CTimeView

IMPLEMENT_DYNCREATE(CTimeView, CView)

CTimeView::CTimeView()
{
	displayMemory = new CDC;
	mode = NoTimeFromRefrence;
	//mode = AbsoluteTimeFromRefrence;
	//mode = RelitiveTimeFromRefrence;

	windowActive = False;
}

CTimeView::~CTimeView()
{
	delete displayMemory;	
}


BEGIN_MESSAGE_MAP(CTimeView, CView)
	//{{AFX_MSG_MAP(CTimeView)
	ON_WM_SIZE()
	ON_WM_CONTEXTMENU()
	ON_COMMAND(ID_TIMEVIEWOPTIONS_TIMEVIEWOPTIONS_ABSOLUTE, OnTimeviewoptionsAbsolutetime)
	ON_UPDATE_COMMAND_UI(ID_TIMEVIEWOPTIONS_TIMEVIEWOPTIONS_ABSOLUTE, OnUpdateTimeviewoptionsAbsolutetime)
	ON_UPDATE_COMMAND_UI(ID_TIMEVIEWOPTIONS_TIMEVIEWOPTIONS_REFRENCEONLY, OnUpdateTimeviewoptionsRefrenceonly)
	ON_COMMAND(ID_TIMEVIEWOPTIONS_TIMEVIEWOPTIONS_REFRENCEONLY, OnTimeviewoptionsRefrenceonly)
	ON_COMMAND(ID_TIMEVIEWOPTIONS_TIMEVIEWOPTIONS_RELITIVETOREFRENCE, OnTimeviewoptionsRelitivefromrefrenceline)
	ON_UPDATE_COMMAND_UI(ID_TIMEVIEWOPTIONS_TIMEVIEWOPTIONS_RELITIVETOREFRENCE, OnUpdateTimeviewoptionsRelitivefromrefrenceline)
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_COMMAND(ID_TIMEVIEWOPTIONS_RESETREFRENCE, OnTimeviewoptionsResetrefrence)
	ON_WM_LBUTTONUP()
	ON_WM_HSCROLL()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTimeView drawing

void CTimeView::OnDraw(CDC* pDC)
{
	CRect client_rect;
	GetClientRect(client_rect);
	CBitmap *old_bitmap;
	old_bitmap = displayMemory->SelectObject(myParent->screenBitmap);
	
	pDC->BitBlt(0,0,client_rect.right,client_rect.bottom, displayMemory, 
		myParent->timeSize.left, myParent->timeSize.top, SRCCOPY);
	
	displayMemory->SelectObject(old_bitmap);

}

/////////////////////////////////////////////////////////////////////////////
// CTimeView diagnostics

#ifdef _DEBUG
void CTimeView::AssertValid() const
{
	CView::AssertValid();
}

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

/////////////////////////////////////////////////////////////////////////////
// CTimeView message handlers

void CTimeView::OnInitialUpdate() 
{
	CView::OnInitialUpdate();

	windowActive = True;

	CClientDC client_dc(this);
	
	refrenceLinePixel = 0;
	refrenceLineTime = (refrenceLinePixel * myParent->viewedTime.pixelToTime)
		+ myParent->viewedTime.startTime;

	if(displayMemory->GetSafeHdc() == NULL)
	{
		displayMemory->CreateCompatibleDC(&client_dc);
	}
	myParent->SaveSize();
	myParent->Draw(this);

	int h_Min, h_Max;

	h_Min = 0;
	h_Max = (int)(myParent->document->lastTrace - myParent->document->firstTrace);


	//SetScrollRange(SB_HORZ, h_Min, h_Max);
	//SetScrollPos(SB_HORZ, 0);
}

void CTimeView::OnSize(UINT nType, int cx, int cy) 
{
	CView::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	if (windowActive)
	{
		myParent->SaveSize();
		myParent->SetTime();
		myParent->Draw(this);
	}

}

void CTimeView::Render(CRect /*placement*/)
{
	MY_RGB color;
	
	color.red   = 255;
	color.blue  = 255;	
	color.green = 255; 
	myParent->DrawCRect(myParent->timeSize, color);

	color.red   = 0;
	color.blue  = 0;	
	color.green = 0; 
	DrawTime(color);
}


void CTimeView::DrawTime(MY_RGB color)
{

	Time clock_tick_span = (SCALES[myParent->viewedTime.secondEnum] * 
		(Time)myParent->viewedTime.step);
	Time start_time = ((int)(myParent->viewedTime.startTime / clock_tick_span)) * clock_tick_span;
	char temp[30];
	char time[30];


	Scalar divisions_on_screen = myParent->timeSize.Width() / (Scalar)PIXELS_PER_DIVISION; 
	
	MY_RGB red;
	red.red = 255; red.blue = 0; red.green = 0;

	MY_RGB blue;
	blue.red = 0; blue.blue = 255; blue.green = 0;
	MY_RGB yellow;
	yellow.red = 255; yellow.blue = 0; yellow.green = 255;
	MY_RGB light_gray;
	light_gray.red = 192; light_gray.blue = 192; light_gray.green = 192;


	
	refrenceLineTime = myParent->viewedTime.startTime + (myParent->viewedTime.pixelToTime * refrenceLinePixel);


	// Draw selection box and start and end lines

	Time left = myParent->viewedTime.startTimeSel;
	Time right = myParent->viewedTime.endTimeSel;

	Min_Clamp(left, myParent->viewedTime.startTime);
	Max_Clamp(right, myParent->viewedTime.endTime);

	left += (myParent->viewedTime.pixelToTime * myParent->timeSize.left);
	right += (myParent->viewedTime.pixelToTime * myParent->timeSize.left);

	

	myParent->DrawBox(left, right, myParent->timeSize.Height(), 0, 0, light_gray);
	

	myParent->DrawLine(myParent->viewedTime.startTimeSel+(myParent->viewedTime.pixelToTime * myParent->timeSize.left), 
							 myParent->viewedTime.startTimeSel+(myParent->viewedTime.pixelToTime * myParent->timeSize.left),
							 myParent->timeSize.Height(), 0, 0, blue, 1);
		
	myParent->DrawLine(myParent->viewedTime.endTimeSel+(myParent->viewedTime.pixelToTime * myParent->timeSize.left), 
							 myParent->viewedTime.endTimeSel+(myParent->viewedTime.pixelToTime * myParent->timeSize.left),
							 myParent->timeSize.Height(), 0, 0, yellow, 1);
	
	



	sprintf(temp, "%8.6fs", refrenceLineTime);

	myParent->DrawTextLeft(temp, 
		myParent->viewedTime.startTime + 
		(myParent->viewedTime.pixelToTime * (myParent->timeSize.left + refrenceLinePixel)), 
		(int)(myParent->timeSize.Height() / 3), red);

	
	myParent->DrawLine(
		myParent->viewedTime.startTime + (myParent->viewedTime.pixelToTime * (myParent->timeSize.left + refrenceLinePixel)),
		myParent->viewedTime.startTime + (myParent->viewedTime.pixelToTime * (myParent->timeSize.left + refrenceLinePixel)),
		myParent->timeSize.Height(), 0, 0, red, 2);


	

	for (Time counter = start_time; counter < myParent->viewedTime.endTime; counter += clock_tick_span)
	{
		int division;
		if (counter != 0)
		{
			division =(int)(counter / clock_tick_span);
		}

		if ((division%2)== 0)
		{
			if (mode == RelitiveTimeFromRefrence)
			{
				sprintf(time, "%8.4f", (counter - refrenceLineTime) / SCALES[myParent->viewedTime.secondEnum]);
				strcpy(temp, time);
				strcat(temp, SCALES_TEXT[myParent->viewedTime.secondEnum]);
				myParent->DrawText(temp, counter + (myParent->viewedTime.pixelToTime * myParent->timeSize.left), 
					(int)(myParent->timeSize.Height() / 4) * 3, color);
			}
			else if (mode == AbsoluteTimeFromRefrence)
			{
				sprintf(time, "%8.4f", counter / SCALES[myParent->viewedTime.secondEnum]);
				strcpy(temp, time);
				strcat(temp, SCALES_TEXT[myParent->viewedTime.secondEnum]);
				myParent->DrawText(temp, counter + (myParent->viewedTime.pixelToTime * myParent->timeSize.left), 
					(int)(myParent->timeSize.Height() / 4) * 3, color);
			}
		}
		
		myParent->DrawLine(counter+(myParent->viewedTime.pixelToTime * myParent->timeSize.left), 
								 counter+(myParent->viewedTime.pixelToTime * myParent->timeSize.left),
								 myParent->timeSize.Height(), (int)(myParent->timeSize.Height() / 1.8), 0, color, 1);
		
	}
}


void CTimeView::OnContextMenu(CWnd* /*pWnd*/, CPoint point) 
{
	
	CMenu menu;
	menu.LoadMenu(IDR_TIME_MENU);
	menu.GetSubMenu(0)->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,
		point.x, point.y, this);
	
}


void CTimeView::OnTimeviewoptionsAbsolutetime() 
{
	mode = AbsoluteTimeFromRefrence;	
	myParent->Draw(myParent->timeView);
}
void CTimeView::OnTimeviewoptionsRelitivefromrefrenceline() 
{
	mode = RelitiveTimeFromRefrence;	
	myParent->Draw(myParent->timeView);
}
void CTimeView::OnTimeviewoptionsRefrenceonly() 
{
	mode = NoTimeFromRefrence;
	myParent->Draw(myParent->timeView);
}

void CTimeView::OnUpdateTimeviewoptionsAbsolutetime(CCmdUI* /*pCmdUI*/) 
{


}

void CTimeView::OnUpdateTimeviewoptionsRefrenceonly(CCmdUI* /*pCmdUI*/) 
{


}
void CTimeView::OnUpdateTimeviewoptionsRelitivefromrefrenceline(CCmdUI* /*pCmdUI*/) 
{
	

}


void CTimeView::OnMouseMove(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	CView::OnMouseMove(nFlags, point);

	if (nFlags ==	MK_LBUTTON)
	{

		refrenceLinePixel = point.x;

		myParent->Draw(myParent->timeView);
		myParent->Draw(myParent->logicView);
	}
}



void CTimeView::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	CView::OnLButtonDown(nFlags, point);
	refrenceLinePixel = point.x;

	myParent->Draw(myParent->timeView);
	myParent->Draw(myParent->logicView);
	//SetCapture();
}

void CTimeView::OnTimeviewoptionsResetrefrence() 
{
	refrenceLinePixel = 0;
	myParent->Draw(myParent->timeView);
	myParent->Draw(myParent->logicView);
}

void CTimeView::OnLButtonUp(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	
	//ReleaseCapture();
	CView::OnLButtonUp(nFlags, point);
}


void CTimeView::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* /* pScrollBar */) 
{
	// TODO: Add your message handler code here and/or call default
	
	
		int 
		old_position,
		current_position,
		temp_position;

	old_position = current_position = GetScrollPos(SB_HORZ);

	BOOL absolute = FALSE;

	switch(nSBCode)
	{
		case SB_THUMBPOSITION:
		case SB_THUMBTRACK:
			current_position = nPos;
			absolute = TRUE;
			break;

		case SB_LINELEFT:
			temp_position = 1;
			current_position -= temp_position;
			break;

		case SB_LINERIGHT:
			temp_position = 1;
			current_position += temp_position;
			break;
		
		case SB_PAGELEFT:
			temp_position = 10;
			current_position -= temp_position;
			break;
		
		case SB_PAGERIGHT:
			temp_position = 10;
			current_position += temp_position;
			break;

		case SB_RIGHT:
			temp_position = 20;
			current_position += temp_position;
			break;

		case SB_LEFT:
			temp_position = 20;
			current_position -= temp_position;
			break;

		default:
			break;
	}

	MoveTime(current_position, absolute);
	
	myParent->Draw(this);
	myParent->Draw(myParent->logicView);
}


BOOL CTimeView::Create(LPCTSTR lpszClassName, LPCTSTR lpszWindowName, DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID, CCreateContext* pContext) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	//return CWnd::Create(lpszClassName, lpszWindowName, dwStyle | WS_HSCROLL, rect, pParentWnd, nID, pContext);
	return CWnd::Create(lpszClassName, lpszWindowName, dwStyle, rect, pParentWnd, nID, pContext);
}

void CTimeView::MoveTime(int current_position, BOOL absolute)
{

	//CScrollBar *pScrollBar = GetScrollBarCtrl(SB_HORZ);
	CLabRatDoc *document = (CLabRatDoc *)GetDocument();

	int old_position = GetScrollPos(SB_HORZ);
	old_position += (int)document->firstTrace;
	current_position += (int)document->firstTrace;

	Time diffrence = (Time)old_position - (Time)current_position;
	
	if (absolute == TRUE)
	{
		myParent->viewedTime.startTime = current_position; 
	}
	else
	{
		myParent->viewedTime.startTime -= (diffrence)*(SCALES[myParent->viewedTime.secondEnum] * myParent->viewedTime.step)*0.5f;
	}

	Max_Clamp(myParent->viewedTime.startTime, document->lastTrace);
	Min_Clamp(myParent->viewedTime.startTime, document->firstTrace);

	myParent->viewedTime.endTime = ((Time)myParent->viewedTime.startTime) + (myParent->viewedTime.pixelToTime * myParent->timeSize.Width());
	Max_Clamp(myParent->viewedTime.endTime, document->lastTrace);

	SetScrollPos(SB_HORZ,(int)myParent->viewedTime.startTime - ((int)document->firstTrace));

}

