/*============================================================================*/
/*                                                                            */
/*                            C O P Y R I G H T                               */
/*                                                                            */
/*                          (C) Copyright 2019 by                             */
/*                              Yang Guojun                                   */
/*                           All Rights Reserved                              */
/*                                                                            */
/*      The author assumes no responsibility for the use or reliability of    */
/*      his software.                                                         */
/*                                                                            */
/*============================================================================*/
////////////////////////////////////////////////////////////////////////////////
//                                  版权申明                                  //
//                         版权所有(C)2006-2019，杨国君                       //
//                                保留全部权利                                //
////////////////////////////////////////////////////////////////////////////////
/* ############################################################################################################################## */

#include "PlotDataHisto.h"
#include <windows.h>

Declare_Namespace_CChart

template<class PlotDataT>
class	CPlotDataHistoImpl : public	CPlotDataHisto
{
public:
	CPlotDataHistoImpl();
	virtual	~CPlotDataHistoImpl();
public:
	void	DrawHisto( HDC hDC, RECT plotRect, double *xRange, double *yRange );
};

template<class PlotDataT>
CPlotDataHistoImpl<PlotDataT>::CPlotDataHistoImpl()
{
	PlotDataT* pT = static_cast<PlotDataT*>(this);
}

template<class PlotDataT>
CPlotDataHistoImpl<PlotDataT>::~CPlotDataHistoImpl()
{
	PlotDataT* pT = static_cast<PlotDataT*>(this);
}

