/*
 * tagsmodel.cpp - plugin
 * Copyright (C) 2010  Evgeny Khryukin
 *
 * 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 library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 *
 */

#include <QtGlobal>

#include "tagsmodel.h"

static const QString allTags = QObject::tr("All Tags");

TagModel::TagModel(QObject *parent)
    : QAbstractItemModel(parent)
{
    stringList.clear();
    pIndex = createIndex(0, 0, -1);
}

int TagModel::rowCount(const QModelIndex &parent) const
{
    if(parent == QModelIndex())
        return 1;
    else if(parent == createAllTagsIndex())
        return stringList.count();

    return 0;
}

QVariant TagModel::headerData(int /*section*/, Qt::Orientation /*orientation*/, int /*role*/) const
{
    return QVariant();
}

QModelIndex TagModel::index(int row, int column, const QModelIndex& parent) const
{
    if(row > stringList.size() || column != 0)
        return QModelIndex();

    if(parent == QModelIndex()) {
        if(row == 0)
            return createAllTagsIndex();
        else
            return QModelIndex();
    }
    else if(parent == createAllTagsIndex())
        return createIndex(row, column, row);

    return QModelIndex();
}

QModelIndex TagModel::parent(const QModelIndex& index) const
{
    if(!index.isValid())
        return QModelIndex();
    if(index.internalId() == (quintptr)-1)
        return QModelIndex();
    if((quintptr)index.row() == index.internalId())
        return createAllTagsIndex();
    return QModelIndex();
}


QVariant TagModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (role != Qt::DisplayRole)
        return QVariant();

    if(index.internalId() == (quintptr)-1)
        return allTags;

    if (index.row() >= stringList.size() || (quintptr)index.row() != index.internalId())
        return QVariant();

    return stringList.at(index.row());

}

void TagModel::addTag(const QString& tag_)
{
    const QString tag = tag_.toLower();
    if(stringList.contains(tag))
        return;
    beginInsertRows(createAllTagsIndex(), stringList.size(), stringList.size());
    stringList.append(tag);
    stringList.sort();
    endInsertRows();
}

void TagModel::removeTag(const QString& tag_)
{
    const QString tag = tag_.toLower();
    int i = stringList.indexOf(tag);
    if(i == -1)
        return;

    beginRemoveRows(QModelIndex(), i, i);
    stringList.removeAt(i);
    endRemoveRows();
}

void TagModel::clear()
{
    beginResetModel();
    stringList.clear();
    endResetModel();
}

QModelIndex TagModel::indexByTag(const QString& tag) const
{
    int row = stringList.indexOf(tag);
    if(row == -1)
        return QModelIndex();

    return index(row,0, createAllTagsIndex());
}

QModelIndex TagModel::createAllTagsIndex() const
{
    return pIndex;
}

QString TagModel::allTagsName()
{
    return allTags;
}




////--------NoteModel---------------------
NoteModel::NoteModel(QObject *parent) : QAbstractListModel(parent)
{
}

int NoteModel::rowCount(const QModelIndex &/*parent*/) const
{
    return notesList.count();
}

QVariant NoteModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid())
        return QVariant();

    if (index.row() >= notesList.size())
        return QVariant();

    if(role == Qt::DisplayRole){
        QDomElement note = notesList.at(index.row());
        QString textNote;
        QString tag = note.attribute("tags");
        QString text = note.firstChildElement("text").text();
        QString title = note.firstChildElement("title").text();
        if(!title.isEmpty())
            textNote += tr("Title: %1").arg(title);
        if(!tag.isEmpty())
            textNote += tr("\nTags: %1").arg(tag);
        if(!text.isEmpty())
            textNote += "\n"+text;

        return textNote.isEmpty() ? QVariant() : QVariant(textNote);
    }
    else if (role == NoteRole) {
        QDomElement note = notesList.at(index.row());
        return QVariant(note.firstChildElement("text").text());
    }
    else if(role == TagRole) {
        QDomElement note = notesList.at(index.row());
        return QVariant(note.attribute("tags"));
    }
    else if(role == TitleRole) {
        QDomElement note = notesList.at(index.row());
        return QVariant(note.firstChildElement("title").text());
    }
    else
        return QVariant();
}

void NoteModel::clear()
{
    beginResetModel();
    notesList.clear();
    endResetModel();
}

void NoteModel::editNote(const QDomElement& note, const QModelIndex &index)
{
    delNote(index);
    insertNote(note, index);
}

void NoteModel::addNote(const QDomElement& note)
{
    beginInsertRows(QModelIndex(), notesList.size(), notesList.size());
    notesList.append(note);
    endInsertRows();
}

void NoteModel::insertNote(const QDomElement& note, const QModelIndex &index)
{
    if (!index.isValid())
        return;

    beginInsertRows(QModelIndex(), index.row(), index.row());
    notesList.insert(index.row(), note);
    endInsertRows();
}

void NoteModel::delNote(const QModelIndex &index)
{
    if (!index.isValid())
        return;

    if (index.row() >= notesList.size())
        return;

    beginRemoveRows(QModelIndex(), index.row(), index.row());
    notesList.removeAt(index.row());
    endRemoveRows();
}

QList<QDomElement> NoteModel::getAllNotes() const
{
    return notesList;
}

QStringList NoteModel::getAllTags() const
{
    QStringList tagsList;
    foreach(const QDomElement& note, notesList) {
        QStringList tags = note.attribute("tags").split(" ", QString::SkipEmptyParts);
        tagsList += tags;
    }
    return tagsList;
}



/////-------------ProxyModel---------------

bool ProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &parent) const
{
    QModelIndex index = sourceModel()->index(sourceRow, 0, parent);
    QString filter = filterRegExp().pattern();
    if(allTags.contains(filter))
        return true;

    QStringList tags = index.data(NoteModel::TagRole).toString().split(" ");
    return  tags.contains(filter, Qt::CaseInsensitive);
}
