#include "wavemodel.h"

WavePartModel::WavePartModel(QHash<int, tbWave> &mwaves, QObject *parent)    :
    QAbstractTableModel(parent), waves(mwaves)
{
    curWave = -1;
//    wavelist = waves.values();
}


int WavePartModel::rowCount(const QModelIndex &) const
{
    if (curWave==-1) return 0;
    return waves[curWave].parts.size();
}


QVariant WavePartModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || (role != Qt::DisplayRole && role != Qt::EditRole)) return QVariant();
    if (curWave==-1) return QVariant();
    if (index.row() >= waves[curWave].parts.size()) return QVariant();
    if (index.column() == 0)
        return QVariant(tr("alien %1").arg(waves[curWave].parts.at(index.row()).alienId));
    if (index.column() == 1)
        return QVariant(waves[curWave].parts.at(index.row()).count);
    return QVariant();
}


bool WavePartModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (role != Qt::EditRole) return false;
    if (curWave==-1) return false;
    if (index.row() >= waves[curWave].parts.size()) return false;
    if (index.column() == 1)
    {
        waves[curWave].parts[index.row()].count = value.toInt();
        return true;
    }
    return false;
}


//bool WaveModel::insertRows(int row, int count, const QModelIndex &parent)
//{
//        beginInsertRows(parent,row+1,row+count);
//        waves[curWave].parts.insert(row,count,tbWavePart );
//        endInsertRows();
//        return true;
//}


bool WavePartModel::removeRows(int row, int count, const QModelIndex &parent)
{
    beginRemoveRows(parent,row,row+count);
    waves[curWave].parts.remove(row,count);
    endRemoveRows();
    return true;
}


void WavePartModel::insertAlien(int alId)
{
    //qDebug() << curWave;
    if (curWave == -1) return;
    for (int i=0; i<waves[curWave].parts.size(); i++)
    {
        if (waves[curWave].parts.at(i).alienId == alId)
        {
            waves[curWave].parts[i].count++;
            emit dataChanged(index(0,0),index(rowCount()-1,1));
            return;
        }
    }
    tbWavePart p;
    p.alienId = alId;
    p.count = 1;
    beginInsertRows(QModelIndex(),rowCount(),rowCount());
    waves[curWave].parts.append(p);
    endInsertRows();
}


void WavePartModel::setCurrentWave(QModelIndex a, QModelIndex b)
{
    //qDebug() << a << b;
    if (!a.isValid())
    {
        if (rowCount()>0)
        {
            beginRemoveRows(QModelIndex(),0,rowCount()-1);
            curWave = -1;
            endRemoveRows();
            return;
        }
        curWave = -1;
        return;
    }
    int wave = a.row();
    int id = waves.values().at(wave).id;
    int lc = waves[id].parts.size();
    if (lc > rowCount()) {
        beginInsertRows(QModelIndex(),rowCount(),lc-1);
        curWave = id;
        endInsertRows();
        emit dataChanged(index(0,0),index(rowCount()-1,1));
        return;
    }
    if (lc < rowCount()) {
        beginRemoveRows(QModelIndex(),lc,rowCount()-1);
        curWave = id;
        endRemoveRows();
        emit dataChanged(index(0,0),index(rowCount()-1,1));
        return;
    }
    curWave = id;
    emit dataChanged(index(0,0),index(rowCount()-1,1));
}


//QStringList WavePartModel::waveList()
//{
//    QStringList strwavelist;
//    for(int i=0; i<wavelist.size(); i++)
//        strwavelist.append(tr("wave %1").arg(wavelist.at(i).id));
//    return strwavelist;
//}


QVariant WaveModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid() || (role != Qt::DisplayRole && role != Qt::EditRole)) return QVariant();
    if (index.row() >= values.size()) return QVariant();
    switch (index.column())
    {
    case 0:
        return QVariant(tr("wave %1").arg(values.at(index.row()).id));
    case 1:
        return QVariant(values.at(index.row()).prise);
    case 2:
        return QVariant(values.at(index.row()).timeout);
    case 3:
        return QVariant(values.at(index.row()).parts.size());
    default:
        return QVariant();
    }
    return QVariant();
}


