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

/**
 * @file fugenDoc4.cpp
 * @brief クラス fugenDoc の実装。
 *
 * ハンドラー関連の実装。表示サブの一部とツールサブ。
 */
#include "stdafx.h"
#include "fugen.h"
#include "fugenDoc.h"
#include "fugenView.h"

#include "undo/GelNODisplayAction.h"
#include "undo/MultiActions.h"

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

using namespace std;

///////////////////////////////////////////////////////////////////////////////////
// Show/Hide Command

void fugenDoc::OnDisplayHide(){
	MGGelPositions gelps(current_objects());
	IAction* pAction = new CGelNoDisplayAction(this, gelps);
	pAction->Do();
}

void fugenDoc::OnUpdateDisplayHide(CCmdUI* pCmdUI){
	pCmdUI->Enable(!current_objects().empty());
}

namespace ShowHide{
	auto isHidden = [](const MGObject* obj) {return obj->no_display(); };
	auto isShown = [](const MGObject* obj) {return !obj->no_display(); };
}

void fugenDoc::OnDisplayShow(){
	MGGelPositions gelps;
	gelps.append_if(&m_group, m_group.begin(), m_group.end(), ShowHide::isHidden);

	// action 
	CGelNoDisplayAction* pAction = new CGelNoDisplayAction(this, gelps, false);
	pAction->Do();
}

void fugenDoc::OnUpdateDisplayShow(CCmdUI* pCmdUI){
	pCmdUI->Enable(!m_group.empty());
}

void fugenDoc::OnDisplayHideSwap(){
	MGGelPositions gelps_shown, gelps_hidden;
	gelps_shown.append_if(&m_group, m_group.begin(), m_group.end(), ShowHide::isShown);
	gelps_hidden.append_if(&m_group, m_group.begin(), m_group.end(), ShowHide::isHidden);

	CMultiActions* act = new CMultiActions(this);
	act->push_back(new CGelNoDisplayAction(this, gelps_hidden, false));
	act->push_back(new CGelNoDisplayAction(this, gelps_shown));
	act->Do();
}

///////////////////////////////////////////////////////////////////////////////////
// Viewing Command

// 全体表示 (すべてのビューポート)
void fugenDoc::OnZoomExtentAllView()
{
	if(m_group.empty()){
		return;
	}

	POSITION pos = GetFirstViewPosition();
	while(pos){
		fugenView* pView = dynamic_cast<fugenView*>(GetNextView(pos));
		if(!pView /* && !pView->is_standard_view()*/){
			continue;
		}

		pView->ZoomToAllExtents();
	}
}

void fugenDoc::OnUpdateZoomExtentAllView(CCmdUI* pCmdUI)
{
	pCmdUI->Enable(!m_group.empty());
}

// 選択オブジェクトの全体表示 (すべてのビューポート)
void fugenDoc::OnZoomSelectedAllView()
{
	if(current_objects().empty()){
		return;
	}

	POSITION pos = GetFirstViewPosition();
	while(pos){
		fugenView* pView = dynamic_cast<fugenView*>(GetNextView(pos));
		if(!pView /* && !pView->is_standard_view()*/){
			continue;
		}

		pView->ZoomToAllSelections();
	}
}

void fugenDoc::OnUpdateZoomSelectedAllView(CCmdUI* pCmdUI)
{
	pCmdUI->Enable(!current_objects().empty());
}

///////////////////////////////////////////////////////////////////////////////////
// Option Command

void fugenDoc::OnUpdateEvalSnapGen(CCmdUI* pCmdUI){
	pCmdUI->Enable(!m_group.empty());
}

void fugenDoc::OnUpdateTessWorld(CCmdUI* pCmdUI)
{
	// UV ビューと同じ事前条件とする。
	if(m_current_objects.size() != 1){
		pCmdUI->Enable(FALSE);
		return;
	}

	const MGGel* pGel = m_current_objects.front().top_object();
	pCmdUI->Enable(pGel && pGel->type_is(mgAll_2Manifold) && !pGel->type_is(mgAll_Plane));
}
