#include "dialog.h"
#include "plotter.h"

#include <QVBoxLayout>
#include <QPushButton>
#include <QRadioButton>
#include <QGroupBox>
#include <QMessageBox>
#include <QLabel>

#include <string>
using namespace std;
#include <cmath>
#include <iostream>

extern void Gauss(double*, double*, double*, int);

Dialog::Dialog(QWidget *parent) : QDialog(parent)
{
  //elements
  QLabel* labelHeader = new QLabel(tr("Picture source: Sebastian Bauer CAU Kiel"));
  QLabel *label_ogs = new QLabel();
  label_ogs->setAlignment(Qt::AlignCenter);
  label_ogs->setPixmap(QPixmap("/Users/OK/Documents/2_TUD/BHYWI-22-2016/BHYWI-22-E1/ogs_teaching_150.png"));
  QLabel *label_exercise = new QLabel();
  label_exercise->setAlignment(Qt::AlignCenter);
  label_exercise->setPixmap(QPixmap("/Users/OK/Documents/2_TUD/BHYWI-22-2016/BHYWI-22-E1/gw1_300.png"));
  pushButtonRUN = new QPushButton(tr("Run simulation"));
  solver_method_ = new QRadioButton("Solver method",parent);
  QGroupBox *groupBox = new QGroupBox(tr("Exclusive Radio Buttons"));
  QRadioButton *radio1 = new QRadioButton(tr("&Gauss Solver"));
  QRadioButton *radio2 = new QRadioButton(tr("Gauss-&Seidel Solver"));
  QRadioButton *radio3 = new QRadioButton(tr("&Alternative Solver"));
  QRadioButton *radio4 = new QRadioButton(tr("&Neues Verfahren"));
  radio2->setChecked(true);
  //connect
  connect(pushButtonRUN,SIGNAL(clicked()),this,SLOT(on_pushButtonRUN_clicked()));
  connect(radio1,SIGNAL(clicked(bool)),this,SLOT(clickkedstate(bool)));
  //layout
  QVBoxLayout *mainLayout = new QVBoxLayout;
  QVBoxLayout *upperLayout = new QVBoxLayout;
  QHBoxLayout *lowerLayout = new QHBoxLayout; //H->V
  QVBoxLayout *lowerleftLayout = new QVBoxLayout;
  upperLayout->addWidget(labelHeader);
  upperLayout->addWidget(label_exercise);
  upperLayout->addWidget(pushButtonRUN);
  lowerLayout->addLayout(lowerleftLayout);
  lowerleftLayout->addWidget(radio1);
  lowerleftLayout->addWidget(radio2);
  lowerleftLayout->addWidget(radio3);
  lowerleftLayout->addWidget(radio4);
  lowerleftLayout->addStretch(1);
  groupBox->setLayout(lowerleftLayout);
  lowerLayout->addWidget(label_ogs);
  mainLayout->addLayout(upperLayout);
  mainLayout->addLayout(lowerLayout);
  setLayout(mainLayout);
  //initializations I
  solver_method = 1;
  solver_iterations = 100;
  n=6;
  int n2=n*n;
  out_file.open("/Users/OK/Documents/2_TUD/BHYWI-22-2016/BHYWI-22-E1/out.txt");
  //out_file.setf(ios::scientific);
  out_file.precision(5);
  eps = 1e-3;
  //data structures
  A = new double[n2]; //matrix
  x = new double[n]; //solution vector
  b = new double[n]; //RHS vector
  //initializations II
  for(int i=0;i<n;i++)
    x[i]=10.; //?
  x[0]=10.;
  x[3]=10.;
}

Dialog::~Dialog()
{
    delete [] A;
}

void Dialog::on_pushButtonRUN_clicked()
{
  QMessageBox msgBox;
  switch(solver_method)
  {
    case 0: //Gauss
      AssembleEQS();   //assemble equation system
      TestOutput(A,b);
      Gauss(A,b,x,n);  //solve EQS via Gauss
      break;
    case 1: //Gauss-Seidel
      GaussSeidel();
      msgBox.setText("Gauss-Seidel method finished, \n results in out.txt");
      break;
    case 3: // neues Verfahren
      msgBox.setText("Neues Verfahren vorbereitet");
     break;
  }
  pushButtonRUN->setStyleSheet("background-color: green");
  msgBox.exec();
}

