/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#include <QAbstractItemView>
#include <QApplication>
#include <QBrush>
#include <QCheckBox>
#include <QColor>
#include <QDebug>
#include <QPainter>
#include <QStringList>
#include <QStylePainter>

#include "MvQCheckBoxCombo.h"


MvQCheckBoxComboDelegate::MvQCheckBoxComboDelegate(QWidget *parent) : QStyledItemDelegate(parent)
{
}

void MvQCheckBoxComboDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
                          const QModelIndex &index) const
{
	if(option.state & QStyle::State_Selected)
            	painter->fillRect(option.rect, option.palette.highlight());

	//Get item status
       	bool status = index.data(Qt::UserRole).toBool();

	//Get item label
        QString text = index.data(Qt::DisplayRole).toString();

	//Fill style options with item data
        const QStyle *style = QApplication::style();

        QStyleOptionButton opt;

	opt.state |= status ? QStyle::State_On : QStyle::State_Off;
	opt.state |= QStyle::State_Enabled;
	opt.text = text;
	opt.rect = option.rect;
	
	//Draw item data as CheckBox
	style->drawControl(QStyle::CE_CheckBox,&opt,painter);
}

QWidget* MvQCheckBoxComboDelegate::createEditor(QWidget *parent,
             const QStyleOptionViewItem&,
             const QModelIndex& ) const
{
	//Create check box as our editor
	QCheckBox *editor = new QCheckBox(parent);
	
	editor->setFocusPolicy(Qt::StrongFocus);

	connect(editor,SIGNAL(stateChanged(int)),
		this, SLOT(slotCheckBoxStateChanged(int)));	
	return editor;
}

void MvQCheckBoxComboDelegate::slotCheckBoxStateChanged(int checked)
{
//	bool b=checked;
//	qDebug() << b;

	commmitAndCloseEditor();
}

void MvQCheckBoxComboDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
	QCheckBox *myEditor = static_cast<QCheckBox*>(editor);

	myEditor->setText(index.data(Qt::DisplayRole).toString());	
	myEditor->setChecked(index.data(Qt::UserRole).toBool());
}


void MvQCheckBoxComboDelegate::setModelData(QWidget *editor, QAbstractItemModel *model,const QModelIndex &index) const
{
//	qDebug() << "setModelData";
	//get the value from the editor (CheckBox)
	
	QCheckBox *myEditor = static_cast<QCheckBox*>(editor);
	
	bool value = myEditor->isChecked();
	
	//set model data
	
	QMap<int,QVariant> data;
	
	data.insert(Qt::DisplayRole,myEditor->text());	
	data.insert(Qt::UserRole,value);
	
	model->setItemData(index,data);

//	qDebug() << "dataChanged";
	emit dataChanged();

}

void MvQCheckBoxComboDelegate::updateEditorGeometry(QWidget *editor,
             const QStyleOptionViewItem &option, const QModelIndex& ) const
{
	editor->setGeometry(option.rect);
}

void MvQCheckBoxComboDelegate::commmitAndCloseEditor()
{
	QCheckBox *editor = static_cast<QCheckBox*>(sender());
//	qDebug() << "commitdata";
	emit commitData(editor);
	
	//emit closeEditor(slider);
}



MvQCheckBoxCombo::MvQCheckBoxCombo(QWidget *widget ) :QComboBox(widget)
{
      	// set delegate items view
      	MvQCheckBoxComboDelegate *delegate = new MvQCheckBoxComboDelegate(this);

	view()->setItemDelegate(delegate);

      	// Enable editing on items view
      	view()->setEditTriggers(QAbstractItemView::CurrentChanged);
 
      	// set "CheckBoxList::eventFilter" as event filter for items view
      	view()->viewport()->installEventFilter(this);

	view()->setAlternatingRowColors(true);

	connect(delegate,SIGNAL(dataChanged()),
		this,SLOT(repaint()));

	connect(delegate,SIGNAL(dataChanged()),
		this,SIGNAL(selectionChanged()));
}

MvQCheckBoxCombo::~MvQCheckBoxCombo()
{
}

bool MvQCheckBoxCombo::eventFilter(QObject *object, QEvent *event)
{
      // don't close items view after we release the mouse button
      // by simple eating MouseButtonRelease in viewport of items view

      if(event->type() == QEvent::MouseButtonRelease && object==view()->viewport())
      {
            return true;
      }
      return QComboBox::eventFilter(object,event);
}

void MvQCheckBoxCombo::paintEvent(QPaintEvent *)
{
 //   	qDebug() << "repaint";

	QStylePainter painter(this);

    	painter.setPen(palette().color(QPalette::Text));

    	// draw the combobox frame, focusrect and selected etc.

    	QStyleOptionComboBox opt;

   	initStyleOption(&opt);

	QString str;
	for(int i=0; i < count(); i++)
	{
		QModelIndex index=model()->index(i,0);
		if(model()->data(index,Qt::UserRole).toBool() == true)
		{			
			if(str.size() != 0)
			{
				str.append("/");
			}

			str.append(model()->data(index,Qt::DisplayRole).toString());
		}
	}	
    	 // if no display text been set , use "..." as default
     	if(str.size() > 0)
 		opt.currentText = str;
	else

            	opt.currentText = "...";

    	painter.drawComplexControl(QStyle::CC_ComboBox, opt);

    	// draw the icon and text
    	painter.drawControl(QStyle::CE_ComboBoxLabel, opt);
}

QStringList MvQCheckBoxCombo::getSelectedValues()
{
	QStringList str;
	for(int i=0; i < count(); i++)
	{
		QModelIndex index=model()->index(i,0);
		if(model()->data(index,Qt::UserRole).toBool() == true)
			str.append(model()->data(index,Qt::DisplayRole).toString());
	}	
	return str;
}
