 /********************************* C_CalendrierObstetrique.cpp ******************
 *   This program is free software; you can redistribute it and/or modify         *
 *   it under the terms of the CeCILL Version 1 du 21/06/2004                     *
 *   License (GPL compatible)                                                     *
 *                              http://www.cecill.info/                           *
 *   as published by :                                                            *
 *                                                                                *
 *   Commissariat a l'Energie Atomique                                            *
 *   - CEA,                                                                       *
 *                            31-33 rue de la Federation, 75752 PARIS cedex 15.   *
 *                            FRANCE                                              *
 *   Centre National de la Recherche Scientifique                                 *
 *   - CNRS,                                                                      *
 *                            3 rue Michel-Ange, 75794 Paris cedex 16.            *
 *                            FRANCE                                              *
 *   Institut National de Recherche en Informatique et en Automatique             *
 *   - INRIA,                                                                     *
 *                            Domaine de Voluceau, Rocquencourt, BP 105, 78153    *
 *                            FRANCE                                              *
 *                                                                                *
 *         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.                   *
 *         CeCILL  License (GPL compatible) for more details.                     *
 *                                                                                *
 **********************************************************************************/
/*! \file C_CalendrierObstetrique.cpp
 \brief Calcul et renvoie le calendrier obstétrical en se basant sur la date des dernières règles.

     #include "C_CalendrierObstetrique.h"
     Project: MedinTux
     Copyright (C) 2003 2004 2005 2006 2007
     by Sevin Roland , Eric Maeker and Data Medical Design
     E-Mail: roland-sevin@medintux.org
*/

/*! \class C_CalendrierObstetrique
 \brief Calcul et renvoie le calendrier obstétrical en se basant sur la date des dernières règles.

     #include "C_CalendrierObstetrique.h"\n
     Project: MedinTux \n
     Copyright (C) 2003 2004 2005 2006 2007 \n
     by Sevin Roland , Eric Maeker and Data Medical Design \n
     E-Mail: roland-sevin@medintux.org \n
*/
#include <qobject.h>
#include <qstringlist.h>

#define TR QObject::tr

#include "C_CalendrierObstetrique.h"

//------------------------------------------ C_CalendrierObstetrique -------------------------------------------------------------
/*! \brief Constructeur, récupère ddr dans la variable globale m_ddr.
    \param ddr :	Le premier jour des dernières règles
*/
C_CalendrierObstetrique::C_CalendrierObstetrique(const QString &ddr)
: m_ddr(ddr)
{
}

//------------------------------------------ ~C_CalendrierObstetrique -------------------------------------------------------------
/*! \brief Destructeur 
*/
C_CalendrierObstetrique::~C_CalendrierObstetrique()
{
}

//------------------------------------------ Terme_Obst -------------------------------------------------------------
/*! \fn QString C_CalendrierObstetrique::Terme_Obst()
    \brief Calcul le terme de la grossesse à la date souhaitée..
    \param dt :		Date à laquelle on souhaite faire le calcul 
    \return Renvoie le terme au format string du style : " XX SA XX Jours "
*/
//--------------------------------------------------------------------------------------------------------------------
QString C_CalendrierObstetrique::Terme_Obst(QDate dt)
{ // Récupère la DDR
  QString sDDR = GetDDR();
  if (!sDDR[0].isNumber()) return QString(TR("La date des dernières règles n'est pas valide"));

  QDate DDR = QDate::fromString(sDDR, Qt::ISODate);

  // Vérification de la validité des dates au cas où...
  if (!DDR.isValid()) return QString(TR("La date des dernières règles n'est pas valide"));
  if (!dt.isValid()) return QString(TR("Impossible d'effectuer le calcul de terme : erreur de dates."));

  // Calcul les jours et semaines du terme
  int nbDays = DDR.daysTo(dt);
  int nbDaysLeft = nbDays % 7;
  int nbWeeks = (nbDays - nbDaysLeft ) / 7;
  QString ret = "";

  // Selon le résultat renvoie un message d'erreur ou le terme de la grossesse
  if (dt < DDR) { ret = TR("Le terme n'est pas calculable (terme négatif). Vérifiez vos dates."); }
  else if (nbWeeks > 45) { ret = TR("Le terme n'est pas calculable (> 45 SA). Vérifiez vos dates."); }
  else { ret = QString::number(nbWeeks) + " SA "+ QString::number(nbDaysLeft) + TR(" Jours "); }

  return ret;
}

