/* -*- c++ -*- */
/*
 * Gqrx SDR: Software defined radio receiver powered by GNU Radio and Qt
 *           https://gqrx.dk/
 *
 * Copyright 2014 Stefano Leucci, Christian Lindner DL2VCL.
 *
 * Gqrx 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, or (at your option)
 * any later version.
 *
 * Gqrx 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 Gqrx; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 51 Franklin Street,
 * Boston, MA 02110-1301, USA.
 */
#include "bookmarkstaglist.h"
#include "bookmarks.h"
#include <QColorDialog>
#include <stdio.h>
#include <QMenu>
#include <QHeaderView>

BookmarksTagList::BookmarksTagList(QWidget *parent, bool bShowUntagged )
    : QTableWidget(parent)
    , m_bUpdating(false)
    , m_bShowUntagged(bShowUntagged)
{
    connect(this, SIGNAL(cellClicked(int,int)),
            this, SLOT(on_cellClicked(int,int)));

    // right click menu
    setContextMenuPolicy(Qt::CustomContextMenu);
    connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
            this, SLOT(ShowContextMenu(const QPoint&)));

    horizontalHeader()->setVisible(false);
    verticalHeader()->setVisible(false);
    setColumnCount(2);
    setColumnWidth(0, 20);
    horizontalHeader()->setStretchLastSection(true);
    setSelectionMode(QAbstractItemView::SingleSelection);
    setSelectionBehavior(QAbstractItemView::SelectRows);
    setSortingEnabled(true);
}

void BookmarksTagList::on_cellClicked(int row, int column)
{
    if(column==0)
    {
        changeColor(row, column);
    }
    if(column==1)
    {
        toggleCheckedState(row, column);
    }
}

void BookmarksTagList::changeColor(int row, int /*column*/)
{
    TagInfo::sptr info = Bookmarks::Get().findOrAddTag(item(row, 1)->text());
    QColor color = QColorDialog::getColor(info->color, this);

    if(!color.isValid())
        return;

    info->color=color;
    updateTags();
    Bookmarks::Get().save();
}

void BookmarksTagList::toggleCheckedState(int row, int column)
{
    QTableWidgetItem* p = item(row,column);
    if(p->checkState()==Qt::Unchecked)
    {
        p->setCheckState(Qt::Checked);
    }
    else
    {
        p->setCheckState(Qt::Unchecked);
    }
}

void BookmarksTagList::updateTags()
{
    m_bUpdating = true;

    // Remember which items were unchecked.
    QStringList unchecked;
    for(int i=0; i<rowCount(); i++)
    {
        if(item(i,1)->checkState()==Qt::Unchecked)
            unchecked.append(item(i,1)->text());
    }

    // Get current List of Tags.
    QList<TagInfo::sptr> newTags = Bookmarks::Get().getTagList();
    if(!m_bShowUntagged)
    {
        for(int i=0; i<newTags.size(); ++i)
        {
            TagInfo::sptr taginfo = newTags[i];
            if(taginfo->name.compare(TagInfo::strUntagged)==0)
            {
                newTags.removeAt(i);
                break;
            }
        }
    }

    // Rebuild List in GUI.
    clear();
    setSortingEnabled(false);
    setRowCount(0);
    for(int i=0; i<newTags.count(); i++)
    {
        AddTag(newTags[i]->name,
                  ( unchecked.contains(newTags[i]->name) ? Qt::Unchecked : Qt::Checked ),
                  newTags[i]->color);
    }
    setSortingEnabled(true);

    m_bUpdating = false;
}

void BookmarksTagList::setSelectedTagsAsString(const QString& strTags)
{
    QStringList list = strTags.split(",");
    int iRows = rowCount();
    for(int i=0; i<iRows; ++i)
    {
        QTableWidgetItem* pItem = item(i,1);
        QString name = pItem->text();
        bool bChecked = list.contains(name);
        pItem->setCheckState(bChecked ? Qt::Checked : Qt::Unchecked);
    }
    setSortingEnabled(true);
}

void BookmarksTagList::setSelectedTags(QList<TagInfo::sptr>& tags)
{
    int iRows = rowCount();
    for(int i=0; i<iRows; ++i)
    {
        QTableWidgetItem* pItem = item(i,1);
        QString name = pItem->text();
        bool bChecked = false;
        for(QList<TagInfo::sptr>::const_iterator it=tags.begin(), itend=tags.end(); it!=itend; ++it)
        {
            TagInfo::sptr pTag = *it;
            if(pTag->name == name) bChecked = true;
        }
        pItem->setCheckState(bChecked ? Qt::Checked : Qt::Unchecked);
    }
    setSortingEnabled(true);
}

