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

#include "stdafx.h"
#include "fugen.h"
#include "Calc/groupfunc.h"
#include "fugenView.h"
#include "ViewCmd/NamedCPlaneItem.h"
#include "ViewCmd/CPlaneUtil.h"
#include "GLNamedCPlaneDlg.h"
#include "ViewCmd/NamedCPlaneTool.h"

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

using namespace groupfunc;

MGNamedCPlaneTool::MGNamedCPlaneTool(fugenDoc* pDoc)
:MGCommandBase(pDoc, ID_CPLANE_NAMED),
 m_pView(theApp.currentfugenView(pDoc)){
	attachModelessDialogue<CGLNamedCPlaneDlg>(this);
}

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

bool MGNamedCPlaneTool::initiate_tool(){
	MGCommandBase::initiate_tool();

	mgModelessDialogue* dialog=getModelessDialogPointer();
	dialog->Create(IDD_NAMED_CPLANE);
	dialog->CenterWindow();
	dialog->ShowWindow(SW_SHOW);

	SetStatusMessage(_T(""));
	return false;
}

namespace{
	struct CompareItemName{
		CString m_name;

		CompareItemName(const CString& name)
		: m_name(name) {
		}

		bool operator()(MGGel* node) const		{
			MGNamedCPlaneItem* item = dynamic_cast<MGNamedCPlaneItem*>(node);
			if(item!=0){
				CString itemName(item->name().getName().c_str());
				return m_name.Compare(itemName) == 0;
			}
			return false;
		}
	};

	struct Collector{
		std::vector<CString>* m_names;

		Collector(std::vector<CString>* names)
		: m_names(names){
		}

		void operator()(MGGel* node)		{
			if(MGNamedCPlaneItem* item = dynamic_cast<MGNamedCPlaneItem*>(node)){
				m_names->push_back(CString(item->name().getName().c_str()));
			}
		}
	};
}

void MGNamedCPlaneTool::List(std::vector<CString>& names){
	ASSERT(names.empty());
	WalkGroup(document()->m_group, Collector(&names));
}

void MGNamedCPlaneTool::Save(const CString& strName){
	fugenDoc* pDoc = document();
	pDoc->m_group.append(
		new MGNamedCPlaneItem(CString(strName), m_pView->cplane().plane()));
	pDoc->SetModifiedFlag(); // 手動で dirty flag を変更
}

void MGNamedCPlaneTool::Restore(const CString& strName){
	GelLocation loc = SearchGroup(document()->m_group, CompareItemName(CString(strName)));
	if(!loc.group){
		return;
	}

	MGNamedCPlaneItem* item = static_cast<MGNamedCPlaneItem*>(loc.pos->get());
	const MGPlane& pl = item->plane();

	ExecPlaneAction(m_pView, pl);
	document()->SetModifiedFlag(); // 手動で dirty flag を変更
}

void MGNamedCPlaneTool::Delete(const CString& strName){
	GelLocation loc = SearchGroup(document()->m_group, CompareItemName(CString(strName)));
	if(!loc.group){
		return;
	}
	loc.group->erase(loc.pos);
	document()->SetModifiedFlag(); // 手動で dirty flag を変更
}

void MGNamedCPlaneTool::Rename(const CString& strOldName, const CString& strNewName){
	GelLocation loc = SearchGroup(document()->m_group, CompareItemName(CString(strOldName)));
	if(!loc.group){
		return;
	}

	MGNamedCPlaneItem* item = static_cast<MGNamedCPlaneItem*>(loc.pos->get());
	item->set_name(CString(strNewName));
	document()->SetModifiedFlag(); // 手動で dirty flag を変更
}