//------------------------------------------ GetDDR -----------------------------------------------------------------
/*! \brief Récupère dans le terrain la date des dernières règles en cas de grossesse. 

 * \return Retourne la date au format Qt::ISODate (yyyy-MM-dd) ou QString:null si n'est pas trouvée.
*/
//--------------------------------------------------------------------------------------------------------------------
QString C_CalendrierObstetrique::GetDDR()
{ // Il faut vérifier le format de la date...
  int end = m_ddr.length();
  int   i = -1;
  QString str;
  while (++i < end) { if (  (m_ddr[i]>='0' && m_ddr[i]<='9') ) str += m_ddr[i]; }
  if (str.length() == 6 )  str.insert ( 4, "20" ); // date forme 011207 --> 01122007
  if (str.length() != 8 )  return QString::null;

  // Recrée la date au format yyyy-MM-dd (Qt::ISODate)
  return str.mid(4,4)+"-"+str.mid(2,2)+"-"+str.mid(0,2);
}


//------------------------------------------ Calendrier_Obst --------------------------------------------------------
/*! \brief Fonction de calendrier accessible depuis les masques de MedinTux.
 * \return Retourne le calendrier obstétrical (dates des échos, déclaration grossesse, terme...).

 * Le calendrier obstétrical s'appuie sur la date des dernières règles. \n
 * Cette date est passée en paramètre au plugins
 * En cas d'erreur, la fonction retourne une phrase d'erreur explicative

 * Pour appeler cette fonction, utilisez dans vos masques, champs d'insertion... le code suivant : 
  \code 
{{[Execute]
pathPlugin=../../Plug/cal_obst/bin/cal_obst
maskExch= *
pathIni=****
waitEnd=y
[Parametres]
m_DateDerRegle = {{DDR=dd-MM-yyyy}}
}}
  \endcode
*/
//--------------------------------------------------------------------------------------------------------------------
QString C_CalendrierObstetrique::Calendrier_Obst()
{ QDate         DDR, observ, dt;
  QString       tmp1, resolvToken;
  QStringList   d; // temporaire de la date

  // Récupère et vérifie la DDR
  tmp1 = GetDDR();
  if (!tmp1[0].isNumber()) return QString(TR("Erreur dans la date des dernières règles"));
  DDR = DDR.fromString(tmp1 , Qt::ISODate);

  // Récupère le terme et vérifie que le calendrier peut être calculé
  tmp1 = Terme_Obst(QDate::currentDate());
  if (!tmp1[0].isNumber()) return tmp1;

  //.......... Introduction au calculs et vérification de la date utilisée pour les calculs
  resolvToken = "<span style=\"font-weight: 600; color: marron\">" + TR("Les calculs sont effectués à  partir du premier jour de la date des dernières règles le ") + DDR.toString("dddd dd MMMM yyyy") + "</span><br /><br />";

  //.......... Calcul le terme à la date du jour
  resolvToken += TR("Aujourd'hui, le ") + QDate::currentDate().toString("dd MMMM yyyy") + TR(" le terme est de ");
  resolvToken += tmp1 + "<br /><br />";

  //.......... Prépare le tableau des dates pour le suivi obstétrical
  resolvToken += "<br /><table width=\"100%\" border=\"1\" cellpadding=\"2\" cellspacing=\"2\">";

  //.......... Calcul les différentes dates du suivi obstétrical (12 SA, 22 SA, 32 SA, Terme)
  resolvToken += "<tr><td>" + TR(" Grossesse à déclarer avant la 15éme SA ") + "</td><td>";
  dt = DDR.addDays( 15 * 7 );
  resolvToken += dt.toString("dd/MM/yyyy") + "</td></tr>";

  resolvToken += "<tr><td>" + TR(" Première échographie entre (12ème SA) ") + "</td><td>";
  dt = DDR.addDays( 12 * 7 );
  resolvToken += dt.toString("dd/MM/yyyy");
  dt = DDR.addDays( 13 * 7 );
  resolvToken += "  --  " + dt.toString("dd/MM/yyyy") + "</td></tr>";

  resolvToken += "<tr><td>" + TR(" Deuxième échographie entre (22ème SA)") + "</td><td>";
  dt = DDR.addDays( 22 * 7 );
  resolvToken += dt.toString("dd/MM/yyyy");
  dt = DDR.addDays( 23 * 7 );
  resolvToken += "  --  " + dt.toString("dd/MM/yyyy") + "</td></tr>";

  resolvToken += "<tr><td>" + TR(" Troisième échographie entre (32ème SA) ") + "</td><td>";
  dt = DDR.addDays( 32 * 7 );
  resolvToken += dt.toString("dd/MM/yyyy");
  dt = DDR.addDays( 33 * 7 );
  resolvToken += "  --  " + dt.toString("dd/MM/yyyy") + "</td></tr>";

  resolvToken += "<tr><td>" + TR(" Trisomie 21 et biomarqueurs entre (14ème-15éme SA) ") + "</td><td>";
  dt = DDR.addDays( 14 * 7 );
  resolvToken += dt.toString("dd/MM/yyyy");
  dt = DDR.addDays( 16 * 7 );
  resolvToken += "  --  " + dt.toString("dd/MM/yyyy") + "</td></tr>";

  resolvToken += "<tr><td>" + TR(" Terme prévu le (41éme SA) ") + "</td><td>";
  dt = DDR.addDays( 41 * 7 );
  resolvToken += "<span style=\"font-weight: 600\">"+dt.toString("dd/MM/yyyy") + "</span></td></tr>";

  //.......... Fini le premier tableau et renvoie le tout pour l'observation
  resolvToken += "</table><br />";


  //.......... Prépare le tableau pour les congés maternités
  resolvToken += "<br /><br /><span style=\"font-weight: 600\">"+TR("Les congés maternités.") + "</span><br /><br /><br />";

  resolvToken += "<table width =\"100%\" border=\"1\" cellpadding=\"2\" cellspacing=\"2\">";
  resolvToken += "<tr><td width =\"50%\">" + TR(" Si moins de trois enfants (6 S / 10 S) ") + "</td><td width =\"25%\">";
  dt = DDR.addDays( (41 - 6) * 7 );
  resolvToken += TR(" du ") + dt.toString("dd/MM/yyyy") + "</td><td width =\"25%\">";
  dt = DDR.addDays( (41 + 10) * 7 );
  resolvToken += TR(" au ") + dt.toString("dd/MM/yyyy") + "</td></tr></table><br /><br />";

  resolvToken += "<table width =\"100%\" border=\"1\" cellpadding=\"2\" cellspacing=\"2\">";
  resolvToken += "<tr><td width =\"50%\">" + TR(" À partir du troisième enfant (8 S / 18 S) ") + "</td><td width =\"25%\">";
  dt = DDR.addDays( (41 - 8) * 7 );
  resolvToken += TR(" du ") + dt.toString("dd/MM/yyyy") + "</td><td width =\"25%\">";
  dt = DDR.addDays( (41 + 18) * 7 );
  resolvToken += TR(" au ") + dt.toString("dd/MM/yyyy") + "</td></tr></table><br /><br />";

  resolvToken += "<table width =\"100%\" border=\"1\" cellpadding=\"2\" cellspacing=\"2\">";
  resolvToken += "<tr><td width =\"50%\">" + TR(" Pour des jumeaux (10 S / 22 S) ") + "</td><td width =\"25%\">";
  dt = DDR.addDays( (41 - 12) * 7 );
  resolvToken += TR(" du ") + dt.toString("dd/MM/yyyy") + "</td><td width =\"25%\">";
  dt = DDR.addDays( (41 + 22) * 7 );
  resolvToken += TR(" au ") + dt.toString("dd/MM/yyyy") + "</td></tr></table><br /><br />";


  resolvToken += "<table width =\"100%\" border=\"1\" cellpadding=\"2\" cellspacing=\"2\">";
  resolvToken += "<tr><td width =\"50%\">" + TR(" Pour des triplés (24 S) ") + "</td><td width =\"25%\">";
  dt = DDR.addDays( (41 - 24) * 7 );
  resolvToken += dt.toString("dd/MM/yyyy") + "</td><td width =\"25%\">";
  dt = DDR.addDays( (41 + 22) * 7 );
  resolvToken += TR(" au ") + dt.toString("dd/MM/yyyy") + "</td></tr>";

  //.......... Fini le premier tableau et renvoie le tout pour l'observation
  resolvToken += "</table><br />";

  return resolvToken;
}

