/*
  Copyright 2010-2012 Grégory Soutadé
  This file is part of KissCount.
  KissCount 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 3 of the License, or
  (at your option) any later version.
  KissCount 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 KissCount.  If not, see .
*/
#include 
#include 
#include 
#include 
#include "StatsPanel.hpp"
StatsPanel::StatsPanel(KissCount* kiss, wxUI *parent, bool lowResolution) : 
    KissPanel(kiss, parent, lowResolution), _plot(0)
{
    QHBoxLayout *hbox = new QHBoxLayout();
    QVBoxLayout *vbox = new QVBoxLayout();
    _hbox2 = new QHBoxLayout();
    _vbox2 = new QVBoxLayout();
    _vbox3 = new QVBoxLayout();
    int i, nbCategories;
    User* user = _kiss->GetUser();
    std::vector::iterator accountIt;
    std::vector::iterator categoryIt;
    std::map > operations;
    std::map >::iterator it;
    QListWidgetItem* item;
    _icons[KissPanel::LOW_RES_ICON] = STATS_LOW_ICON;
    _icons[KissPanel::HIGH_RES_ICON] = STATS_ICON;
    setLayout(vbox);
    _monthFrom = new QComboBox(parent);
    for(i=0; i<12; i++)
    	_monthFrom->addItem(wxUI::months[i]);
    _yearFrom = new QComboBox(parent);
    _monthTo = new QComboBox(parent);
    for(i=0; i<12; i++)
    	_monthTo->addItem(wxUI::months[i]);
    _yearTo = new QComboBox(parent);
    operations = _kiss->GetAllOperations();
    for(i=0, it = operations.begin(); it != operations.end(); it++, i++)
    {
        _yearFrom->addItem(QString::number(it->first));
        _yearTo->addItem(QString::number(it->first));
    }
    if (i) i--;
    _yearFrom->setCurrentIndex(i);
    _yearTo->setCurrentIndex(i);
    _monthFrom->setCurrentIndex(0);
    _monthTo->setCurrentIndex(11);
    QLabel* label = new QLabel(_("From"));
    hbox->addWidget(label);
    hbox->addWidget(_monthFrom);
    hbox->addWidget(_yearFrom);
    label = new QLabel(_("To"));
    hbox->addWidget(label);
    hbox->addWidget(_monthTo);
    hbox->addWidget(_yearTo);
    connect(_yearFrom, SIGNAL(currentIndexChanged(int)), this, SLOT(OnRangeChange(int)));
    connect(_monthFrom, SIGNAL(currentIndexChanged(int)), this, SLOT(OnRangeChange(int)));
    connect(_yearTo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnRangeChange(int)));
    connect(_monthTo, SIGNAL(currentIndexChanged(int)), this, SLOT(OnRangeChange(int)));
    
    _account = new QListWidget(this);
    for(i=0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end(); accountIt++, i++)
    {
	item = new QListWidgetItem(accountIt->name, _account);
	if (accountIt->hidden)
	    item->setCheckState (Qt::Unchecked);
	else
	    item->setCheckState (Qt::Checked);
    }
    _account->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
    connect(_account, SIGNAL(itemClicked(QListWidgetItem*)), this, SLOT(OnAccountChange(QListWidgetItem*)));
    _categories = new QString[user->GetCategoriesNumber()] ;
    for(i=0, categoryIt = user->_categories.begin(); 
        categoryIt != user->_categories.end(); 
        categoryIt++, i++)
    {
        _categoriesIndexes[categoryIt->id] = i;
        _categories[i] = _(categoryIt->name.toStdString().c_str()) ;
    }
    DEFAULT_FONT(font);
    _costRepartitionBanner = new CostRepartitionBanner(_kiss, this, _categories);
    _vbox3->addWidget(_account);
    nbCategories = user->GetCategoriesNumber();
    _categoriesValues = new int[nbCategories];
    for(i=0; iaddWidget(_costRepartitionBanner);
    _vbox2->addLayout(hbox);
    _hbox2->addLayout(_vbox2);
    vbox->addLayout(_hbox2);
    _hbox2->addLayout(_vbox3);
    OnRangeChange(0);
    layout();
}
KissPanel* StatsPanel::CreatePanel()
{
    return new StatsPanel(_kiss, _wxUI, _lowResolution);
}
QString StatsPanel::GetToolTip()
{
    return _("Statistics");
}
void StatsPanel::UpdateStats(int monthFrom, int yearFrom, int monthTo, int yearTo)
{
    std::map > > accountAmounts;
    std::map categories;
    std::map tags;
    std::map > operations;
    std::vector::iterator accountIt;
    std::map::iterator categoriesIt;
    std::map >::iterator accountYearIt;
    int total;
    int account, size, i, a, b, nbDays;
    QString value, v;
    User* user = _kiss->GetUser();
    QDate date;
    bool failed;
    QVector vec;
    QStringList xlabels;
    if (_plot)
    {
	_vbox2->removeWidget(_plot);
        delete _plot;
    }
    _plot = new KDChart::Widget();
    if (monthFrom == monthTo && yearFrom == yearTo)
    {
	date.setDate(yearFrom, monthFrom+1, 1);
    	nbDays = date.daysInMonth();
    	_kiss->GetMonthStats(monthFrom, yearFrom, nbDays, &operations, &categories, &tags);
	
    	// Line on 0 all over the years
    	for (a=0; asetDataset(0, vec, "");
	i=0;
    	for (account = 0, i = 0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end(); 
    	     account++, accountIt++)
    	{
	    if (_account->item(account)->checkState() != Qt::Checked)
    		continue;
	    vec.clear();
	    for (a=0; aid][a] / 100;
	    _plot->setDataset(++i, vec, user->GetAccountName(accountIt->id));
    	}
    }
    else
    {
    	_kiss->GetStats(monthFrom, yearFrom, monthTo, yearTo, &accountAmounts, &categories, &tags);
    	// Line on 0 all over the years
	nbDays = ((yearTo - yearFrom) + 1) * 12;
	for (a=0; a<(nbDays/12); a++)
	{
	    for(b=0; b<12; b++)
	    {
		vec << 0.0;
		if (b == 0 || b == 5 || (b == 11 /*&& a == ((nbDays/12)-1))*/))
		    xlabels << wxUI::months[b] + " " + QString::number(yearFrom+a);
		else
		    xlabels << "" ;
	    }
	}
	_plot->setDataset(0, vec, "");
    	for (account = 0, i = 0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end(); 
    	     account++, accountIt++, i++)
    	{
	    if (_account->item(account)->checkState() != Qt::Checked)
    	    { 
    		i-- ; 
    		continue;
    	    }
	    vec.clear();
    	    for(a = 0, accountYearIt = accountAmounts[accountIt->id].begin();
    		accountYearIt != accountAmounts[accountIt->id].end();
    		accountYearIt++, a++)
    	    {
    		for(b = 0; b<=12; b++)
    		{
    		    if (!accountAmounts[accountIt->id][accountYearIt->first].count(b))
    		    {
    			/*
    			  If previously failed, continue to avoid to set
    			  account to 0 (only for display)
    			 */
    			if (!b || failed) continue;
    			/* 
    			   Compute cur month value (if there are operations)
    			   as next month value
    			*/
    			vec << (double) (accountAmounts[accountIt->id][accountYearIt->first][b-1] 
				+ _kiss->CalcAccountAmount(accountIt->id, b-1, accountYearIt->first, 0)) / 100;
    			failed = true;
    		    }
    		    else
    		    {
    			vec << (double) accountAmounts[accountIt->id][accountYearIt->first][b] / 100;
    			failed = false;
    		    }
    		    size++;
    		}
    	    }
	    _plot->setDataset(i+1, vec, user->GetAccountName(accountIt->id));
    	}
    }
    KDChart::CartesianAxis *xAxis = new KDChart::CartesianAxis(_plot->lineDiagram());
    KDChart::CartesianAxis *yAxis = new KDChart::CartesianAxis (_plot->lineDiagram());
    xAxis->setPosition (KDChart::CartesianAxis::Bottom);
    yAxis->setPosition (KDChart::CartesianAxis::Left);
    yAxis->setTitleText (_("Amount"));
    xAxis->setLabels(xlabels);
    xAxis->setShortLabels(xlabels);
    
    // Rotate only for months names
    if (monthFrom != monthTo || yearFrom != yearTo)
    {
	KDChart::TextAttributes axisTextAttr(xAxis->textAttributes());
	axisTextAttr.setRotation(-60);
	xAxis->setTextAttributes(axisTextAttr);
	xAxis->setTitleText (_("Months"));
    }
    else
	xAxis->setTitleText (_("Days"));
    _plot->lineDiagram()->addAxis(xAxis);
    _plot->lineDiagram()->addAxis(yAxis);
		
    _plot->addLegend(KDChart::Position::East);
    KDChart::Legend* legend = _plot->legend();
    legend->setOrientation(Qt::Vertical);
    legend->setTitleText(_("Accounts"));
    legend->setText(0, _("0 line"));
    {
	i = 1;
	for (a=0, accountIt = user->_accounts.begin(); accountIt != user->_accounts.end(); 
	     a++, accountIt++)
	{
	    if (_account->item(a)->checkState() == Qt::Checked)
		legend->setText(i++, accountIt->name);
	}
    }
    _vbox2->addWidget(_plot);
    total = 0.0;
    for(i=0, categoriesIt = categories.begin(); categoriesIt != categories.end(); categoriesIt++, i++)
    {
        _categoriesValues[_categoriesIndexes[categoriesIt->first]] = categoriesIt->second;
        total += categoriesIt->second;
    }
    _costRepartitionBanner->UpdateCosts(_categoriesValues, total);
    layout();
}
void StatsPanel::OnShow()
{
    _wxUI->setWindowTitle(_kiss->GetUser()->_name + _(" - ") + _("Statistics"));
}
void StatsPanel::OnRangeChange(int index)
{
    int monthFrom, monthTo, yearFrom, yearTo;
    
    monthFrom = _monthFrom->currentIndex();
    yearFrom = _yearFrom->currentText().toInt();
    monthTo = _monthTo->currentIndex();
    yearTo = _yearTo->currentText().toInt();
    if (yearTo < yearFrom ||
        (yearFrom == yearTo && monthFrom > monthTo))
    {
        QMessageBox::critical(0, _("Error"), _("Invalide date range"));
        return;
    }
    _costRepartitionBanner->Reset();
    UpdateStats(monthFrom, yearFrom, monthTo, yearTo);
}
void StatsPanel::OnAccountChange(QListWidgetItem* item)
{
    OnRangeChange(0);
}