/***************************************************************************
 *   Copyright (C) 2008 by Juergen Thies                                   *
 *   layout@juergenthies.de                                                *
 *                                                                         *
 *   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.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/


#include "layermanager.h"
#include <qpushbutton.h>
#include <qvalidator.h>
#include <qlineedit.h>
#include "general/setup.h"
#include <qstring.h>
#include <qspinbox.h>
#include <qradiobutton.h>
#include <qfiledialog.h>
#include <qcheckbox.h> 
#include <qcolordialog.h>
#include <QFileDialog>
#include <QLabel>
#include <QStyleFactory>
#include <QMessageBox>
#include <QPainter>
#include <QMouseEvent>
#ifdef FULL_VERSION
#include "license/license.h"
#endif

#include "general/layer.h"
#include <QVBoxLayout>

layerManager::layerManager(QWidget* )
: layerManagerDialog()
{setupUi(this);
setModal(true);

setup3dView = new display3d(this);
setup3dView->setObjectName(QString::fromUtf8("setup3dView"));
setup3dView->setMinimumSize(QSize(100, 0));
verticalLayout_8->addWidget(setup3dView);
initLayer=layers::displayedLayers;
for (int i=0;i<initLayer;i++){
  layerWidget[i]=new layerSetupWidget2(scrollAreaWidgetContents,i);
  scrollAreaWidgetContents->layout()->addWidget(layerWidget[i]);
  connect(layerWidget[i],SIGNAL(entered(int)),this,SLOT(layerChanged(int)));
}

 for (int i=0;i<layerStyle;i++){
 	b[i]= new layersetupbutton(i,Ui_layerManagerDialog::style);
	int k,j;
	j=0;
	k=i*25; while (k>180+50) {k-=250;j+=25;}
 	b[i]->setGeometry(5+k,20+j,25,25);
	connect(b[i],SIGNAL(pressed2(int)),this,SLOT(changeStyle(int)));
 }
Ui_layerManagerDialog::style->setMaximumWidth(280);
curLayer->setMaximum(initLayer-1);
currentLayer=0;
curLayer->setValue(currentLayer);
readLayer();
connect(enableAll,SIGNAL(clicked()),this,SLOT(allEnable()));
connect(disableAll,SIGNAL(clicked()),this,SLOT(allDisable()));
connect(color,SIGNAL(clicked()),this,SLOT(changeColor()));
connect(curLayer,SIGNAL(valueChanged(int)),this,SLOT(layerChanged(int)));
connect(thickness3d,SIGNAL(valueChanged(int)),this,SLOT(change3d(int)));
connect(level3d,SIGNAL(valueChanged(int)),this,SLOT(change3d(int)));
connect(setup3dView,SIGNAL(selectLayer(int)),this,SLOT(layerChanged(int)));
connect(setup3dView,SIGNAL(setupChange(int,int)),this,SLOT(set3d(int,int)));
ignoreChange=false;
this->setToolTip(tr("cross section view\nclick and move to adjust"));
}

layerManager::~layerManager()
{
for (int i=0;i<initLayer;i++){
 delete layerWidget[i];
}

}

void layerManager::set3d(int l,int t){
  ignoreChange=true;
  level3d->setValue(l);
  thickness3d->setValue(t);
  ignoreChange=false;
}

/*$SPECIALIZATION$*/
void layerManager::reject()
{
  QDialog::reject();
}

void layerManager::accept()
{
  writeLayer();
  QDialog::accept();
  for (int i=0;i<initLayer;i++){
    layerWidget[i]->save();
  }
}



void layerManager::open()
{
  

  for (int i=0;i<initLayer;i++){
    layerWidget[i]->setup();
  }
   readLayer();
   show();
}

void layerManager::allEnable(){
  for (int i=0;i<initLayer;i++){
      layerWidget[i]->setEnabled(true);
  }
}

void layerManager::allDisable(){
    for (int i=0;i<initLayer;i++){
      layerWidget[i]->setEnabled(false);
  }
}

