/***************************************************************************
 *   Project TupiTube Desk                                                 *
 *   Project Contact: info@tupitube.com                                    *
 *   Project Website: http://www.tupitube.com                              * 
 *                                                                         *
 *   Developers:                                                           *
 *   2025:                                                                 *
 *    Utopian Lab Development Team                                         *
 *   2010:                                                                 *
 *    Gustav Gonzalez                                                      *
 *   ---                                                                   *
 *   KTooN's versions:                                                     *
 *   2006:                                                                 *
 *    David Cuadrado                                                       *
 *    Jorge Cuadrado                                                       *
 *   2003:                                                                 *
 *    Fernado Roldan                                                       *
 *    Simena Dinas                                                         *
 *                                                                         *
 *   License:                                                              *
 *   This program 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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 this program.  If not, see <http://www.gnu.org/licenses/>. *
 ***************************************************************************/

#include "tactionmanager.h"

/**
 * Create an actions manager
 */
TActionManager::TActionManager(QObject *parent) : QObject(parent)
{
    setObjectName("TActionManager" + parent->objectName());
}

/**
 * Destructor
 */
TActionManager::~TActionManager()
{
}

/**
 * Inserts an action within the manager
 */
bool TActionManager::insert(QAction *action, const QString &_id, const QString &container)
{
    /*
    #ifdef TUP_DEBUG
        qDebug() << "TActionManager::insert() - _id -> " << _id;
        qDebug() << "TActionManager::insert() - container -> " << container;
    #endif
    */

    QString id = _id.toLower();
    if (id.isEmpty() || container.isEmpty())
        return false;

    QAction *a = (m_actionContainer[container])[id];
    if (a == action) {
        #ifdef TUP_DEBUG
            qDebug() << "TActionManager::insert() - Fatal Error: Cannot insert action with id -> " + id;
        #endif

        return false;
    }

    action->setParent(this);
    m_actionContainer[container].insert(id, action);

    return true;
}

/**
 * Removes an action from the manager
 */
void TActionManager::remove(QAction* action, const QString &container)
{
    delete take(action, container);
}

/**
 * Remueve una accion del manejador retornando dicha accion.
 * @param action para remover
 * @return la accion removida o cero si esta no estaba en el manejador
 */
QAction *TActionManager::take(QAction* action, const QString &container)
{
    QAction *actionItem = nullptr;
    QString id = m_actionContainer[container].key(action);

    if (! container.isEmpty()) {
        if (m_actionContainer[container].contains(id))
            actionItem = m_actionContainer[container].take(id);
    } else {
        foreach (QString key, m_actionContainer.keys()) {
            if (m_actionContainer[key].contains(id)) {
                actionItem = m_actionContainer[key].take(id);
                break;
            }
        }
    }

    if (!actionItem || actionItem != action)
        return nullptr;

    return actionItem;
}

/**
 * Busca una accion en el manejardor.
 * @param id asociado a la accion
 * @return la accion requeriada
 */
QAction *TActionManager::find(const QString &_id, const QString &container) const
{
    /*
    #ifdef TUP_DEBUG
        qDebug() << "TActionManager::find() - _id -> " << _id;
    #endif
    */

    QAction *action = nullptr;
    QString id = _id.toLower();

    if (!container.isEmpty()) {
        if (m_actionContainer[container].contains(id))
            action = m_actionContainer[container][id];
    } else {
        foreach (QString key, m_actionContainer.keys()) {
            if (m_actionContainer[key].contains(id)) {
                action =m_actionContainer[key][id];
                break;
            }
        }
    }

    if (action == nullptr) {
        #ifdef TUP_DEBUG
            qDebug() << "TActionManager::find() - Fatal Error: Returning NULL action: " << id << " in " << container;
        #endif
    }

    return action;
}

/**
 * Retorna la accion asociada a id
 * @param id 
 */
QAction *TActionManager::operator[](const QString &id) const
{
    return find(id);
}

/**
 * Retorna la accion asociada a id
 * @param id
 */
void TActionManager::enable(const QString &id, bool flag)
{
   QAction *action = find(id);
   if (action != 0)
       action->setEnabled(flag);
}

/**
 * Exec the action defined by id 
 * @param id
 */
void TActionManager::exec(const QString &id)
{
   QAction *action = find(id);
   if (action != 0) {
       action->toggle();
       action->setChecked(true);
   } 
}

QMenuBar *TActionManager::setupMenuBar(QMenuBar *menuBar, const QStringList &containers, bool clear)
{
    if (menuBar) {
        if (clear)
            menuBar->clear();
    } else {
        menuBar = new QMenuBar(0);
    }

    foreach (QString container, containers)
        menuBar->addMenu(setupMenu(0, container, clear));

    return menuBar;
}

QMenu *TActionManager::setupMenu(QMenu *menu, const QString &container, bool clear)
{
    if (!menu)
        menu = new QMenu(container);

    if (clear)
        menu->clear();

    foreach (QAction *action, m_actionContainer[container]) {
       if (action)
           menu->addAction(action);
    }

    return menu;
}

QToolBar *TActionManager::setupToolBar(QToolBar *toolBar, const QString &container, bool clear)
{
    if (!toolBar)
        toolBar = new QToolBar();

    if (clear)
        toolBar->clear();

    foreach (QAction *a, m_actionContainer[container]) {
        if (a)
            toolBar->addAction(a);
    }

    if (m_actionContainer.count() == 0)
        toolBar->hide();
     else
        toolBar->show();

    return toolBar;
}
