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

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

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

// MGLineTan1Tool

MGLineTan1Tool::MGLineTan1Tool(fugenDoc* pDoc)
: MGLocateState(pDoc,ID_CURVE_LINE_TANGENT1,NO_RUBBER,POINT_IPDRAW),
m_curve(nullptr), m_bBoth(false){
	// near が必須となる
	turn_on_near();
	turn_on_end();
}

MGLineTan1Tool::MGLineTan1Tool(MGCommandStateOwner* owner)
: MGLocateState(owner, UNLOCK_SNAP_ATTRIB, NO_RUBBER, POINT_IPDRAW),
m_curve(nullptr), m_bBoth(false){
	// near が必須となる
	turn_on_near();
	turn_on_end();
}

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

void MGLineTan1Tool::do_make_temporary_display(mgSysGL& sgl,fugenView* pView){
	const LInfoVec& linfos=locates();
	if(linfos.empty()){
		// 1点目入力待ち
		m_curve=nullptr;
	}else{
		// 2点目入力待ち
		const MGPosition& P0=linfos[0]->point_world();
		if(m_curve)
			m_line = mgcalc::create_tangent_line(*m_curve, m_param, cursor(), m_bBoth);
		if(m_line.get()){
			MGColor::get_instance(MGColor::SpringGreen).exec(sgl);
			m_line->drawWire(sgl);
		}
	}
}

bool MGLineTan1Tool::OnKeyDown(fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags){
	// 1点目入力待ち
	switch(nChar){
	case 'b':
	case 'B':
		m_bBoth = !m_bBoth;
		break;
	default:;
	}
	return MGLocateState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
}

bool MGLineTan1Tool::OnLocated(const MGLocateInfo& info){
	const LInfoVec& linfos=locates();
	size_t np = linfos.size();
	if(np==0){
		m_curve=nullptr;
	}else if(np==1){
		// 1点目の入力チェック
		m_curve = dynamic_cast<const MGCurve*>(info.object());
		if(m_curve){
			// 1点目は曲線上にある
			m_param = info.curve_parameter();
		}else
			cancel_last_locate();
	}else{
		// 計算開始
		const LInfoVec& linfos=locates();	
		const MGPosition& P1=linfos[1]->point_world();

		// 最終的な形状を決定して線分を生成する
		m_line = mgcalc::create_tangent_line(*m_curve, m_param, P1, m_bBoth);
	
		// ドキュメント変更
		add_object_to_current_group(m_line.release());	
		return OnCommandEnd(1);
	}
	return false;
}

void MGLineTan1Tool::prompt_message() const{
	// たまたま文字列リソースが垂線コマンドのものを流用できるので
	// 流用してしまう。
	
	UINT nIDS = 0;
	CString strYesNo; strYesNo.LoadString(m_bBoth ? IDS_YES : IDS_NO);
	if(locates().empty()){
		// 1点目入力待ち
		nIDS = IDS_PROMPT_LINE_PERP1_START_BP;		
	}else{
		// 2点目入力待ち
		nIDS = IDS_PROMPT_LINE_PERP1_END;
	}
	ASSERT(nIDS);
	SetStatusMessage(nIDS,strYesNo);
}
