#include "input.hpp"

QtInput::QtInput():QWidget(){
  geometry=new Geometry;
  geometry->initDefault();
  
  main_layout=new QVBoxLayout;
  button_layout=new QHBoxLayout;
  tab_widget=new QTabWidget;
  button_widget=new QWidget;
  button_save=new QPushButton("Save");
  button_cancel=new QPushButton("Cancel");
  button_run=new QPushButton("Run");

  input_view=new QtInputView;
  input_physics=new QtInputPhysics;
  input_time=new QtInputTime;
  input_geometry=new QtInputGeometry(geometry);
  input_initial_state=new QtInputInitialState;
  input_sources=new QtInputSources;

  input_view->setGeometry(geometry);
  input_view->updateGeometry();
  
  //Tab
  tab_widget->addTab(input_physics,"Physics");
  tab_widget->addTab(input_time,"Time");
  tab_widget->addTab(input_geometry,"Geometry");
  tab_widget->addTab(input_initial_state,"Initial state");
  tab_widget->addTab(input_sources,"Sources");
  
  //Buttons
  button_layout->addWidget(button_run);
  button_layout->addWidget(button_save);
  button_layout->addWidget(button_cancel);
  button_widget->setLayout(button_layout);

  //Main
  main_layout->addWidget(tab_widget);
  main_layout->addWidget(input_view,2);
  main_layout->addWidget(button_widget);
  setLayout(main_layout);

  //Conectors
  connect(button_save,&QPushButton::clicked,this,&QtInput::save);
  connect(button_cancel,&QPushButton::clicked,this,&QtInput::cancel);
  connect(button_run,&QPushButton::clicked,this,&QtInput::run);
  connect(input_geometry,&QtInputGeometry::geometryChanged,this,&QtInput::updateGeometry);
  connect(tab_widget,&QTabWidget::currentChanged,this,&QtInput::changeTabIndex);

  previous_index=-1;

}

QtInput::QtInput(QString filename):QtInput(){
  load(filename.toStdString());
}

QtInput::~QtInput(){
}

bool
QtInput::validate(){
  QWidget* widget=input_physics->validate();
  if(widget!=nullptr){
    QMessageBox msgBox;
    msgBox.setText("Incorrect physics entry");
    msgBox.exec();
    tab_widget->setCurrentWidget(input_physics);
    widget->setFocus();
    return false;
  }
  widget=input_time->validate();
  if(widget!=nullptr){
    QMessageBox msgBox;
    msgBox.setText("Incorrect time entry");
    msgBox.exec();
    tab_widget->setCurrentWidget(input_time);
    widget->setFocus();
    return false;
  }
  widget=input_geometry->validate();
  if(widget!=nullptr){
    QMessageBox msgBox;
    msgBox.setText("Incorrect geometry entry");
    msgBox.exec();
    tab_widget->setCurrentWidget(input_geometry);
    widget->setFocus();
    return false;
  }
  return true;  
}

void
QtInput::save(){
  if(validate()){
    QString filename=QFileDialog::getSaveFileName(this,"Save input","inputs/","QT input file (*.input)");
    if(not filename.isEmpty()){
      if(filename.indexOf(".input")==-1){
	filename.append(".input");
      }
      save_input(filename.toStdString());
    }
  }
}

void
QtInput::run(){
  if(validate()){
    emit run_signal();
  }
}

void
QtInput::save_input(string filename){
  fstream file;
  file.open(filename.c_str(),fstream::out|fstream::trunc|fstream::binary);
  input_physics->save(file);
  input_time->save(file);
  input_geometry->save(file);
  file.close();
}

void
QtInput::cancel(){
  emit exit_signal();
}

void
QtInput::load(string filename){
  fstream file;
  file.open(filename.c_str(),fstream::in|fstream::binary);
  input_physics->load(file);
  input_time->load(file);
  input_geometry->load(file);
  file.close();
}

void
QtInput::changeTabIndex(int index){
  if(previous_index==2){
    updateGeometry();
  }
  previous_index=index;
  
}

void
QtInput::updateGeometry(){
  QWidget* widget=input_geometry->validate();
  if(widget!=nullptr){
    QMessageBox msgBox;
    msgBox.setText("Incorrect geometry entry");
    msgBox.exec();
    tab_widget->setCurrentWidget(input_geometry);
    widget->setFocus();
  }
  else{
    input_view->updateGeometry();
  }
}
