/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/* ***************************************************** */
/********************************************************************/
#if !defined(MultiActions_H)
#define MultiActions_H

#if _MSC_VER >= 1000
#pragma once
#endif // _MSC_VER >= 1000

#include <vector>
#include "Undo/DocAction.h"

/// MultiActions.h: interface for the CMultiActions class.
/// It defines the following operations:
///		void Do();
///			--Notify the undo manager,
///			--Perform do operation of all the member actions.
///
///		void Undo();
///			--perform undo operation of all the member actions.
///
///		void Redo();
///			--perform redo operation of all the member actions.
class CMultiActions : public CDocAction{
public:
	/// Container requirements に関する typedef
	typedef std::vector<CDocAction*>::value_type             value_type;
	typedef std::vector<CDocAction*>::reference              reference;
	typedef std::vector<CDocAction*>::const_reference        const_reference;
	typedef std::vector<CDocAction*>::iterator               iterator;
	typedef std::vector<CDocAction*>::const_iterator         const_iterator;
	typedef std::vector<CDocAction*>::difference_type        difference_type;
	typedef std::vector<CDocAction*>::size_type              size_type;

	// Reversible container requirements に関する typedef
	typedef std::vector<CDocAction*>::reverse_iterator       reverse_iterator;
	typedef std::vector<CDocAction*>::const_reverse_iterator const_reverse_iterator;

	explicit CMultiActions(fugenDoc* aTarget=0);
	CMultiActions(fugenDoc* aTarget, /*const*/ CDocAction* action);

	///Copy constructor.
	CMultiActions(CMultiActions& mactions);

	virtual ~CMultiActions();

	///////////////operator overloaded//////////////

	const_reference operator[](size_type i)const{return m_actions[i];};
	reference       operator[](size_type i){return m_actions[i];};

	///Assignment
	CMultiActions& operator=(CMultiActions& mactions);

	//////////Member Function//////////

	std::vector<CDocAction*>& actions(){return m_actions;};

	/// Return(but does not remove) last element in the actions.
	/// If list is empty, behavior is undefined.
	const_reference back() const{return m_actions.back();};
	reference       back()      {return m_actions.back();};

	/// Return iterator at the beginning of list.
	const_iterator begin() const{return m_actions.begin();}
	iterator       begin()      {return m_actions.begin();}

	///pobjs is to control the current objects of CMultiActions.
	///Do will update pobjs instead of the document's current object.
	virtual void Do();

	///Return true (1) if there are no items in the actions,
	/// false(0) otherwise.
	bool empty() const{return m_actions.empty();};

	/// Return const_iterator at the end of actions.
	const_iterator end() const{return m_actions.end();};
	iterator       end()      {return m_actions.end();};

	///iterator erase(iterator position);
	iterator erase(iterator first, iterator last);

	/// Return(but does not remove) first element in the actions.
	/// If this vector is empty, behavior is undefined.
	const_reference front() const{return m_actions.front();};
	reference       front()      {return m_actions.front();};

	/// pop last element.
	void pop_back();

	/// push element x at the end.
	void push_back(CDocAction* x);

	//push elements in gelps at the end.
	//The ownership of CDocAction* of actions are transfered to this CMultiActions.
	//void push_back(std::vector<CDocAction*>& actions);

	/// Return reverse_iterator at the beginning of list.
	const_reverse_iterator rbegin() const{return m_actions.rbegin();};
	reverse_iterator       rbegin()      {return m_actions.rbegin();};

	virtual void Redo();

	/// Return const_reverse_iterator at the end of list.
	const_reverse_iterator rend() const{return m_actions.rend();};
	reverse_iterator       rend()      {return m_actions.rend();};

	///Resize the gelp.
	void resize(size_type n);

	///Set stack kind as undo stack.
	virtual void set_as_undo_stack();
	///Set stack kind as redo stack.
	virtual void set_as_redo_stack();

	/// Return the number of items that are in the list.
	size_type size() const{return m_actions.size();};

	virtual void Undo();

protected:
	//vector of newed CActions.
	std::vector<CDocAction*> m_actions;
};

#endif
