/***********************************************************************************

    Copyright( C) 2009 Ahmet Öztürk( aoz_2@yahoo.com)

    This file is part of Lifeograph.

    Lifeograph is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Lifeograph is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Lifeograph.  If not, see <http://www.gnu.org/licenses/>.

***********************************************************************************/


#include "undo.hpp"


using namespace LIFEO;


// UNDOABLE
Undoable::Undoable( const Glib::ustring& name, UndoableType type )
: m_name( name ), m_type( type )
{
    m_time.assign_current_time();
}

// UNDO MANAGER
// static undo manager
UndoManager *UndoManager::m = nullptr;

void
UndoManager::add_action( Undoable *action )
{
    for( int i = m_stack_redo.size()-1; i>= 0; i-- )
        delete m_stack_redo[i];

    m_stack_redo.clear();

    if(  ! m_stack_undo.empty() )
        if(  m_stack_undo.front()->can_merge( action ) )
        {
            m_stack_undo.front()->merge( action );
            delete action;
            return;
        }
    m_stack_undo.push_front( action );
}

void
UndoManager::clear()
{
    int i;
    for(  i = m_stack_undo.size()-1; i>= 0; i-- )
        delete m_stack_undo[i];

    for(  i = m_stack_redo.size()-1; i>= 0; i-- )
        delete m_stack_redo[i];

    m_stack_undo.clear();
    m_stack_redo.clear();
}

void
UndoManager::undo()
{
    if(  ! m_stack_undo.empty() )
    {
        m_freezed = true;
        m_stack_undo.front()->undo();
        m_stack_redo.push_front( m_stack_undo.front() );
        m_stack_undo.pop_front();
        m_freezed = false;
    }
}

void
UndoManager::redo()
{
    if(  ! m_stack_redo.empty() )
    {
        m_freezed = true;
        m_stack_redo.front()->redo();
        m_stack_undo.push_front( m_stack_redo.front() );
        m_stack_redo.pop_front();
        m_freezed = false;
    }
}