QStringList BookmarksTagList::getSelectedTags()
{
    QStringList tags;

    int iRows = rowCount();
    for(int i=0; i<iRows; ++i)
    {
        QTableWidgetItem* pItem = item(i,1);
        if(pItem->checkState() == Qt::Checked)
        {
            tags << pItem->text();
        }
    }
    return tags;
}

void BookmarksTagList::ShowContextMenu(const QPoint& pos)
{
    QMenu* menu=new QMenu(this);

    // Rename currently does not work.
    // The problem is that after the tag name is changed in GUI
    // you can not find the right TagInfo because you dont know
    // the old tag name.
    #if 0
    // MenuItem "Rename"
    {
        QAction* actionRename = new QAction("Rename", this);
        menu->addAction(actionRename);
        connect(actionRename, SIGNAL(triggered()), this, SLOT(RenameSelectedTag()));
    }
    #endif

    // MenuItem "Create new Tag"
    {
        QAction* actionNewTag = new QAction("Create new Tag", this);
        menu->addAction(actionNewTag);
        connect(actionNewTag, SIGNAL(triggered()), this, SLOT(AddNewTag()));
    }

    // Menu "Delete Tag"
    {
        QAction* actionDeleteTag = new QAction("Delete Tag", this);
        menu->addAction(actionDeleteTag);
        connect(actionDeleteTag, SIGNAL(triggered()), this, SLOT(DeleteSelectedTag()));
    }

    // Menu "Select All"
    {
        QAction* action = new QAction("Select All", this);
        menu->addAction(action);
        connect(action, SIGNAL(triggered()), this, SLOT(SelectAll()));
    }

    // Menu "Deselect All"
    {
        QAction* action = new QAction("Deselect All", this);
        menu->addAction(action);
        connect(action, SIGNAL(triggered()), this, SLOT(DeselectAll()));
    }

    menu->popup(viewport()->mapToGlobal(pos));
}

#if 0
bool BookmarksTagList::RenameSelectedTag()
{
    QModelIndexList selected = selectionModel()->selectedRows();

    if(selected.empty())
    {
        return true;
    }

    int iRow = selected.first().row();
    QTableWidgetItem* pItem = item(iRow,1);bUpdating
    editItem(pItem);
    //Bookmarks::Get().save();

    return true;
}
#endif

void BookmarksTagList::AddNewTag()
{
    AddTag("*new*");
    scrollToBottom();
    editItem(item(rowCount()-1, 1));
}

void BookmarksTagList::AddTag(QString name, Qt::CheckState checkstate, QColor color)
{
    int i = rowCount();
    setRowCount(i+1);

    // Column 1
    QTableWidgetItem *item = new QTableWidgetItem(name);
    item->setCheckState(checkstate);
    item->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled);
    setItem(i, 1, item);

    // Column 0
    item = new QTableWidgetItem();
    item->setFlags(Qt::ItemIsEnabled);
    item->setBackground(QBrush(color));
    setItem(i, 0, item);
}

void BookmarksTagList::DeleteSelectedTag()
{
    QModelIndexList selected = selectionModel()->selectedRows();
    if(selected.empty())
    {
        return;
    }
    int iRow = selected.first().row();
    QTableWidgetItem* pItem = item(iRow,1);
    QString strTagName = pItem->text();
    DeleteTag(strTagName);
    return;
}

void BookmarksTagList::DeleteTag(const QString& name)
{
    Bookmarks::Get().removeTag(name);
    updateTags();
}

void BookmarksTagList::SelectAll()
{
    int iRows = rowCount();
    for(int i=0; i<iRows; ++i)
    {
        QTableWidgetItem* pItem = item(i,1);
        QString name = pItem->text();
        pItem->setCheckState(Qt::Checked);
    }
}

void BookmarksTagList::DeselectAll()
{
    int iRows = rowCount();
    for(int i=0; i<iRows; ++i)
    {
        QTableWidgetItem* pItem = item(i,1);
        QString name = pItem->text();
        pItem->setCheckState(Qt::Unchecked);
    }
}
