/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/

/**
 * @file RectCorner.cpp
 * @brief MGRectCornerTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "fugen.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "GLInputRealDlg.h"
#include "Calc/mgcalc.h"
#include "Common/CommandStateOwner.h"
#include "Misc/UserPreference.h"
#include "CurveCmd/RectCenter.h"
#include "CurveCmd/Rect3Point.h"
#include "CurveCmd/RectVertical.h"
#include "CurveCmd/RectCorner.h"

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

// MGRectCornerTool

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

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

bool MGRectCornerTool::initiate_tool(){
	MGLocateState::initiate_tool();
	const UserPreference& pref = UserPreference::getInstance();
	m_dRadius = pref.GetDoubleValue(upv_Curve_RectCorner_Radius);
	//m_dRho = pref.GetDoubleValue(upv_Curve_RectCorner_Rho);
	//m_bCircle = pref.GetBoolValue(upv_Curve_RectCorner_Circle);
	return false;
}

bool MGRectCornerTool::terminate_tool(bool cancel){
	UserPreference& pref = UserPreference::getInstance();
	pref.SetDoubleValue(upv_Curve_RectCorner_Radius, m_dRadius);
	//pref.SetDoubleValue(upv_Curve_RectCorner_Rho, m_dRho);
	//pref.SetBoolValue(upv_Curve_RectCorner_Circle, m_bCircle);

	return MGLocateState::terminate_tool(cancel);
}

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

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

		if(!m_round_rect.valid()){
			// fail
			m_nIDS = IDS_FAIL_GENERATE_CURVE;
			return false;
		}
	}else{
		m_rect.create_from_corner(plane,P0,posLast);
		if(!m_rect.valid()){
			// fail
			m_nIDS = IDS_FAIL_GENERATE_CURVE;
			return false;
		}
	}

	return true;
}

void MGRectCornerTool::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 MGRectCornerTool::OnKeyDown(fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags){
	switch(nChar){
	case 'c':
	case 'C':
		if(locates().empty()){
			// 中心指定
			set_sibling_next_command(new MGRectCenterTool(get_owner_command()));
		}
		break;
	case 'p':
	case 'P':
		// 3点指定
		set_sibling_next_command(new MGRect3PointTool(get_owner_command()));
		break;
	case 'r':
	case 'R':
		// round option
		if(locates().empty()){
			m_bRound = !m_bRound;
		}else if(locates().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(m_nIDS);
					}
					// ドキュメント変更
					add_object_to_current_group(m_bRound ? m_round_rect.release() : m_rect.release());
					return OnCommandEnd(1);
				}
			}
		}
		break;
	case 'v':
	case 'V':
		// 垂直
		set_sibling_next_command(new MGRectVerticalTool(get_owner_command()));
		break;
	default:;
	}
	return MGLocateState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
}

bool MGRectCornerTool::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(m_nIDS);
	}

	// ドキュメント変更
	add_object_to_current_group(m_bRound ? m_round_rect.release() : m_rect.release());
	return OnCommandEnd(1);
}

void MGRectCornerTool::prompt_message() const{
	switch(locates().size()){
	case 0:{
			CString strYesNo;
			strYesNo.LoadString(m_bRound ? IDS_YES : IDS_NO);
			SetStatusMessage(IDS_PROMPT_RECT_CORNER_START_R,strYesNo);
		}
		break;
	case 1:
		SetStatusMessage(IDS_PROMPT_RECT_CORNER_END);
		break;
	case 2:{
			SetStatusMessage(IDS_PROMPT_RECT_ROUND, m_dRadius);
		}
		break;
	}
}
