/*********************************************************************************
NixNote - An open-source client for the Evernote service.
Copyright (C) 2013 Randy Baumgarte

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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
***********************************************************************************/

#include "tageditornewtag.h"
#include "global.h"
#include "sql/tagtable.h"

#include <QKeyEvent>
#include <QListView>
#include <QStringListModel>
#include <QApplication>
#include <QDesktopWidget>
#include <QScrollBar>
#include <QStandardItem>

extern Global global;


//****************************************************
//* Constructor
//****************************************************
TagEditorNewTag::TagEditorNewTag(QWidget *parent) :
    QLineEdit(parent)
{
    QLOG_TRACE_IN() << typeid(*this).name();
    account = 0;
    this->setCursor(Qt::PointingHandCursor);
    // Setup the note title editor
    QPalette pal;
    pal.setColor(backgroundRole(), QPalette::Base);
    setPalette(pal);

    this->setFont(global.getGuiFont(font()));

    inactiveColor = "QLineEdit {background-color: transparent; border-radius: 0px;} ";
    activeColor = "QLineEdit {border: 1px solid #808080; background-color: white; border-radius: 4px;} ";
    this->setStyleSheet(inactiveColor);

    this->setPlaceholderText(tr("Click to add tag..."));
    connect(this, SIGNAL(textChanged(QString)), this, SLOT(textModified(QString)));

//    connect(this, SIGNAL(focussed(bool)), this, SLOT(gainedFocus(bool)));
    completer = new QCompleter(this);
    //completer->popup()->setItemDelegate(new TagEditorNewTagCompleterPopupDelegate());
    connect(completer, SIGNAL(activated(QString)), this, SLOT(mouseCompleterSelection(QString)));
    loadCompleter();
    connect(this, SIGNAL(returnPressed()), this, SLOT(enterPressed()));
    hide();
    QLOG_TRACE_OUT() << typeid(*this).name();
}


