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

/**
 * @file ElpsFociTool.cpp
 * @brief MGElpsFociTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "mg/Transf.h"
#include "Calc/ellipse.h"
#include "Calc/mgcalc.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "Misc/UserPreference.h"
#include "Common/CommandStateOwner.h"
#include "CurveCmd/ElpsFociTool.h"

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

// MGElpsFociTool

MGElpsFociTool::MGElpsFociTool(fugenDoc* pDoc)
: MGLocateState(pDoc,ID_CURVE_ELLIPSE_FOCI,NO_RUBBER,POINT_IPDRAW),
m_bMarkFoci(false){
}

MGElpsFociTool::MGElpsFociTool(MGCommandStateOwner* owner)
: MGLocateState(owner, UNLOCK_SNAP_ATTRIB, NO_RUBBER, POINT_IPDRAW){
}

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

bool MGElpsFociTool::initiate_tool(){
	MGLocateState::initiate_tool();
	UserPreference& pref = UserPreference::getInstance();
	m_bMarkFoci = pref.GetBoolValue(upv_Curve_EllipseFoci_Mark);
	return false;
}

bool MGElpsFociTool::terminate_tool(bool cancel){
	UserPreference& pref = UserPreference::getInstance();
	pref.SetBoolValue(upv_Curve_EllipseFoci_Mark, m_bMarkFoci);
	return MGLocateState::terminate_tool(cancel);
}

void MGElpsFociTool::do_make_temporary_display(mgSysGL& sgl,fugenView* pSView){
	std::unique_ptr<MGEllipse> elps;
	const LInfoVec& linfos=locates();
	size_t np = linfos.size();	
	if(np==2){
		const MGPosition& P0=linfos[0]->point_world();
		const MGPosition& P1=linfos[1]->point_world();
		elps=mgcalc::create_ellipse(P0,P1,cursor());
	}

	if(elps.get()){
		MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
		elps->drawWire(sgl);
	}
}

bool MGElpsFociTool::OnKeyDown(fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags){
	switch(nChar){
	case 'm':
	case 'M':
		// 焦点をオブジェクトとして生成する
		if(locates().size() < 2){
			m_bMarkFoci = !m_bMarkFoci;
		}
		break;
	default:;
	}
	return MGLocateState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
}

bool MGElpsFociTool::OnLocated(const MGLocateInfo& info){
	const LInfoVec& linfos=locates();
	size_t np = linfos.size();
	if(np>=2){
		const MGPosition& P0=linfos[0]->point_world();
		const MGPosition& P1=linfos[1]->point_world();		
		const MGPosition& P2=linfos[2]->point_world();
		if((P2-P1).is_collinear(P1-P0))
			cancel_last_locate();
		else{
			// 計算開始(np>=3)
			std::unique_ptr<MGEllipse> elps=mgcalc::create_ellipse(P0,P1,P2);
			if(!elps.get()){// failed
				return OnCommandEnd(IDS_FAIL_GENERATE_CURVE);
			}

			// ドキュメントを変更
			if(m_bMarkFoci){
				std::list<MGGel*> ls;
				ls.push_back(elps.release());
				ls.push_back(new MGPoint(P0));
				ls.push_back(new MGPoint(P1));
				addGelsToCurrentGroup(ls.begin(), ls.end());
			}else{
				add_object_to_current_group(elps.release());
			}
			return OnCommandEnd(1); // コマンド終了
		}
	}
	return false;
}

void MGElpsFociTool::prompt_message() const{
	const LInfoVec& linfos=locates();
	size_t np = linfos.size();
	switch(np){
	case 0:
	case 1:
		{
			CString strYesNo;
			strYesNo.LoadString(m_bMarkFoci ? IDS_YES : IDS_NO);
			SetStatusMessage(IDS_PROMPT_ELLIPSE_FOCUS_NTH, np+1, strYesNo);
		}
		break;
	case 2:
		SetStatusMessage(IDS_PROMPT_CURVE_POINT);
		break;
	}
}
