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

/**
 * @file CurveBlendTool.cpp
 * @brief MGCurveBlendTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "mg/LBRepEndC.h"
#include "Calc/curve.h"
#include "Calc/mgcalc.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "SliderDlg.h"
#include "CurveCmd/CurveBlendTool.h"

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

// MGCurveBlendTool

MGCurveBlendTool::MGCurveBlendTool(fugenDoc* pDoc)
:MGSelectState(pDoc, ID_CURVE_BLEND,
	MGSelectState::SINGLE_SELECT, // single-pick
	mgAll_Curve), m_nIDS(1), m_first(true){
	// ダイアログを準備する
	attachModelessDialogue<CSliderDlg>(this);
}

bool MGCurveBlendTool::calculate(){
	CSliderDlg& dialog = *(static_cast<CSliderDlg*>(getModelessDialogPointer()));
	dialog.UpdateData();
	m_tmp=mgcalc::blend(
		*curve1(),*curve2(),m_curve1.parameter()[0],m_curve2.parameter()[0],
		0.1*dialog.m_slider1,0.1*dialog.m_slider2);

	if(!m_tmp.get()){
		// failed.
		m_nIDS = IDS_FAIL_CURVE_BLEND;
		return false;
	}
	// ドキュメントを変更
	add_object_to_current_group(m_tmp.release());
	return true;
}

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

bool MGCurveBlendTool::initiate_tool(){
	MGSelectState::initiate_tool();

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

#define CUVATURE_DENSITY 12
void MGCurveBlendTool::do_make_temporary_display(mgSysGL& sgl,fugenView* pSView){
	CSliderDlg& dialog = *(static_cast<CSliderDlg*>(getModelessDialogPointer()));
	if(!m_curve1.is_null() && !m_curve2.is_null()){
		dialog.UpdateData();
		m_tmp=mgcalc::blend(
			*curve1(),*curve2(),
			m_curve1.parameter()[0],m_curve2.parameter()[0],
			0.1*dialog.m_slider1,
			0.1*dialog.m_slider2);
	}
	if(m_tmp.get()){
		MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
		m_tmp->drawWire(sgl);
		MGColor::get_instance(MGColor::White).exec(sgl);
		sgl.drawCurvaGraph(*m_tmp, CUVATURE_DENSITY);
		sgl.drawCurvaGraph(*curve1(), CUVATURE_DENSITY);
		sgl.drawCurvaGraph(*curve2(), CUVATURE_DENSITY);
	}
}

//Invoked when command is to terminate as a nomal end.
bool MGCurveBlendTool::OnCommandEnd(
	UINT nIDS,	//=0: erase the current message, and display no messages.
				//=1: display "xxxx" normally end.
				//otherwise: nIDS is a string id, and load the message from string table to display.
	bool erase_temporary_display
){
	if(m_curve1.is_null()||m_curve2.is_null()){
		return MGSelectState::OnCommandEnd(m_nIDS);
	}else if(!calculate()){
		return MGSelectState::OnCommandEnd(m_nIDS);
	}
	return MGSelectState::OnCommandEnd(nIDS);
}

bool MGCurveBlendTool::OnSelected(
	fugenView* pView,
	MGPickObjects& curobj,
	MGPickObjects&
){
	ASSERT(curobj.size() == 1);
	if(m_curve1.is_null()){
		// 1本目のカーブをセット
		m_curve1 = curobj.front();
		MGPosition param(1); // わかりにくいが1次元
		param(0) = curve1()->param_se(m_curve1.parameter()[0]);
		m_curve1.set_parameter(param);
		lock_so_far();
	}else if(m_curve2.is_null()){
		// 2本目のカーブをセット
		m_curve2 = curobj.front();
		MGPosition param(1); // わかりにくいが1次元
		param(0) = curve2()->param_se(m_curve2.parameter()[0]);
		m_curve2.set_parameter(param);
		lock_so_far();

		if(m_first){
			// ダイアログボックスをlaunchする
			m_first = false;
			CPoint point;
			::GetCursorPos(&point);
			point.Offset(-4, -4);
			CSliderDlg& dialog = *(static_cast<CSliderDlg*>(getModelessDialogPointer()));
			dialog.SetWindowPos(&CWnd::wndTop,point.x,point.y,0,0,SWP_NOSIZE|SWP_SHOWWINDOW);
		}
	}
	prompt_message();
	draw_temporary();
	return false;
}

void MGCurveBlendTool::prompt_message() const{
	if(m_curve1.is_null()){
		SetStatusMessage(IDS_PROMPT_CURVE_END_NTH, 1);
	}else if(m_curve2.is_null()){
		SetStatusMessage(IDS_PROMPT_CURVE_END_NTH, 2);
	}else{
		SetStatusMessage(IDS_PROMPT_MAGNITUDE);
	}
}
