/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/* ***************************************************** */
/********************************************************************/
/// GLANODisplayAction: interface for the CGelNoDisplayAction class.
// This class serves as MGAppearance NODisplay action
// It defines the following operations:
//
//		void Do();
//			--Notify the undo manager,
//			--Perform operation(set the object as no display or as display)
//
//		void Undo();
//			-- set the object as display or no display.
//
//		void Redo();
//			-- set the object as no display or as display.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "fugenView.h"
#include "Undo/GelNoDisplayAction.h"

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

//Dummy action.
CGelNoDisplayAction::CGelNoDisplayAction(fugenDoc *doc)
:CDocAction(doc),m_nodisplay(true),m_agelModified(doc){
}
//Add or replace action.
//When attribed_gel already have the same type attribute as attrib,
//this will replace the old MGGLAttrib.
CGelNoDisplayAction::CGelNoDisplayAction(
	fugenDoc *doc,
	const MGGelPosition& gelp,//MGObjects or MGAttribedGel to process of the following nodisplay.
	bool nodisplay //Set the gel as no display if true, as display if false.
):CDocAction(doc),m_nodisplay(nodisplay),m_agelModified(doc){
	construct(gelp);
}

CGelNoDisplayAction::CGelNoDisplayAction(
	fugenDoc *doc,
	const MGGelPositions& gelps,//MGObjects or MGGroups to process of the following nodisplay.
	bool nodisplay //Set the gel as no display if true, as display if false.
):CDocAction(doc),m_nodisplay(nodisplay),m_agelModified(doc){
	size_t n=gelps.size();
	for(size_t i=0; i<n; i++){
		construct(gelps[i]);
	}
}

CGelNoDisplayAction::~CGelNoDisplayAction(){
	//If in undo_stack(), the objects need not be deleted, since the objects are used in
	//MGAttribedObject.
}

//Construct a member from one gelp data.
void CGelNoDisplayAction::construct(const MGGelPosition& gelp){
	MGGelPositions& agels=m_agelModified.target_gels();

	const MGGroup* grpi=gelp.bottom_group();
	const MGAttribedGel* agel=gelp.leafAttribedGel();
	if(agel)
		agels.push_back(gelp);
}

void CGelNoDisplayAction::Do(){
	CDocAction::Do();

//process for MGAttribedGel.
	MGGelPositions& agels=m_agelModified.target_gels();
	do_action(m_nodisplay);
	fugenDoc& doc=*(actionTarget());
	if(m_nodisplay){
		doc.set_current_object(false);
	}else{
		doc.set_current_object(agels,false);
	}
	update_all_views(ACTION_DO);
}

void CGelNoDisplayAction::Undo(){
	MGGelPositions& agels=m_agelModified.target_gels();
	if(m_nodisplay){
		fugenDoc& doc=*(actionTarget());
		doc.set_current_object(agels,false);
	}
	do_action(!m_nodisplay);
	update_all_views(ACTION_UNDO);
	CDocAction::Undo();
}

void CGelNoDisplayAction::Redo(){
	CDocAction::Redo();
//process for MGAttribedGel.
	do_action(m_nodisplay);

	MGGelPositions& agels=m_agelModified.target_gels();
	fugenDoc& doc=*(actionTarget());
	if(m_nodisplay){
		doc.set_current_object(false);
	}else{
		doc.set_current_object(agels,false);
	}
	update_all_views(ACTION_REDO);
}

void CGelNoDisplayAction::do_action(bool nodisplay){
	fugenDoc& doc=*(actionTarget());
	MGAppearance* app;

	MGGelPositions& agels=m_agelModified.target_gels();
	size_t n=agels.size();
	for(size_t i=0; i<n; i++){
		MGGelPosition& gp=agels[i];
		MGAttribedGel* agel=static_cast<MGAttribedGel*>(gp.leafAttribedGel());
		app=agel->ensure_appearance();
		if(nodisplay){
			app->set_no_display();
		}else{
			app->set_display();
		}
	}
}

//Update the views. This will be invoked by CDocAction::update_all_views,
//when DO, Undo, or Redo operations are invoked.
void CGelNoDisplayAction::view_update(ACTION_TYPE at){
	if(((at==ACTION_DO || at==ACTION_REDO) && m_nodisplay) || (at==ACTION_UNDO && !m_nodisplay)){
		m_agelModified.delete_view();
	}else{
		m_agelModified.add_view();
	}
}