void layerManager::setPixmap(){
pixmap=QPixmap(100,100);
QPainter p(&pixmap);
pixmap.fill(setup::backgroundColor);
p.setBrush(brush);
p.setPen(pen);
p.drawRect(10,10,80,80);
color->setIcon(QIcon(pixmap));
}

void layerManager::changeColor(){
 QColor color=QColorDialog::getColor(pen.color());
  if (color.isValid()){
  	pen.setColor(color);
  	brush.setColor(color);
  	setPixmap();}
}

void layerManager::changeStyle(int bs){
brushStyle=bs;
brush=layer::getBrush(bs);
brush.setColor(pen.color());
setPixmap();
}

void layerManager::readLayer(){
  currentLayer=curLayer->value();
  brushStyle=layerWidget[currentLayer]->brushStyle;
  brush=layer::getBrush(brushStyle);
  brush.setColor(layerWidget[currentLayer]->color);
  pen=QPen(layerWidget[currentLayer]->color);
  level3d->setValue(layerWidget[currentLayer]->level);
  thickness3d->setValue(layerWidget[currentLayer]->thickness);
  setPixmap();
  shortKeyB->setShortKey(layerWidget[currentLayer]->shortKey);
  layerWidget[currentLayer]->setStyleSheet("color:red;");
  setup3d();
}

void layerManager::writeLayer(){
  layerWidget[currentLayer]->shortKey=shortKeyB->getShortKey();
  layerWidget[currentLayer]->setStyleSheet("");
  layerWidget[currentLayer]->brushStyle=brushStyle;
  layerWidget[currentLayer]->color=pen.color();
  layerWidget[currentLayer]->level=level3d->value();
  layerWidget[currentLayer]->thickness=thickness3d->value();
  scrollArea->ensureWidgetVisible(layerWidget[currentLayer]);
}

void layerManager::layerChanged(int l){
  if(l!=curLayer->value())curLayer->setValue(l);
  writeLayer();
  readLayer();
}

void layerManager::change3d(int){
  if (ignoreChange) return;
	setup3dView->top=level3d->value()+thickness3d->value();
	setup3dView->bottom=level3d->value();
	setup3dView->brush=brush;
	if (setup3dView->top>setup3dView->max) setup3dView->max=setup3dView->top;
	if (setup3dView->bottom<setup3dView->min) setup3dView->min=setup3dView->bottom;
	QString s;
	s.setNum(currentLayer);
	setup3dView->layerName=layerWidget[currentLayer]->getLayerName()+" ("+s+")";
	setup3dView->update();
}

void layerManager::setup3d(){
  setup3dView->data.clear();
  setup3dView->cols=0;
  setup3dView->min=0;
  setup3dView->max=0;
  for (int i=0;i<initLayer;i++){
    if (i!=currentLayer){
      if ((layerWidget[i]->thickness!=0)&&(layerWidget[i]->isEnable())){
	display3dData data3d;
	data3d.col=0;
	data3d.top=layerWidget[i]->level+layerWidget[i]->thickness;
	data3d.bottom=layerWidget[i]->level;
	data3d.brush=layer::getBrush(layerWidget[i]->brushStyle);
        data3d.brush.setColor(layerWidget[i]->color);
	data3d.layer=i;
	bool ok=true;
	do {
	  ok=true;
	  data3d.col++;
	  for (int k=0;k<setup3dView->data.size();k++){
	    //printf("%d %d %d %d\n",k,data3d.col,i,setup3dView->data.at(k).col);
	    if (setup3dView->data.at(k).col==data3d.col){
	      if ((setup3dView->data.at(k).top>data3d.bottom)&&(setup3dView->data.at(k).bottom<data3d.top)){ok=false; break;}
	    }
	  }
	}
	while (ok==false);
	setup3dView->data<<data3d;
	if (data3d.top>setup3dView->max) setup3dView->max=data3d.top;
	if (data3d.bottom<setup3dView->min) setup3dView->min=data3d.bottom;
 	if (data3d.col>setup3dView->cols) setup3dView->cols=data3d.col;
      }}
      else {
	setup3dView->top=level3d->value()+thickness3d->value();
	setup3dView->bottom=level3d->value();
	setup3dView->brush=brush;
	if (setup3dView->top>setup3dView->max) setup3dView->max=setup3dView->top;
	if (setup3dView->bottom<setup3dView->min) setup3dView->min=setup3dView->bottom;
	QString s;
	s.setNum(i);
	setup3dView->layerName=layerWidget[i]->getLayerName()+" ("+s+")";
    };
  }
  setup3dView->update();
}

