// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "../../include/pdfwindow/PDFWindow.h"
#include "../../include/pdfwindow/PWL_Wnd.h"
#include "../../include/pdfwindow/PWL_Caret.h"
#include "../../include/pdfwindow/PWL_Utils.h"

#define PWL_CARET_FLASHINTERVAL		500

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CPWL_Caret::CPWL_Caret() :
	m_bFlash(FALSE),
	m_ptHead(0,0),
	m_ptFoot(0,0),
	m_fWidth(0.4f),
	m_nDelay(0)
{
}

CPWL_Caret::~CPWL_Caret()
{
}

CFX_ByteString CPWL_Caret::GetClassName() const
{
	return "CPWL_Caret";
}

void CPWL_Caret::GetThisAppearanceStream(CFX_ByteTextBuf & sAppStream)
{
	GetCaretApp(sAppStream,CPDF_Point(0.0f,0.0f));
}

void CPWL_Caret::DrawThisAppearance(CFX_RenderDevice* pDevice, CPDF_Matrix* pUser2Device)
{
	if (IsVisible() && m_bFlash)
	{
		CPDF_Rect rcRect = GetCaretRect();
		CPDF_Rect rcClip = GetClipRect();

		CFX_PathData path;

		path.SetPointCount(2);
		
		FX_FLOAT fCaretX = rcRect.left + m_fWidth * 0.5f;
		FX_FLOAT fCaretTop = rcRect.top;
		FX_FLOAT fCaretBottom = rcRect.bottom;

		if (!rcClip.IsEmpty())
		{
			rcRect.Intersect(rcClip);
			if (!rcRect.IsEmpty())
			{
				fCaretTop = rcRect.top;
				fCaretBottom = rcRect.bottom;
				path.SetPoint(0, fCaretX, fCaretBottom, FXPT_MOVETO);
				path.SetPoint(1, fCaretX, fCaretTop, FXPT_LINETO);
			}
			else
			{
				return;
			}
		}
		else
		{
			path.SetPoint(0, fCaretX, fCaretBottom, FXPT_MOVETO);
			path.SetPoint(1, fCaretX, fCaretTop, FXPT_LINETO);
		}

		CFX_GraphStateData gsd;
		gsd.m_LineWidth = m_fWidth;

		pDevice->DrawPath(&path, pUser2Device, &gsd,0,  ArgbEncode(255,0,0,0), FXFILL_ALTERNATE);
	}
}

void CPWL_Caret::GetCaretApp(CFX_ByteTextBuf & sAppStream,const CPDF_Point & ptOffset)
{
	if (IsVisible() && m_bFlash)
	{	
		CFX_ByteTextBuf sCaret;

		CPDF_Rect rcRect = GetCaretRect();
		CPDF_Rect rcClip = GetClipRect();

		rcRect = CPWL_Utils::OffsetRect(rcRect,ptOffset.x,ptOffset.y);
		rcClip = CPWL_Utils::OffsetRect(rcClip,ptOffset.x,ptOffset.y);

		sCaret << "q\n";
		if (!rcClip.IsEmpty())
		{
			sCaret << rcClip.left << " " << rcClip.bottom + 2.5f << " " 
				<< rcClip.right - rcClip.left << " " << rcClip.top - rcClip.bottom - 4.5f << " re W n\n";
		}
		sCaret << m_fWidth << " w\n0 G\n";
		sCaret << rcRect.left + m_fWidth/2 << " " << rcRect.bottom << " m\n";
		sCaret << rcRect.left + m_fWidth/2 << " " << rcRect.top << " l S\nQ\n";	

		sAppStream << sCaret;	
	}
}

CFX_ByteString CPWL_Caret::GetCaretAppearanceStream(const CPDF_Point & ptOffset)
{
	CFX_ByteTextBuf sCaret;
	GetCaretApp(sCaret,ptOffset);
	return sCaret.GetByteString();
}

void CPWL_Caret::TimerProc()
{
	if (m_nDelay > 0)
	{
		m_nDelay--;	
	}
	else
	{
		m_bFlash = !m_bFlash;
		InvalidateRect();
	}
}

CPDF_Rect CPWL_Caret::GetCaretRect() const
{
	return CPDF_Rect(m_ptFoot.x,
			m_ptFoot.y,
			m_ptHead.x + this->m_fWidth,
			m_ptHead.y);
}

void CPWL_Caret::SetCaret(FX_BOOL bVisible, const CPDF_Point & ptHead, const CPDF_Point & ptFoot)
{
	if (bVisible)
	{	
		if (IsVisible())
		{
			if (m_ptHead.x != ptHead.x || m_ptHead.y != ptHead.y || 
					m_ptFoot.x != ptFoot.x || m_ptFoot.y != ptFoot.y)
			{
				this->m_ptHead = ptHead;
				this->m_ptFoot = ptFoot;

				m_bFlash = TRUE;
				//Move(GetCaretRect(),FALSE,TRUE);
				Move(m_rcInvalid, FALSE, TRUE);
			}
		}
		else
		{
			this->m_ptHead = ptHead;
			this->m_ptFoot = ptFoot;

			EndTimer();
			BeginTimer(PWL_CARET_FLASHINTERVAL);
			
			CPWL_Wnd::SetVisible(TRUE);
			m_bFlash = TRUE;

			//Move(GetCaretRect(),FALSE,TRUE);	
			Move(m_rcInvalid, FALSE, TRUE);
		}		
	}
	else
	{
		this->m_ptHead = CPDF_Point(0,0);
		this->m_ptFoot = CPDF_Point(0,0);

		m_bFlash = FALSE;
		if (IsVisible())
		{
			EndTimer();
			CPWL_Wnd::SetVisible(FALSE);
		}		
	}
}

void CPWL_Caret::InvalidateRect(CPDF_Rect * pRect)
{
	if (pRect)
	{
		CPDF_Rect rcRefresh = CPWL_Utils::InflateRect(*pRect,0.5f);
		rcRefresh.top += 1;
		rcRefresh.bottom -= 1;	
		
		CPWL_Wnd::InvalidateRect(&rcRefresh);
	}
	else
		CPWL_Wnd::InvalidateRect(pRect);
}