template<class PlotDataT>
void		CPlotDataHistoImpl<PlotDataT>::DrawHisto( HDC hDC, RECT plotRect, double *xRange, double *yRange )
{
	PlotDataT* pT = static_cast<PlotDataT*>(this);

	if(pT->GetDataCount()<=0)return;
	if(!pT->IsVisible())return;
		
	int			nDatas;
	double		myX, myY;
	bool		bXLog, bYLog;

	double		x1,x2, y1, y2;
	
	POINT		point;
	
	double xScale, yScale;
	POINT *myPoints;
	xScale = pT->xScale;
	yScale = pT->yScale;
	myPoints = pT->myPoints;
	
	nDatas = pT->GetDataCount();
	
	bXLog = ((CPlotImpl*)pT->GetPlot())->IsXLogarithm();
	bYLog = ((CPlotImpl*)pT->GetPlot())->IsYLogarithm();

	int plottype = pT->GetPlotType();
	int j;

	int linestyle, linesize, linecolor;
	linestyle = pT->GetPlotLineStyle();
	linesize = pT->GetPlotLineSize();
	linecolor = pT->GetPlotColor();
	HPEN hPen, hOldPen;
	hPen = CreatePen(linestyle, linesize, linecolor);
	hOldPen = (HPEN)SelectObject(hDC, hPen);

	if(m_bHisto)
	{
		switch(plottype)
		{
		case kXYPlotStepHV:
		case kXYPlotStepVH:
			for( j = 0; j < nDatas-1; j++ )
			{
				myX = pT->GetData()[j].val[0];
				if(bXLog)myX = log10(myX);
				myY = pT->GetData()[j].val[1];
				if(bYLog)myY = log10(myY);
				if(!((CPlotImpl*)pT->GetPlot())->IsXOpposite())
					point.x = (long)(plotRect.left + xScale * (myX-xRange[0]));
				else
					point.x = (long)(plotRect.right - xScale * (myX-xRange[0]));
				if(!((CPlotImpl*)pT->GetPlot())->IsYOpposite())
					point.y = (long)(plotRect.bottom - yScale * (myY-yRange[0]));
				else
					point.y = (long)(plotRect.top + yScale * (myY-yRange[0]));
				myPoints[2*j] = point;

				myX = pT->GetData()[j+1].val[0];
				if(bXLog)myX = log10(myX);
				myY = pT->GetData()[j+1].val[1];
				if(bYLog)myY = log10(myY);
				if( plottype == kXYPlotStepHV )
				{
					if(!((CPlotImpl*)pT->GetPlot())->IsXOpposite())
						point.x = (long)(plotRect.left + xScale * (myX-xRange[0]));
					else
						point.x = (long)(plotRect.right - xScale * (myX-xRange[0]));
				}
				else if( plottype == kXYPlotStepVH )
				{
					if(!((CPlotImpl*)pT->GetPlot())->IsYOpposite())
						point.y = (long)(plotRect.bottom - yScale * (myY-yRange[0]));
					else
						point.y = (long)(plotRect.top + yScale * (myY-yRange[0]));
				}
				
				//Histo mode
				switch(m_nHistoMode)
				{
				case kHistoFromBottom:
					MoveToEx(hDC, point.x, plotRect.bottom, NULL);
					LineTo(hDC, point.x, point.y);
					break;
				case kHistoFromTop:
					MoveToEx(hDC, point.x, plotRect.top, NULL);
					LineTo(hDC, point.x, point.y);
					break;
				case kHistoFromLeft:
					MoveToEx(hDC, plotRect.left, point.y, NULL);
					LineTo(hDC, point.x, point.y);
					break;
				case kHistoFromRight:
					MoveToEx(hDC, plotRect.right, point.y, NULL);
					LineTo(hDC, point.x, point.y);
					break;
				}
			}
			break;
		case kXYPlotStepHVH:
		case kXYPlotStepVHV:
			for( j = 0; j < nDatas-1; j++ )
			{
				myX = pT->GetData()[j].val[0];
				if(bXLog)myX = log10(myX);
				myY = pT->GetData()[j].val[1];
				if(bYLog)myY = log10(myY);

				if(!((CPlotImpl*)pT->GetPlot())->IsXOpposite())
					point.x = (long)(plotRect.left + xScale * (myX-xRange[0]));
				else
					point.x = (long)(plotRect.right - xScale * (myX-xRange[0]));

				if(!((CPlotImpl*)pT->GetPlot())->IsYOpposite())
					point.y = (long)(plotRect.bottom - yScale * (myY-yRange[0]));
				else
					point.y = (long)(plotRect.top + yScale * (myY-yRange[0]));

				myX = pT->GetData()[j+1].val[0];
				if(bXLog)myX = log10(myX);
				myY = pT->GetData()[j+1].val[1];
				if(bYLog)myY = log10(myY);
				if( plottype == kXYPlotStepHVH )
				{
					x1 = point.x;
					if(!((CPlotImpl*)pT->GetPlot())->IsXOpposite())
						x2 = (long)(plotRect.left + xScale * (myX-xRange[0]));
					else
						x2 = (long)(plotRect.right - xScale * (myX-xRange[0]));
					point.x = long( (x1 + x2) / 2 );
					myPoints[3*j+1] = point;

					if(!((CPlotImpl*)pT->GetPlot())->IsYOpposite())
						y2 = (long)(plotRect.bottom - yScale * (myY-yRange[0]));
					else
						y2 = (long)(plotRect.top + yScale * (myY-yRange[0]));
					point.y = long( y2 );
					myPoints[3*j+2] = point;
				}
				else if( plottype == kXYPlotStepVHV )
				{
					y1 = point.y;
					if(!((CPlotImpl*)pT->GetPlot())->IsYOpposite())
						y2 = (long)(plotRect.bottom - yScale * (myY-yRange[0]));
					else
						y2 = (long)(plotRect.top + yScale * (myY-yRange[0]));
					point.y = long( (y1 + y2) / 2 );
					myPoints[3*j+1] = point;
					if(!((CPlotImpl*)pT->GetPlot())->IsXOpposite())
						x2 = (long)(plotRect.left + xScale * (myX-xRange[0]));
					else
						x2 = (long)(plotRect.right - xScale * (myX-xRange[0]));
					point.x = long( x2 );
					myPoints[3*j+2] = point;
				}
				switch(m_nHistoMode)
				{
				case kHistoFromBottom:
					MoveToEx(hDC, point.x, plotRect.bottom, NULL);
					LineTo(hDC, point.x, point.y);
					break;
				case kHistoFromTop:
					MoveToEx(hDC, point.x, plotRect.top, NULL);
					LineTo(hDC, point.x, point.y);
					break;
				case kHistoFromLeft:
					MoveToEx(hDC, plotRect.left, point.y, NULL);
					LineTo(hDC, point.x, point.y);
					break;
				case kHistoFromRight:
					MoveToEx(hDC, plotRect.right, point.y, NULL);
					LineTo(hDC, point.x, point.y);
					break;
				}
			}
			break;

		}
	}
	hPen = (HPEN)SelectObject(hDC, hOldPen);
	DeleteObject(hPen);
}

Declare_Namespace_End

