/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/********************************************************************/
/**
 * @file CurveExtractCPoint.cpp
 * @brief MGCurveExtractCPointTool クラスのインプリメンテーション
 */
#include "stdafx.h"
#include "fugenDoc.h"
#include "fugenView.h"
#include "CurveCmd/CurveExtractCPoint.h"

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

// MGCurveExtractCPointTool

MGCurveExtractCPointTool::MGCurveExtractCPointTool(fugenDoc* pDoc)
	 : MGSelectState(
		 pDoc,
		 ID_CURVE_EXTRACT_POINT,
		 MGSelectState::MULTIPLE_SELECT, // multiple selection
		 mgAll_Curve), // | mgAll_FSurface
	   m_nIDS(1)
{
}

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

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

	// 選択モデルから曲線を選別
	if(current_object_is_valid(mgAll_Curve, m_curve)){
		// さらに非 NURBS 系を除外
		m_curve.remove(mgAll_Straight);
		m_curve.remove(mgAll_Ellipse);
		m_curve.remove(mgAll_SurfCurve);
		m_curve.remove(mgAll_TrimmedCurve);
		m_curve.remove(mgAll_CompositeCurve);
	}
	set_current_object(m_curve);

	if(!m_curve.empty()){
		// 計算開始
		if(!calculate()){
			return OnCommandEnd(m_nIDS);
		}
		return OnCommandEnd(1);
	}else{
		set_add_mode();
		prompt_message();
	}
	return false;
}

void MGCurveExtractCPointTool::do_make_temporary_display(mgSysGL& sgl,fugenView* pView)
{
	if(m_preview_points.empty()){
		return;
	}

	//::glPushAttrib(GL_CURRENT_BIT | GL_POINT_BIT);
	sgl.drawPoints(
		MGColor::get_instance(MGColor::SpringGreen),
		MGColor::get_instance(MGColor::White),
		m_preview_points);
	//::glPopAttrib();
}

bool MGCurveExtractCPointTool::OnKeyDown(fugenView* pView, UINT nChar, UINT nRepCnt, UINT nFlags){
	switch(nChar){
	case VK_RETURN:
		if(m_curve.empty()){
			// キャンセル
			return OnCommandEnd(m_nIDS);
		}

		// 計算開始
		if(!calculate()){
			return OnCommandEnd(m_nIDS);
		}
		return OnCommandEnd(1);
	default:
		return MGSelectState::OnKeyDown(pView, nChar, nRepCnt, nFlags);
	}
}

bool MGCurveExtractCPointTool::OnSelected(
	fugenView*,
	MGPickObjects&,
	MGPickObjects&
)
{
	// さらに非 NURBS 系を除外
	if(current_object_is_valid(mgAll_Curve, m_curve)){
		// さらに非 NURBS 系を除外
		m_curve.remove(mgAll_Straight);
		m_curve.remove(mgAll_Ellipse);
		m_curve.remove(mgAll_SurfCurve);
		m_curve.remove(mgAll_TrimmedCurve);
		m_curve.remove(mgAll_CompositeCurve);
	}
	set_current_object(m_curve);

	UpdatePreview();
	return false;
}

void MGCurveExtractCPointTool::UpdatePreview()
{
	std::vector<MGPosition> points;

	MGPickObjects::iterator cur = m_curve.begin(), last = m_curve.end();
	for(; cur != last; ++cur){
		const MGCurve* c = dynamic_cast<const MGCurve*>((*cur)->top_object());
		MGBPointSeq bp;
		if(!c->get_control_points(bp)) continue;

		int n = bp.length();
		points.reserve(n + points.size());
		while(n--){
			points.push_back(bp(n));
		}
	}
	points.swap(m_preview_points);

	draw_temporary();
}

bool MGCurveExtractCPointTool::calculate(){
	// 処理中メッセージ
	SetStatusMessage(IDS_PROMPT_COMPUTE);
	CWaitCursor wc;

	// 計算開始
	MGGelPositions gelps;
	MGPickObjects::iterator cur = m_curve.begin(), last = m_curve.end();
	for(; cur != last; ++cur){
		const MGCurve* c = dynamic_cast<const MGCurve*>((*cur)->top_object());
		MGBPointSeq bp;
		if(!c->get_control_points(bp)) continue;

		int n = bp.length();
		while(n--){
			gelps.push_back(MGGelPosition((*cur)->bottom_group(),new MGPoint(bp(n))));
		}
	}
	if(gelps.empty()){
		m_nIDS = IDS_FAIL_GENERATE_POINT;
		return false;
	}
	// ドキュメントを変更
	add_object_to_document(gelps);
	
	return true;
}

void MGCurveExtractCPointTool::prompt_message() const{
	SetStatusMessage(IDS_PROMPT_CURVE);
}
