/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/********************************************************************/
/**
 * @file RectCenter.cpp
 * @brief MGRectCenterTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "fugen.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "CurveCmd/RectCenter.h"
#include "GLInputRealDlg.h"
#include "Calc/rect.h"
#include "Calc/mgcalc.h"
#include "Common/CommandStateOwner.h"
#include "Misc/UserPreference.h"

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

// MGRectCenterTool

namespace{
	const double dRadius = 3.0;
	const double dRho    = 0.5;
	const bool   bCircle = true;
}

MGRectCenterTool::MGRectCenterTool(fugenDoc* pDoc)
: MGLocateState(pDoc,ID_CURVE_RECT_CEN_C,NO_RUBBER,POINT_IPDRAW),
m_dRadius(dRadius), m_bRound(false){
}

MGRectCenterTool::MGRectCenterTool(MGCommandStateOwner* owner)
: MGLocateState(owner,UNLOCK_SNAP_ATTRIB,NO_RUBBER,POINT_IPDRAW),
m_dRadius(dRadius), m_bRound(false){
}

MGCommandBase* MGRectCenterTool::initial_clone(fugenDoc* pDoc)const{
	return new MGRectCenterTool(pDoc);
}

bool MGRectCenterTool::initiate_tool(){
	MGLocateState::initiate_tool();
	const UserPreference& pref = UserPreference::getInstance();
	m_dRadius = pref.GetDoubleValue(upv_Curve_RectCenter_Radius);
	//m_dRho = pref.GetDoubleValue(upv_Curve_RectCenter_Rho);
	//m_bCircle = pref.GetBoolValue(upv_Curve_RectCenter_Circle);
	return false;
}

bool MGRectCenterTool::terminate_tool(bool cancel){
	UserPreference& pref = UserPreference::getInstance();
	pref.SetDoubleValue(upv_Curve_RectCenter_Radius, m_dRadius);
	//pref.SetDoubleValue(upv_Curve_RectCenter_Rho, m_dRho);
	//pref.SetBoolValue(upv_Curve_RectCenter_Circle, m_bCircle);

	return MGLocateState::terminate_tool(cancel);
}

bool MGRectCenterTool::calculate(const MGPosition& posLast){
	const LInfoVec& linfos=locates();
	if(linfos.empty()){
		m_rect.clear();
	}
	if(linfos.size() == 1){
		m_round_rect.clear();
	}
	if(linfos.size()<=0)
		return false;

	const MGPlane& plane=linfos[0]->window()->cplane().plane();
	const MGPosition& P0=linfos[0]->point_world();
	if(m_bRound){
		if(linfos.size() >= 2){
			m_round_rect.create(&m_rect,posLast);
		}else if(linfos.size() == 1){
			// round mode ではあるが、プレビュー用の絵を作る。
			m_rect.create_from_center(plane,P0,posLast);
		}

		if(!m_round_rect.valid()){
			// fail
			return false;
		}
	}else{
		m_rect.create_from_center(plane,P0,posLast);
		if(!m_rect.valid()){
			// fail
			return false;
		}
	}
	return true;
}

void MGRectCenterTool::do_make_temporary_display(mgSysGL& sgl,fugenView* pView){
	calculate(cursor());
	MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
	if(m_round_rect.valid()){
		m_round_rect.draw(sgl);
	}else if(m_rect.valid()){
		m_rect.draw(sgl);
	}
}

bool MGRectCenterTool::OnKeyDown(fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags){
	const LInfoVec& linfos=locates();
	
	switch(nChar){
	case 'r':
	case 'R':
		// round option
		if(linfos.empty() && !m_bRound){
			m_bRound = true;
		}else if(linfos.size() == 2 && m_bRound){
			// 数値入力(real)
			CString title; title.LoadString(IDS_PROMPT_CIRCLE_RADIUS);
			CGLInputRealDlg dlg(title);
			dlg.SetValue(m_dRadius);
			if(dlg.DoModal()==IDOK){
				double x = dlg.GetValue();
				if(x > 0){
					m_dRadius = x;
					m_round_rect.create(&m_rect,m_dRadius);
					if(!m_round_rect.valid()){
							return OnCommandEnd(IDS_FAIL_GENERATE_CURVE);
					}
					add_object_to_current_group(m_round_rect.release());
					return OnCommandEnd(1);
				}
			}
		}
		break;
	default:;
	}
	return MGLocateState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
}

bool MGRectCenterTool::OnLocated(const MGLocateInfo& info){
	size_t np = locates().size();
	if(np<2 || (m_bRound && np <= 2)){
		return false;
	}

	if(!calculate(locates().back()->point_world())){
		// failed
		return OnCommandEnd(IDS_FAIL_GENERATE_CURVE);
	}

	add_object_to_current_group(m_bRound ? m_round_rect.release() : m_rect.release());
	return OnCommandEnd(1);
}

void MGRectCenterTool::prompt_message() const{
	switch(locates().size()){
	case 0:
		{
			UINT nIDS = m_bRound
				? IDS_PROMPT_RECT_CENTER_NO_R : IDS_PROMPT_RECT_CENTER_R;
			SetStatusMessage(nIDS);
		}
		break;
	case 1:
		SetStatusMessage(IDS_PROMPT_RECT_CENTER_CORNER);
		break;
	case 2:
		{
			SetStatusMessage(IDS_PROMPT_RECT_ROUND, m_dRadius);
		}
		break;
	}
}