display3d::display3d(QWidget* parent ):QWidget(parent){
  setMouseTracking (true);
}

display3d::~display3d(){
}

void display3d::mousePressEvent ( QMouseEvent * e){
  QPoint mousePos=e->pos();
  //printf("-- %d %d\n",e->pos().x(),e->pos().y());
  if (mousePos.x()>w){
    if (e->buttons()==Qt::LeftButton){
       int col=mousePos.x()/w;
       if (scale==0) return;
       int pos=int((mousePos.y()-o)/scale);
       //printf("%d %d\n",pos,col);
       for (int k=0;k<data.size();k++){
	    if ((data.at(k).col==col)&&(data.at(k).top>=pos)&&(data.at(k).bottom<=pos)){
	      //printf("found %d\n",k);
	      emit selectLayer(data.at(k).layer);
	      return;
	    }
	}
      
    }
  }else {
    if (e->buttons()==Qt::LeftButton){
      int pos=int((mousePos.y()-o)/scale);
      mouseMovePos=pos;
      if (pos>top) moveTop=true;
      else if (pos<bottom) moveBottom=true;
      else {
	moveTop=true;
	moveBottom=true;
      }
    }
  }
}

void display3d::mouseReleaseEvent ( QMouseEvent * event ){
}

void display3d::mouseMoveEvent ( QMouseEvent * e ){
  if (e->buttons()==Qt::LeftButton){
    int pos=int((e->pos().y()-o)/scale)-mouseMovePos;
    if (moveTop){
      top+=pos;
      if (top>max) {max=top;}
    }
    if (moveBottom){
      bottom+=pos;
      if (bottom<min) {min=bottom;}
      
    }
    if (bottom>top) top=bottom;
    if (top>max) {max=top;}
    mouseMovePos+=pos;
    emit setupChange(bottom,top-bottom);
    update();
  }
  else
  {
    moveTop=false;
    moveBottom=false;
  }
}

void display3d::paintEvent ( QPaintEvent * event ){
  w=width()/(cols+1);
  scale=-(double(height())-20.0)/(max-min+1);
  o=int(height()-10-scale*min);
  QPen pen(brush.color());
  QPainter paint(this); 
  paint.setPen(pen);
  paint.setBrush(brush);
  paint.drawRect(0,int(scale*top+o),w-1,int(scale*(bottom-top)));
  //printf("%f %d %d %d %d %d\n",scale,o,min,max,top,bottom);
  for (int k=0;k<data.size();k++){
    QPen pen(data.at(k).brush.color());
    paint.setPen(pen);
    paint.setBrush(data.at(k).brush);
    paint.drawRect(data.at(k).col*w,int(scale*data.at(k).top+o),w-1,int(scale*(-data.at(k).top+data.at(k).bottom))-1);
  }
  QPen pen1;
  paint.setPen(pen1);
  QRect r(0,0,width(),12);
  QFont f;
  f.setPixelSize(9);
  paint.setFont(f);
  paint.drawText(r,Qt::AlignHCenter,tr("top"));
  r=QRect(0,height()-12,width(),12);
  paint.drawText(r,Qt::AlignHCenter,tr("bottom"));
  QMatrix m(0,-1,1,0,0,0);
  paint.setMatrix(m);
  r=QRect(-height(),0,height(),w);
  paint.drawText(r,Qt::AlignCenter,layerName);
  paint.end();
}
