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

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

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

// MGLineVerticalTool

MGLineVerticalTool::MGLineVerticalTool(fugenDoc* pDoc)
:MGLocateState(pDoc, ID_CURVE_LINE_VERTICAL, NO_RUBBER, POINT_IPDRAW),m_bBoth(false){
}

MGLineVerticalTool::MGLineVerticalTool(MGCommandStateOwner* owner)
: MGLocateState(owner, UNLOCK_SNAP_ATTRIB,NO_RUBBER, POINT_IPDRAW),
m_bBoth(false){
}

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

bool MGLineVerticalTool::initiate_tool(){
	MGLocateState::initiate_tool();
	const UserPreference& pref = UserPreference::getInstance();
	m_bBoth = pref.GetBoolValue(upv_Curve_LineVertical_Both);
	return false;
}

bool MGLineVerticalTool::terminate_tool(bool cancel){
	UserPreference& pref = UserPreference::getInstance();
	pref.SetBoolValue(upv_Curve_LineVertical_Both, m_bBoth);
	return MGLocateState::terminate_tool(cancel);
}

void MGLineVerticalTool::do_make_temporary_display(mgSysGL& sgl,fugenView* pView){
	std::unique_ptr<MGCurve> line;
	const LInfoVec& linfos=locates();
	if(!linfos.empty()){
		const MGPosition& P0=linfos[0]->point_world();
		line = mgcalc::create_line(P0,cursor(),m_bBoth);
	}

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

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

bool MGLineVerticalTool::OnLocated(const MGLocateInfo& info){
	const LInfoVec& linfos=locates();
	size_t np=linfos.size();
	if(np==0){//==0 takes place by backspace key push down action.
		disable_AETPmode();
	}else if(np==1){
		// マウスポインタ制限
		setElevationRestrictionToProhibitUpdate(*linfos[0]);
	}
	if(np<=1){//==0 takes place by backspace key push down action.
		return false;
	}

	// 計算開始
	const MGPosition& P0=linfos[0]->point_world();
	const MGPosition& P1=linfos[1]->point_world();
	std::unique_ptr<MGCurve> line=mgcalc::create_line(P0, P1, m_bBoth);
	if(!line.get()){
		// failed
		return OnCommandEnd(IDS_FAIL_GENERATE_CURVE);
	}
	add_object_to_current_group(line.release());
	disable_AETPmode();
	return OnCommandEnd(1); // コマンド終了
}

void MGLineVerticalTool::prompt_message() const{
	switch(locates().size()){
	case 0:
		SetStatusMessage(IDS_PROMPT_LINE_START);
		break;
	case 1:
		{
			CString strYesNo;
			strYesNo.LoadString(m_bBoth ? IDS_YES : IDS_NO);
			SetStatusMessage(IDS_PROMPT_LINE_END, strYesNo);
		}
		break;
	}
}
