/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/********************************************************************/
#include "stdafx.h"
#include "Calc/groupfunc.h"
#include "fugen.h"
#include "ViewCmd/NamedViewItem.h"
#include "Undo/CameraAction.h"
#include "fugenView.h"
#include "GLNamedViewDlg.h"
#include "ViewCmd/NamedViewTool.h"

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

using namespace groupfunc;

MGNamedViewTool::MGNamedViewTool(fugenDoc* pDoc)
: MGCommandBase(pDoc, ID_VIEW_NAMED), m_pView(theApp.currentfugenView(pDoc)){
	attachModelessDialogue<CGLNamedViewDlg>(this);
}

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

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

	mgModelessDialogue* dialog = getModelessDialogPointer();
	dialog->Create(IDD_NAMED_VIEW);
	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		{
			MGNamedViewItem* item = dynamic_cast<MGNamedViewItem*>(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(MGNamedViewItem* item = dynamic_cast<MGNamedViewItem*>(node)){
				m_names->push_back(CString(item->name().getName().c_str()));
			}
		}
	};
}

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

void MGNamedViewTool::Save(const CString& strName){
	fugenDoc* pDoc = document();
	pDoc->m_group.push_back(std::unique_ptr<MGGel>(
		new MGNamedViewItem(CString(strName), *m_pView)));
	pDoc->SetModifiedFlag(); // 手動で dirty flag を変更
}

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

	MGNamedViewItem* item = static_cast<MGNamedViewItem*>(loc.pos->get());
	const MGglViewAttrib& env = item->view_env();

	CCameraAction* pAct = new CCameraAction(m_pView);
	pAct->SaveEnvParam(IAction::ACTION_UNDO);
	//env.GetEnvParam(*m_pView);
	m_pView->copy(env);
	m_pView->Invalidate(FALSE);
	pAct->Do();
	pAct->SaveEnvParam(IAction::ACTION_REDO);
}

void MGNamedViewTool::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 MGNamedViewTool::Rename(const CString& strOldName, const CString& strNewName){
	GelLocation loc = SearchGroup(document()->m_group, CompareItemName(CString(strOldName)));
	if(!loc.group){
		return;
	}

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