#include "consoleoutmodel.h"

ConsoleOutModel::ConsoleOutModel(QWidget *parent):QAbstractListModel(parent){
    filterVerbose = false; filterInformation = false;
    filterError = false; filterFatal = false;
    this->buildDisplayList();
}

QVariant ConsoleOutModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()){
        return QVariant();
    }
    if (index.row() >= dataListDisplay.size()){
        return QVariant();
    }
    if (role == Qt::DisplayRole){
        return dataListDisplay.at(index.row());
    }
    if (role == Qt::DecorationRole){
        switch (outputTypeListDisplay.at(index.row())){
        case ConsoleOut::Verbose:
            return QIcon(":/icons/console-verbose.png");
        case ConsoleOut::Information:
            return QIcon(":/icons/console-information.png");
        case ConsoleOut::Error:
            return QIcon(":/icons/console-error.png");
        case ConsoleOut::Fatal:
            return QIcon(":/icons/console-fatal.png");
        default:
            return QVariant();
        }
    }
    return QVariant();
}

//Will never use this - in as best practise
QVariant ConsoleOutModel::headerData(int section, Qt::Orientation orientation,
                                             int role) const
{
   if (role == Qt::DisplayRole){
       return QString("Header..");
   }
   return QVariant();
}


void ConsoleOutModel::buildDisplayList(){
    dataListDisplay.clear();
    outputTypeListDisplay.clear();
    for (int i = 0; i < dataList.size(); i++){
        switch (outputTypeList.at(i)) {
        case ConsoleOut::Error:
            if (!filterError){
                    dataListDisplay << dataList.at(i);
                    outputTypeListDisplay << outputTypeList.at(i);
                }
            break;
        case ConsoleOut::Fatal:
            if (!filterFatal){
                    dataListDisplay << dataList.at(i);
                    outputTypeListDisplay << outputTypeList.at(i);
                }
            break;
        case ConsoleOut::Information:
            if (!filterInformation){
                    dataListDisplay << dataList.at(i);
                    outputTypeListDisplay << outputTypeList.at(i);
                }
            break;
        case ConsoleOut::Verbose:
            if (!filterVerbose){
                    dataListDisplay << dataList.at(i);
                    outputTypeListDisplay << outputTypeList.at(i);
                }
            break;
        //default:
            //Should cause an error..
        }
    }

}

//TODO:  This is all backwards (this=! etc), should it use remove rows? or reset model?
void ConsoleOutModel::changeFilterVerbose(bool filterVerbose){
    this->filterVerbose = !filterVerbose;
    this->buildDisplayList();
    emit dataChanged(QModelIndex(), QModelIndex());
}
void ConsoleOutModel::changefilterInformation(bool filterInformation){
    this->filterInformation = !filterInformation;
    this->buildDisplayList();
    emit dataChanged(QModelIndex(), QModelIndex());
}
void ConsoleOutModel::changeFilterError(bool filterError){
    this->filterError = !filterError;
    this->buildDisplayList();
    emit dataChanged(QModelIndex(), QModelIndex());
}
void ConsoleOutModel::changeFilterFatal(bool filterFatal){
    this->filterFatal = !filterFatal;
    this->buildDisplayList();
    emit dataChanged(QModelIndex(), QModelIndex());
}

void ConsoleOutModel::consoleVerbose(QString text){
    if(dataList.size()==0){
        beginInsertRows(QModelIndex(), 0, 0);
    }else{
        beginInsertRows(QModelIndex(), dataList.size()-1, dataList.size()-1);
    }
    dataList << text;
    outputTypeList << ConsoleOut::Verbose;
    if(!filterVerbose){
        dataListDisplay << text;
        outputTypeListDisplay << ConsoleOut::Verbose;
    }
    endInsertRows();
}
void ConsoleOutModel::consoleInformation(QString text){
    if(dataList.size()==0){
        beginInsertRows(QModelIndex(), 0, 0);
    }else{
        beginInsertRows(QModelIndex(), dataList.size()-1, dataList.size()-1);
    }
    dataList << text;
    outputTypeList << ConsoleOut::Information;
    if(!filterInformation){
        dataListDisplay << text;
        outputTypeListDisplay << ConsoleOut::Information;
    }
    endInsertRows();
}
void ConsoleOutModel::consoleError(QString text){
    if(dataList.size()==0){
        beginInsertRows(QModelIndex(), 0, 0);
    }else{
        beginInsertRows(QModelIndex(), dataList.size()-1, dataList.size()-1);
    }
    dataList << text;
    outputTypeList << ConsoleOut::Error;
    if(!filterError){
        dataListDisplay << text;
        outputTypeListDisplay << ConsoleOut::Error;
    }
    endInsertRows();
}
void ConsoleOutModel::consoleFatal(QString text){
    if(dataList.size()==0){
        beginInsertRows(QModelIndex(), 0, 0);
    }else{
        beginInsertRows(QModelIndex(), dataList.size()-1, dataList.size()-1);
    }    dataList << text;
    outputTypeList << ConsoleOut::Fatal;
    if(!filterFatal){
        dataListDisplay << text;
        outputTypeListDisplay << ConsoleOut::Fatal;
    }
    endInsertRows();
}

void ConsoleOutModel::receiveConsoleOut(QString text, ConsoleOut::OutputType type){
    switch(type){
    case ConsoleOut::Error:
        this->consoleError(text); break;
    case ConsoleOut::Fatal:
        this->consoleFatal(text); break;
    case ConsoleOut::Information:
        this->consoleInformation(text); break;
    case ConsoleOut::Verbose:
        this->consoleVerbose(text); break;
    }
}