void TagEditorNewTag::mouseCompleterSelection(QString value) {
    QLOG_DEBUG() << "Mouse selection completer for tag: " << value;
    QKeyEvent *event = new QKeyEvent (QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
    QCoreApplication::postEvent (this, event);
}


void TagEditorNewTag::enterPressed() {
    QLOG_DEBUG() << "Enter pressed in new tag";
    QKeyEvent *event = new QKeyEvent (QEvent::KeyPress, Qt::Key_Tab, Qt::NoModifier);
    QCoreApplication::postEvent (this, event);
}



//***********************************************************
//* Load the completer with the list of valid tag names
//***********************************************************
void TagEditorNewTag::loadCompleter() {
    QLOG_TRACE_IN() << typeid(*this).name();
    QList<int> tagList;
    TagTable tagTable(global.db);
    QStringList tagNames;
    tagTable.getAll(tagList);
    for (qint32 i=0; i<tagList.size(); i++) {
        Tag t;
        QString guid;
        tagTable.getGuid(guid, tagList[i]);
        tagTable.get(t, guid);
        QString name = t.name;
        qint32 tagAccount = tagTable.owningAccount(tagList[i]);
        if (!currentTags.contains(name) && tagAccount == account)
            tagNames << name;        
    }
    qSort(tagNames.begin(), tagNames.end(), caseInsensitiveLessThan);
    completer->setModelSorting(QCompleter::CaseInsensitivelySortedModel);
    completer->setCaseSensitivity(Qt::CaseInsensitive);
    setCompleter(completer);

    QStringListModel *model;
    model = (QStringListModel*)(completer->model());
    if(model==NULL)
        model = new QStringListModel();

    model->setStringList(tagNames);
    completer->setModel(model);
    //completer->popup()->setItemDelegate(new Tag)
    QLOG_TRACE_OUT() << typeid(*this).name();
}



//******************************************************
//* Set the color whe the editor has a good focus
//******************************************************
void TagEditorNewTag::setActiveColor() {
    QLOG_TRACE_IN() << typeid(*this).name();
    setStyleSheet(activeColor);
    QLOG_TRACE_OUT() << typeid(*this).name();
}


//*******************************************************
//* Focus event.  The editor has gained focus
//*******************************************************
void TagEditorNewTag::focusInEvent(QFocusEvent *e)
{
    QLOG_TRACE_IN() << typeid(*this).name();
    this->setCursor(Qt::ArrowCursor);
    QLineEdit::focusInEvent(e);
    setStyleSheet(activeColor);
    emit(focussed(true));
    QLOG_TRACE_OUT() << typeid(*this).name();
}


//*******************************************************
//* Focus event.  The editor has lost focus
//*******************************************************
void TagEditorNewTag::focusOutEvent(QFocusEvent *e)
{
    QLOG_TRACE_IN() << typeid(*this).name();
    this->setCursor(Qt::PointingHandCursor);
    QLineEdit::focusOutEvent(e);
    setStyleSheet(inactiveColor);
    emit(focussed(false));
    QLOG_TRACE_OUT() << typeid(*this).name();
}


//*******************************************************
//* The current text has changed
//*******************************************************
void TagEditorNewTag::textModified(QString text) {
    QLOG_TRACE_IN() << typeid(*this).name();
    if (this->hasFocus()) {
        QLOG_TRACE_OUT() << typeid(*this).name();
        return;
    }
    this->blockSignals(true);
    setText(text);
    this->blockSignals(false);
    QLOG_TRACE_OUT() << typeid(*this).name();
}


//*******************************************************
//* Get the current text.  If the text is the default
//* text, the n return an empty string.
//*******************************************************
QString TagEditorNewTag::getText() {
    QLOG_TRACE_IN() << typeid(*this).name();
    QString retval = text().trimmed();
    QLOG_TRACE_OUT() << typeid(*this).name();
    return retval;
}


//*******************************************************
//* Set the list of valid tags for the completer
//*******************************************************
void TagEditorNewTag::setTags(QStringList s) {
    QLOG_TRACE_IN() << typeid(*this).name();
    currentTags = s;
    loadCompleter();
    QLOG_TRACE_OUT() << typeid(*this).name();
}


//*******************************************************
//* Add a new tag to the completer list
//*******************************************************
void TagEditorNewTag::addTag(QString s) {
    QLOG_TRACE_IN() << typeid(*this).name();
    currentTags.append(s);
    loadCompleter();
    QLOG_TRACE_OUT() << typeid(*this).name();
}



//*******************************************************
//* Override the event loop.  If the user presses "TAB"
//* and there is a valid tag entered, we signal the parent
//* that a new tag is needed.
//*******************************************************
bool  TagEditorNewTag::event(QEvent *event)
{
    QLOG_TRACE_IN() << typeid(*this).name();
    if (event->type() == QEvent::KeyPress) {
        QKeyEvent *ke = (QKeyEvent*)event;
        if (ke->key() == Qt::Key_Tab) {
            if (getText().trimmed() != "") {
                emit(tabPressed());
                QLOG_TRACE_OUT() << typeid(*this).name();
                return true;
            }
            QLOG_TRACE_OUT() << typeid(*this).name();
            return QLineEdit::event(event);
        }
    }
    QLOG_TRACE_OUT() << typeid(*this).name();
    return QLineEdit::event(event);
}



//*******************************************************
//* Reset the tag editor to the default text
//*******************************************************
void TagEditorNewTag::resetText() {
    QLOG_TRACE_IN() << typeid(*this).name();
    blockSignals(true);
    setText("");
    blockSignals(false);
    QLOG_TRACE_OUT() << typeid(*this).name();
}


void TagEditorNewTag::notebookSelectionChanged(qint32 notebook) {
    QLOG_TRACE_IN() << typeid(*this).name();
    account = notebook;
    loadCompleter();
    QLOG_TRACE_OUT() << typeid(*this).name();
}


void TagEditorNewTag::keyPressEvent(QKeyEvent * event) {
    if (event->key() == Qt::Key_Comma)
        this->enterPressed();
    else
        QLineEdit::keyPressEvent(event);

}