void Dialog::GaussSeidel()
{
  double x0[6];
  double y;
  for(int k=0;k<solver_iterations;k++)
  {
    x0[1]=x[1];
    x0[2]=x[2];
    x0[4]=x[4];
    x0[5]=x[5];
    x[1] = 0.2408 * x[2] + 0.3211 * x[4] + 4.4181;
    x[2] = 0.4285 * x[1] + 0.5714 * x[5] + 0.0857;
    x[4] = 0.7028 * x[1] + 0.1054 * x[5] + 2.0223 ;
    x[5] = 0.8695 * x[2] + 0.1304 * x[4];
    out_file << "Iteration step: " << k << endl;
    TestOutput(x);
    //Fehlerberechung
    y = abs(x0[1]-x[1]) + abs(x0[2]-x[2]) + abs(x0[4]-x[4]) + abs(x0[5]-x[5]);
    y = y/4.;
    cout << y << endl;
    if(y<eps) return;
  }
}


void Dialog::TestOutput(double*x)
{
  for(int i=0;i<n;i++)
  {
    out_file << "h" << QString::number(i).toStdString() << ":" << x[i] << endl;
  }
}

void Dialog::TestOutput(double*a,double*b)
{

  for(int i=0;i<n;i++)
  {
    for(int j=0;j<n;j++)
    {
      out_file << A[n*i+j] << "\t";
    }
    out_file << " : " << b[i] << endl;
  }
}

void Dialog::AssembleEQS()
{
    // h1 ist BC
    A[0] =  -0.103788; //a11
    A[1] =   0.025000; //a12
    A[2] =   0.033330; //a13
    A[3] =   0.000000; //a14
    A[4] =   0.025000; //a21
    A[5] =  -0.058300; //a22
    A[6] =   0.000000; //a23
    A[7] =   0.033333; //a24
    A[8] =   0.033333; //a31
    A[9] =  -0.047400; //a32
    A[10] =  0.000000; //a33
    A[11] =  0.005000; //a34
    A[12] =  0.000000; //a41
    A[13] =  0.033333; //a42
    A[14] =  0.00500; //a43
    A[15] = -0.0383; //a44
    // Assemble RHS vector
    b[0] = -0.458545;
    b[1] = -0.005000;
    b[2] = -0.095900;
    b[3] = -0.000000;
}

/*
void Dialog::AssembleEQS()
{
    // h1 ist BC
    A[0] = 1.; //a11
    A[1] = 0.; //a12
    A[2] = 0.; //a13
    A[3] = 0.; //a14
    A[4] = 0.; //a15
    A[5] = 0.; //a16
    // h2
    A[6] = 0.; //a21
    A[7] = -0.103788; //a22
    A[8] = 0.025; //a23
    A[9] = 0.; //a24
    A[10] = 0.0333; //a25
    A[11] = 0.; //a26
    // h3
    A[12] = 0.; //a31
    A[13] = 0.025; //a32
    A[14] = -0.0583; //a33
    A[15] = 0.; //a34
    A[16] = 0.; //a35
    A[17] = 0.0333; //a36
    // h4 ist BC
    A[18] = 0.; //a41
    A[19] = 0.; //a42
    A[20] = 0.; //a43
    A[21] = 1.; //a44
    A[22] = 0.; //a45
    A[23] = 0.; //a46
    // h5
    A[24] = 0.; //a51
    A[25] = 0.0333; //a52
    A[26] = 0.; //a53
    A[27] = 0.; //a54
    A[28] = -0.0474; //a55
    A[29] = 0.005; //a56
    // h6
    A[30] = 0.; //a61
    A[31] = 0.; //a62
    A[32] = 0.0333; //a63
    A[33] = 0.; //a64
    A[34] = 0.005; //a65
    A[35] = -0.383; //a66
    // Assemble RHS vector
    b[0] = 10.;
    b[1] = -0.458545;
    b[2] = -0.005;
    b[3] = 10.;
    b[4] = -0.0959;
    b[5] = 0.;
}
*/
