#include "parameters.h"
#include "ressources.h"
#include "resstring.h"
#include "winexception.h"
#include <stdio.h>
#include <string.h>
#include <fstream>

Parameters::Parameters(): 
    _name(""), _nbParameters(0)
{}

Parameters::Parameters(const std::string &name):
    _name(name), _nbParameters(NB_PARAMETERS)
{
    Process();
}

Parameters::Parameters(const Parameters &rhs):
    _name(rhs._name), _pi(rhs._pi), _tiny(rhs._tiny),
    _lambda(rhs._lambda), _screenDistance(rhs._screenDistance),
    _dxStep(rhs._dxStep), _dyStep(rhs._dyStep),
    _nbParameters(rhs._nbParameters)
{}

Parameters::~Parameters()
{}

Parameters &Parameters::operator=(const Parameters &rhs)
{
    if(&rhs != this)
      {
      _name = rhs._name;
      _pi = rhs._pi;
      _tiny = rhs._tiny;
      _lambda = rhs._lambda;
      _screenDistance = rhs._screenDistance;
      _dxStep = rhs._dxStep;
      _dyStep = rhs._dyStep;
      _nbParameters = rhs._nbParameters;
      }
    return (*this);
}

void Parameters::RestoreDefaults()
{ 
    char text[MAX_PATH];

    _name = ResString(DEFAULT_PARAM_NAME);
    _nbParameters = NB_PARAMETERS;
    _pi = M_PI;
    _tiny = TINY;
    _lambda = LAMBDA_WAVE;
    _screenDistance = SCREEN_DISTANCE;
    _dxStep = DX_STEP;
    _dyStep = DY_STEP;
    
    std::ofstream file(_name.c_str(), std::ios::out);
    
    if(!file.is_open())
      throw WinException(ResString(ERROR_RESTORING_PARAMS));
  
    file << "// Fichier des paramètres.\n";
    file << "// A ne modifier qu'en connaissance de cause en respectant la syntaxe ci-dessous.\n";
    file << "// Une mauvaise modification peut mener à une instabilité numérique et à des calculs faux.\n";
    file << "// Leblanc Christophe.\n";

    file << "// Nombre pi\n";
    file << "pi ";
    sprintf(text, "%1.15f\n", _pi);
    file << text;

    file << "// Valeur de la tolérance dans les calculs\n";
    file << "tiny ";
    sprintf(text, "%5.20f\n", _tiny);
    file << text;

    file << "// Longueur d'onde incidente [m]\n";
    file << "lambda ";
    sprintf(text, "%5.20f\n", _lambda);
    file << text;

    file << "// Distance à l'écran [m]\n";
    file << "screen ";
    sprintf(text, "%5.20f\n", _screenDistance);
    file << text;

    file << "// Pas de discrétisation dans la direction x [m]\n";
    file << "dx ";
    sprintf(text, "%5.20f\n", _dxStep);
    file << text;

    file << "// Pas de discrétisation dans la direction y [m]\n";
    file << "dy ";
    sprintf(text, "%5.20f\n", _dyStep);
    file << text;

    file.write("\n", sizeof(char));
    file.close();
}

void Parameters::ReloadParams()
{
    Process();
}

double Parameters::pi() const
{
    return _pi;
}

double Parameters::tiny() const
{
    return _tiny;
}

double Parameters::lambda() const
{
    return _lambda;
}

double Parameters::screenDistance() const
{
    return _screenDistance;
}

double Parameters::dxStep() const
{
    return _dxStep;
}

double Parameters::dyStep() const
{
    return _dyStep;
}

char const* Parameters::name() const
{
    return _name.c_str();
}

double Parameters::ProcessString(char const *pc)
{
    int i(0);
    
    while(!isdigit(pc[i]) && pc[i] != '\n' && pc[i] != '\0')
       i++;
       
    if(pc[i] == '\n' || pc[i] == '\0')
      throw WinException(ResString(ERROR_FILE_PARAMS));
      
    return atof(pc+i);
}

void Parameters::Process()
{
    char text[MAX_PATH], *pc;
    int nParams = 0;
    std::ifstream file(_name.c_str(), std::ios::in);
    
    if(!file.is_open())
      throw WinException(ResString(ERROR_NO_FILE_PARAMS), ERROR_NO_FILE_PARAMS);
    
while(file.getline(text, MAX_PATH))
   {
   if(text[0] == '/' || text[0] == '%' || text[0] == '!')
     continue;

   if((pc = strstr(text, "pi")) != NULL)
     {
     _pi = ProcessString(pc);
     nParams++;
     }
   else if((pc = strstr(text, "tiny")) != NULL)
     {
     _tiny = ProcessString(pc);
     nParams++;
     }
   else if((pc = strstr(text, "lambda")) != NULL)
     {
     _lambda = ProcessString(pc);
     nParams++;
     }
   else if((pc = strstr(text, "screen")) != NULL)
     {
     _screenDistance = ProcessString(pc);
     nParams++;
     }
   else if((pc = strstr(text, "dx")) != NULL)
     {
     _dxStep = ProcessString(pc);
     nParams++;
     }
   else if((pc = strstr(text, "dy")) != NULL)
     {
     _dyStep = ProcessString(pc);
     nParams++;
     }
   }    
    
    if(nParams != _nbParameters)
      throw WinException(ResString(ERROR_FILE_PARAMS), ERROR_FILE_PARAMS);
    
    file.close();
}
