/*
    QGL MaterialsEditor
    Ivan Pelipenko peri4ko@yandex.ru

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 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 Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#include "materials_editor.h"

#include "glmaterial.h"
#include "material_editor.h"
#include "qglview.h"
#include "ui_materials_editor.h"

#include <QInputDialog>
#include <ecombobox.h>
#include <qad_types.h>


MaterialsEditor::MaterialsEditor(QWidget * parent): QWidget(parent) {
	ui = new Ui::MaterialsEditor();
	ui->setupUi(this);
	ui->widgetMaterial->setMaterial(0);
	ui->scrollArea->viewport()->setAutoFillBackground(false);
	ui->scrollAreaWidgetContents->setAutoFillBackground(false);
	view = 0;
}


void MaterialsEditor::assignQGLView(QGLView * v) {
	view = v;
	connect(view, SIGNAL(selectionChanged()), this, SLOT(selectionChanged()));
	connect(view, SIGNAL(materialsChanged()), this, SLOT(materialsChanged()));
	connect(view, SIGNAL(materialThumbnailCreated(Material *)), this, SLOT(materialThumbnailCreated(Material *)));
	materialsChanged();
}


bool MaterialsEditor::event(QEvent * e) {
	if (e->type() == QEvent::FontChange || e->type() == QEvent::Polish) {
		QSize sz = preferredIconSize(1.5, this);
		ui->comboMaterial->setIconSize(sz * 3);
		ui->buttonRename->setIconSize(sz);
		ui->buttonAdd->setIconSize(sz);
		ui->buttonClone->setIconSize(sz);
		ui->buttonDelete->setIconSize(sz);
		ui->buttonAssign->setIconSize(sz);
		ui->buttonUnset->setIconSize(sz);
	}
	return QWidget::event(e);
}


void MaterialsEditor::changeEvent(QEvent * e) {
	QWidget::changeEvent(e);
	switch (e->type()) {
	case QEvent::LanguageChange: ui->retranslateUi(this); break;
	default: break;
	}
}


Material * MaterialsEditor::currentMaterial() {
	if (!view) return 0;
	int ind                  = ui->comboMaterial->currentIndex();
	QVector<Material *> mats = view->scene()->getMaterials();
	if (ind < 0 || ind >= mats.size()) return 0;
	return mats[ind];
}


void MaterialsEditor::selectMaterial(Material * m) {
	if (!m) {
		ui->comboMaterial->setCurrentIndex(-1);
		return;
	}
	for (int i = 0; i < ui->comboMaterial->count(); ++i) {
		if ((Material *)(ui->comboMaterial->itemData(i, Qt::UserRole + 1).value<quintptr>()) == m) {
			ui->comboMaterial->setCurrentIndex(i);
			break;
		}
	}
}


int MaterialsEditor::indexByMaterial(Material * m) {
	if (!m) return -1;
	for (int i = 0; i < ui->comboMaterial->count(); ++i) {
		if ((Material *)(ui->comboMaterial->itemData(i, Qt::UserRole + 1).value<quintptr>()) == m) return i;
	}
	return -1;
}


void MaterialsEditor::selectionChanged() {
	if (!view) return;
	// qDebug() << "selectionChanged";
	ObjectBase * o = view->selectedObject();
	if (o) selectMaterial(o->material());
}


void MaterialsEditor::materialsChanged() {
	if (ui->widgetMaterial->ignore_next > 0) {
		ui->widgetMaterial->ignore_next--;
		return;
	}
	Material * cm = currentMaterial();
	ui->comboMaterial->clear();
	if (!view) return;
	QVector<Material *> mats = view->scene()->getMaterials();
	for (int i = 0; i < mats.size(); ++i) {
		Material * m = mats[i];
		ui->comboMaterial->addItem(QString("[%1] " + m->name).arg(i + 1), QVariant(m->name));
		ui->comboMaterial->setItemData(i, QVariant(quintptr(m)), Qt::UserRole + 1);
		ui->comboMaterial->setItemIcon(i, QIcon(QPixmap::fromImage(view->materialThumbnail(m))));
		if (cm == m) ui->comboMaterial->setCurrentIndex(i);
	}
}


void MaterialsEditor::materialThumbnailCreated(Material * m) {
	// qDebug() << "materialThumbnailCreated" << m;
	int i = indexByMaterial(m);
	if (i < 0 || !view) return;
	// qDebug() << "materialThumbnailCreated set to" << i;
	ui->comboMaterial->setItemIcon(i, QIcon(QPixmap::fromImage(view->materialThumbnail(m))));
}


void MaterialsEditor::on_comboMaterial_currentIndexChanged(int index) {
	ui->widgetMaterial->setMaterial(currentMaterial());
}


void MaterialsEditor::on_buttonRename_clicked() {
	Material * m = currentMaterial();
	if (!m) return;
	QString nn = QInputDialog::getText(this, "Materials editor", "Input new name:", QLineEdit::Normal, m->name);
	if (nn.isEmpty()) return;
	m->name = nn;
	int ind = ui->comboMaterial->currentIndex();
	ui->comboMaterial->setItemText(ind, QString("[%1] " + nn).arg(ind + 1));
	ui->comboMaterial->setItemData(ind, nn);
}


void MaterialsEditor::on_buttonAdd_clicked() {
	if (!view) return;
	Material * m = view->scene()->newMaterial();
	materialsChanged();
	selectMaterial(m);
}


void MaterialsEditor::on_buttonClone_clicked() {
	if (!view) return;
	Material * curm = currentMaterial();
	if (!curm) return;
	Material * m = view->scene()->newMaterial(curm->name);
	QString nm   = m->name;
	*m           = *curm;
	m->name      = nm;
	m->_changed  = true;
	materialsChanged();
	selectMaterial(m);
}


void MaterialsEditor::on_buttonDelete_clicked() {
	if (!view) return;
	Material * m = currentMaterial();
	if (!m) return;
	view->scene()->removeMaterial(m);
	materialsChanged();
}


void MaterialsEditor::on_buttonAssign_clicked() {
	if (!view) return;
	Material * m      = currentMaterial();
	ObjectBaseList ol = view->selectedObjects();
	foreach(ObjectBase * o, ol)
		o->setMaterial(m, true);
}


void MaterialsEditor::on_buttonUnset_clicked() {
	if (!view) return;
	ObjectBaseList ol = view->selectedObjects();
	foreach(ObjectBase * o, ol)
		o->setMaterial(0, true);
}