QVariant WaveModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Vertical || (role != Qt::DisplayRole && role != Qt::EditRole)) return QVariant();
    switch (section)
    {
    case 0:
        return QVariant(tr("#"));
    case 1:
        return QVariant(tr("prise"));
    case 2:
        return QVariant(tr("timeout"));
    case 3:
        return QVariant(tr("parts"));
    default:
        return QVariant();
    }
    return QVariant();
}


QVariant WavePartModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (orientation == Qt::Vertical || (role != Qt::DisplayRole && role != Qt::EditRole)) return QVariant();
    switch (section)
    {
    case 0:
        return QVariant(tr("alien"));
    case 1:
        return QVariant(tr("count"));
    default:
        return QVariant();
    }
    return QVariant();
}


bool WaveModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    if (role != Qt::EditRole) return false;
    if (index.row() >= values.size()) return false;
    if (index.column() == 1)
    {
        waves[values.at(index.row()).id].prise = value.toInt();
        refreshData();
        return true;
    }
    if (index.column() == 2)
    {
        waves[values.at(index.row()).id].timeout = value.toInt();
        refreshData();
        return true;
    }
    return false;
}


void WaveModel::refreshData(bool inverse)
{
    if (inverse)
    {
        emit needUpdateIndex();
        waves.clear();
        for (int i=0; i<values.size(); i++)
        {
            values[i].id = i+1;
            waves.insert(values[i].id,values[i]);
        }
    } else {
        values.clear();
        values = waves.values();
    }
    emit dataChanged(index(0,0),index(rowCount()-1,columnCount()-1));
}


WaveModel::WaveModel(QHash<int, tbWave> &mwaves, QObject *parent) :
    QAbstractTableModel(parent), waves(mwaves)
{
    refreshData();
}


void WavePartModel::removeAlien(QModelIndex index)
{
    if (!index.isValid()) return;
    //    for (int i=0; i<waves[curWave].parts.size(); i++)
    //    {
    //        if (waves[curWave].parts.at(i).alienId == alId)
    //        {
    //            waves[curWave].parts[i].count++;
    //            emit dataChanged(index(0,0),index(rowCount()-1,1));
    //            return;
    //        }
    //    }
    int i = index.row();
    beginRemoveRows(QModelIndex(),i,i);
    waves[curWave].parts.remove(i);
    endRemoveRows();
}


void WavePartModel::clearAliens()
{
    if (rowCount() == 0) return;
    beginRemoveRows(QModelIndex(),0,rowCount()-1);
    waves[curWave].parts.clear();
    endRemoveRows();
}


void WaveModel::addWave(QModelIndex a)
{
    tbWave w;
    w.id = 0;
    w.prise = 0;
    w.timeout = 10;
    if (a.isValid())
    {
        beginInsertRows(QModelIndex(),a.row(),a.row());
        values.insert(a.row()+1,w);
        endInsertRows();
    } else {
        beginInsertRows(QModelIndex(),rowCount()-1,rowCount()-1);
        values.append(w);
        endInsertRows();
    }
    refreshData(true);
}


void WaveModel::copyWave(QModelIndex a)
{
    if (a.isValid())
    {
        tbWave w = values.at(a.row());
        beginInsertRows(QModelIndex(),a.row(),a.row());
        values.insert(a.row()+1,w);
        endInsertRows();
        refreshData(true);
    }
}


void WaveModel::removeWave(QModelIndex a)
{
    if (a.isValid())
    {
        beginRemoveRows(QModelIndex(),a.row(),a.row());
        values.removeAt(a.row());
        endRemoveRows();
        refreshData(true);
    }
}


void WaveModel::upWave(QModelIndex a)
{
    if (a.isValid())
    {
        if (a.row() == 0) return;
        values.move(a.row(),a.row()-1);
        refreshData(true);
    }
}


void WaveModel::downWave(QModelIndex a)
{
    if (a.isValid())
    {
        if (a.row() == rowCount()-1) return;
        values.move(a.row(),a.row()+1);
        refreshData(true);
    }
}


void WavePartModel::updateIndex()
{
    setCurrentWave(index(-1,-1));
}
