/*
Copyright (C) 2006 Evan Teran
                   eteran@alum.rit.edu

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 "ResultViewModel.h"
#include <QtAlgorithms>

//------------------------------------------------------------------------------
// Name: 
// Desc: 
//------------------------------------------------------------------------------
ResultViewModel::ResultViewModel(QObject *parent) : QAbstractItemModel(parent), m_UpdatesEnabled(false) {
}

//------------------------------------------------------------------------------
// Name: 
// Desc: 
//------------------------------------------------------------------------------
QVariant ResultViewModel::headerData (int section, Qt::Orientation orientation, int role) const {
	
	if(role == Qt::DisplayRole && orientation == Qt::Horizontal) {
		switch(section) {
		case 0:
			return tr("Block");
		case 1:
			return tr("Size");
		case 2:
			return tr("Type");
		case 3:
			return tr("Data");
		}	
	}
	
	return QVariant();
}

//------------------------------------------------------------------------------
// Name: data(const QModelIndex &index, int role) const
// Desc: 
//------------------------------------------------------------------------------
QVariant ResultViewModel::data(const QModelIndex &index, int role) const {

	if (!index.isValid())
		return QVariant();

	if (role != Qt::DisplayRole)
		return QVariant();
			
	const Result &result = m_Results[index.row()];

	switch(index.column()) {
	case 0:
		return QString("%1").arg(result.block, EDB_MAX_HEX, 16, QChar('0'));
	case 1:
		return QString("%1").arg(result.size, EDB_MAX_HEX, 16, QChar('0'));
	case 2:
		return result.type;
	case 3:
		return result.data;
	default:
		return QVariant();
	}
}

//------------------------------------------------------------------------------
// Name: addResult(const Result &r)
// Desc: 
//------------------------------------------------------------------------------
void ResultViewModel::addResult(const Result &r) {
	m_Results.push_back(r);
	update();
}

//------------------------------------------------------------------------------
// Name: clearResults()
// Desc: 
//------------------------------------------------------------------------------
void ResultViewModel::clearResults() {
	m_Results.clear();
	update();
}

//------------------------------------------------------------------------------
// Name: update()
// Desc: 
//------------------------------------------------------------------------------
void ResultViewModel::update() {
	if(m_UpdatesEnabled) {
		reset();
	}
}

//------------------------------------------------------------------------------
// Name: index(int row, int column, const QModelIndex &parent) const
// Desc: 
//------------------------------------------------------------------------------
QModelIndex ResultViewModel::index(int row, int column, const QModelIndex &parent) const {

	Q_UNUSED(parent);

	if(row >= m_Results.size()) {
		return QModelIndex();
	}

	if(column >= 4) {
		return QModelIndex();
	}
	
	return createIndex(row, column, const_cast<Result *>(&m_Results[row]));
}

//------------------------------------------------------------------------------
// Name: parent(const QModelIndex &index) const
// Desc: 
//------------------------------------------------------------------------------
QModelIndex ResultViewModel::parent(const QModelIndex &index) const {
	Q_UNUSED(index);
	return QModelIndex(); 
}

//------------------------------------------------------------------------------
// Name: rowCount(const QModelIndex &parent) const
// Desc: 
//------------------------------------------------------------------------------
int ResultViewModel::rowCount(const QModelIndex &parent) const {
	Q_UNUSED(parent);
	return m_Results.size();
}

//------------------------------------------------------------------------------
// Name: columnCount(const QModelIndex &parent) const
// Desc: 
//------------------------------------------------------------------------------
int ResultViewModel::columnCount(const QModelIndex &parent) const {
	Q_UNUSED(parent);
	return 4;
}

//------------------------------------------------------------------------------
// Name: sort(int column, Qt::SortOrder order)
// Desc: 
//------------------------------------------------------------------------------
void ResultViewModel::sort(int column, Qt::SortOrder order) {

	if(order == Qt::AscendingOrder) {
		switch(column) {
		case 0:
			qSort(m_Results.begin(), m_Results.end(), BlockLess);
			break;
		case 1:
			qSort(m_Results.begin(), m_Results.end(), SizeLess);
			break;
		case 2:
			qSort(m_Results.begin(), m_Results.end(), TypeLess);
			break;
		case 3:
			qSort(m_Results.begin(), m_Results.end(), DataLess);
			break;
		}
	} else {
		switch(column) {
		case 0:
			qSort(m_Results.begin(), m_Results.end(), BlockGreater);
			break;
		case 1:
			qSort(m_Results.begin(), m_Results.end(), SizeGreater);
			break;
		case 2:
			qSort(m_Results.begin(), m_Results.end(), TypeGreater);
			break;
		case 3:
			qSort(m_Results.begin(), m_Results.end(), DataGreater);
			break;
		}
	}
	
	emit dataChanged(createIndex(0, 0, 0), createIndex(-1, -1, 0));
}


void ResultViewModel::setUpdatesEnabled(bool value) {
	m_UpdatesEnabled = value;
	if(m_UpdatesEnabled) {
		update();
	}
}

bool ResultViewModel::updatesEnabled() const {
	return m_UpdatesEnabled;
}
