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

/**
 * @file LineExtend.cpp
 * @brief MGLineExtendTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "Calc/line.h"
#include "Calc/mgcalc.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "Common/CommandStateOwner.h"
#include "CurveCmd/LineExtend.h"

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

// MGLineExtendTool

MGLineExtendTool::MGLineExtendTool(fugenDoc* pDoc)
: MGLocateState(pDoc,ID_CURVE_LINE_EXTEND),
m_curve(nullptr), m_bBoth(false){
	turn_on_end();
}

MGLineExtendTool::MGLineExtendTool(MGCommandStateOwner* owner)
: MGLocateState(owner, UNLOCK_SNAP_ATTRIB),
m_curve(nullptr), m_bBoth(false){
	turn_on_end();
}

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

bool MGLineExtendTool::initiate_tool(){
	MGLocateState::initiate_tool();

	// クリアも必須
	clear_pick_object();
	return false;
}

void MGLineExtendTool::do_make_temporary_display(mgSysGL& sgl,fugenView* pView){
	// 線分リアルタイムプレビュー
	std::unique_ptr<MGCurve> spLine(create_line(cursor()));

	// 描画
	if(spLine.get()){
		MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
		spLine->drawWire(sgl);
	}
}

std::unique_ptr<MGCurve> MGLineExtendTool::create_line(const MGPosition& epos)const{
	std::unique_ptr<MGCurve> spline;
	if(m_curve){
		spline=mgcalc::create_line_by_extension(*m_curve, m_param, epos, m_bBoth);
	}
	return spline;
}

bool MGLineExtendTool::OnKeyDown(fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags){
	switch(nChar){
	case 'b':
	case 'B':
		m_bBoth = !m_bBoth;
		break;
	default:;
	}
	return MGLocateState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
}

bool MGLineExtendTool::OnLocated(const MGLocateInfo& info){
	const auto& linfos=locates();
	size_t n=linfos.size();
	if(n){

	switch(n){
	case 1:
		m_curve = dynamic_cast<const MGCurve*>(linfos.back()->object());
		if(m_curve){
			// 覚えておく。
			m_param = info.curve_parameter();
		}else{
			cancel_last_locate();
		}
		break;
	case 2:// 計算開始
		{
		std::unique_ptr<MGCurve> spLine(create_line(linfos.back()->point_world()));
		if(spLine.get()){
			add_object_to_current_group(spLine.release());
			return OnCommandEnd(1);
		}else{
			// failed
			cancel_last_locate();
		}
		}
	default:;
	}

	}else
		m_curve=nullptr;//This is necessary because of backspace possibility.

	return false;
}

void MGLineExtendTool::prompt_message() const{
	switch(locates().size()){
	case 0:
		// 既存の曲線の端点を選択する
		SetStatusMessage(IDS_PROMPT_CURVE_END);
		break;
	case 1:
		// 作成したい直線の端点をロケートする
		{
			CString strYesNo;
			strYesNo.LoadString(m_bBoth ? IDS_YES : IDS_NO);
			SetStatusMessage(IDS_PROMPT_LINE_END, strYesNo);
		}
		break;
	}
}
