#include "stdafx.h"
#include "CircleProgress.h"
#include "shlwapi.h"

namespace ui
{

CircleProgress::CircleProgress() :
	m_bCircular(true),
	m_bClockwise(true),
	m_nCircleWidth(1),
	m_dwBackgroundColor(0),
	m_dwForegroundColor(0),
	m_dwGradientColor(0),
	m_pIndicator(nullptr)
{

}

void CircleProgress::SetAttribute(const std::wstring& srName, const std::wstring& strValue)
{
	if (srName == _T("circular")) SetCircular(strValue == _T("true"));
	else if (srName == _T("circlewidth")) SetCircleWidth(_ttoi(strValue.c_str()));
	else if (srName == _T("indicator")) SetIndicator(strValue);
	else if (srName == _T("clockwise")) SetClockwiseRotation(strValue == _T("true"));
	else if (srName == _T("bgcolor")) {
		LPCTSTR pValue = strValue.c_str();
		while (*pValue > _T('\0') && *pValue <= _T(' ')) pValue = ::CharNext(pValue);
		SetBackgroudColor(pValue);
	}
	else if (srName == _T("fgcolor")) {
		LPCTSTR pValue = strValue.c_str();
		while (*pValue > _T('\0') && *pValue <= _T(' ')) pValue = ::CharNext(pValue);
		SetForegroudColor(pValue);
	}
	else if (srName == _T("gradientcolor")) {
		LPCTSTR pValue = strValue.c_str();
		while (*pValue > _T('\0') && *pValue <= _T(' ')) pValue = ::CharNext(pValue);
		SetCircleGradientColor(pValue);
	}
	else Progress::SetAttribute(srName, strValue);
}

void CircleProgress::PaintStatusImage(IRenderContext* pRender)
{
	Progress::PaintStatusImage(pRender);
	if (m_bCircular)
	{
		//目前IRenderContext还有很多GDI+接口未实现，暂时直接用gdi+画图了
		//以后可能会调整：需实现1、DrawArc  2、Pen增加brush(渐变)入参 3、可以自由设置Graphics属性
		int direction = m_bClockwise ? 1 : -1;   //旋转方向
		int bordersize = 1;          //弧度宽度目前使用1像素

		Gdiplus::Graphics graphics(pRender->GetDC());
		graphics.SetSmoothingMode(Gdiplus::SmoothingModeAntiAlias);
		Gdiplus::Pen bgPen(m_dwBackgroundColor, m_nCircleWidth);
		// 圆形中心
		CPoint center;
		center.x = m_rcItem.left + (m_rcItem.right - m_rcItem.left) / 2;
		center.y = m_rcItem.top + (m_rcItem.bottom - m_rcItem.top) / 2;

		// 控件矩形内的最大正方形的边界
		int side = min(m_rcItem.right - m_rcItem.left, m_rcItem.bottom - m_rcItem.top);
		//UiRect rcBorder;  仍然存在UiRect 到 RectF的转换，所以直接用gdi的RectF了
		Gdiplus::RectF rcBorder;
		rcBorder.X = center.x - side / 2;
		rcBorder.Y = center.y - side / 2;
		rcBorder.Width = rcBorder.Height = side;

		Gdiplus::RectF outer = rcBorder;
		if (m_pIndicator) {
			outer.Inflate(-1.0F *m_pIndicator->GetWidth() / 2, -1.0F * m_pIndicator->GetWidth() / 2);
		}
		else
		{
			outer.Inflate(-0.5 * m_nCircleWidth, -0.5 * m_nCircleWidth);
		}
		outer.Inflate(-1, -1);


		if (m_dwGradientColor == 0)
		{
			//不使用渐变色，直接用前景色铺满
			Gdiplus::Pen fgPen(m_dwForegroundColor, m_nCircleWidth);
			graphics.DrawArc(&bgPen, outer, 270, 360);   //270从最上面开始递增，设为0的话，是最右边开始
			graphics.DrawArc(&fgPen, outer, 270, direction * 360 * (m_nValue - m_nMin) / (m_nMax - m_nMin));
		}
		else
		{
			Gdiplus::REAL factors[4] = { 0.0f, 0.4f, 0.6f, 1.0f };
			Gdiplus::REAL positions[4] = { 0.0f, 0.2f, 0.8f, 1.0f };

			Gdiplus::LinearGradientBrush lgbrush(rcBorder, m_dwForegroundColor, m_dwGradientColor, Gdiplus::LinearGradientModeVertical);
			lgbrush.SetBlend(factors, positions, 4);
			graphics.DrawArc(&bgPen, outer, 270, 360);
			Gdiplus::Pen fgPen(&lgbrush, m_nCircleWidth);
			graphics.DrawArc(&fgPen, outer, 270, direction * 360 * (m_nValue - m_nMin) / (m_nMax - m_nMin));

		}

		//画旋转指示器图标，需要用到矩阵
		if (m_pIndicator)
		{
			Gdiplus::Matrix matrix;
			matrix.RotateAt(direction * 360 * (m_nValue - m_nMin) / (m_nMax - m_nMin), Gdiplus::PointF(center.x, center.y), Gdiplus::MatrixOrderAppend);
			graphics.SetTransform(&matrix);
			Gdiplus::RectF rectf;
			rectf.X = center.x - m_pIndicator->GetWidth() / 2;
			rectf.Y = outer.Y + bordersize / 2 - m_pIndicator->GetHeight() / 2;
			rectf.Width = m_pIndicator->GetWidth();
			rectf.Height = m_pIndicator->GetHeight();
			graphics.DrawImage(m_pIndicator, rectf);
		}

	}
}

void CircleProgress::ClearImageCache()
{
	__super::ClearImageCache();
	if (m_pIndicator)
	{
		delete m_pIndicator;
		m_pIndicator = nullptr;
	}
}

void CircleProgress::SetCircular(bool bCircular /*= true*/)
{
	m_bCircular = bCircular;
	Invalidate();
}

void CircleProgress::SetClockwiseRotation(bool bClockwise /*= true*/)
{
	if (bClockwise != m_bClockwise)
	{
		m_bClockwise = bClockwise;
		if (m_pIndicator)
		{
			//已经旋转了图片，旋转到相反的方向
			m_pIndicator->RotateFlip(Gdiplus::Rotate180FlipNone);
		}

	}
}

void CircleProgress::SetCircleWidth(int nCircleWidth)
{
	m_nCircleWidth = nCircleWidth;
	Invalidate();
}


void CircleProgress::SetBackgroudColor(const std::wstring& strColor)
{
	m_dwBackgroundColor = GlobalManager::GetTextColor(strColor);
	ASSERT(m_dwBackgroundColor != 0);
	Invalidate();
}

void CircleProgress::SetForegroudColor(const std::wstring& strColor)
{
	m_dwForegroundColor = GlobalManager::GetTextColor(strColor);
	ASSERT(m_dwForegroundColor != 0);
	Invalidate();
}

void CircleProgress::SetIndicator(const std::wstring& sIndicatorImage)
{
	if (m_sIndicatorImage != sIndicatorImage)
	{
		m_sIndicatorImage = sIndicatorImage;
		if (m_pIndicator)
		{
			delete m_pIndicator;
			m_pIndicator = nullptr;
		}
		std::wstring imagepath = m_sIndicatorImage;
		if (!::PathFileExistsW(imagepath.c_str())) {
			imagepath = GlobalManager::GetResourcePath() + m_pWindow->GetWindowResourcePath() + imagepath;
		}
		if (!::PathFileExistsW(imagepath.c_str())) {
			return;
		}
		m_pIndicator = new Gdiplus::Image(imagepath.c_str());

		Gdiplus::Status state = m_pIndicator->GetLastStatus();
		if (Gdiplus::Ok == state)
		{
			// 假定图片指向上
			m_pIndicator->RotateFlip(m_bClockwise ? Gdiplus::Rotate90FlipNone : Gdiplus::Rotate270FlipNone);
			Invalidate();
		}
	}
}

void CircleProgress::SetCircleGradientColor(const std::wstring& strColor)
{
	m_dwGradientColor = GlobalManager::GetTextColor(strColor);
	ASSERT(m_dwGradientColor != 0);
	Invalidate();
}

}
