/****************************************************************************
** ui.h extension file, included from the uic-generated form implementation.
**
** If you wish to add, delete or rename functions or slots use
** Qt Designer which will update this file, preserving your code. Create an
** init() function in place of a constructor, and a destroy() function in
** place of a destructor.
*****************************************************************************/

#define SEPARATOR_DAY_HEIGHT 20
#define W_OFSET 20
#define V_OFSET 2
#define Min(a, b)             ((a) < (b) ? (a) : (b))
#define Max(a, b)             ((a) > (b) ? (a) : (b))
#include "../../MedinTuxTools/Theme.h"

//---------------------------------------- init --------------------------------------------
void Wdg_AgendaDay::init()
{//QString path_img = G_pCApp->m_PathAppli + "Images" + QDir::separator();
 m_RDV_List.setAutoDelete(TRUE);
 m_RDV_List.clear();
 //m_Wdg_RendezVous_LIST.setAutoDelete(TRUE);
 m_Wdg_RendezVous_LIST.clear();
 m_ExpandHeight   = SEPARATOR_DAY_HEIGHT;
 m_Height         = SEPARATOR_DAY_HEIGHT;
 m_ResoPix        = 1;
 m_DayNoExpand    = Theme::getIcon("RightExpandArrow.xpm");
 m_DayIsExpand    = Theme::getIcon("DownExpandArrow.xpm");
 m_DayNewRDV      = Theme::getIcon("DayNewRDV.xpm");
 m_FileSave       = Theme::getIcon("filesave.xpm");
 m_pCMoteurAgenda = 0;
}

//---------------------------------------- GetRDV_List -------------------------------------------
int Wdg_AgendaDay::RDV_Get_List(QDate date)
{
 if (m_pCMoteurAgenda == 0) return 0;
 return m_pCMoteurAgenda->RDV_Get_List(date, G_pCApp->m_SignUser, m_RDV_List);
}

//---------------------------------------- initDialog --------------------------------------------
void Wdg_AgendaDay::initDialog(QDate date, MAP_COLOR *colorProfils, CMoteurAgenda *pCMoteurAgenda)
{m_Date           = date;
 m_pColorProfils  = colorProfils;
 m_pCMoteurAgenda = pCMoteurAgenda;
 QString str_date = SetTitle();
 /*
 if (str_date.left(3) == "sam")
    {textLabel_Titre->setPaletteBackgroundColor (QColor("#9fcebd"));
    }
 if (str_date.left(3) == "dim")
    {textLabel_Titre->setPaletteBackgroundColor (QColor("#49d1a1"));
    }
 */

 m_ButtonDate = new CMyButton(this, str_date, this);
 m_ButtonDate->setGeometry(2,0,20,SEPARATOR_DAY_HEIGHT);
 m_ButtonDate->setFlat( TRUE );
 m_ButtonDate->setPixmap(m_DayNoExpand);
 QToolTip::add( m_ButtonDate,   tr("Ouvre et ferme une page de l'agenda") );

 m_ButtonNewRDV = new CMyButton(this, str_date, this);
 m_ButtonNewRDV->setGeometry(22,0,20,SEPARATOR_DAY_HEIGHT);
 m_ButtonNewRDV->setFlat( TRUE );
 m_ButtonNewRDV->setPixmap(m_DayNewRDV);
 QToolTip::add( m_ButtonNewRDV,  tr("Ajouter un nouveau rendez-vous à cette date") );

 m_ButtonSave = new CMyButton(this, str_date, this);
 m_ButtonSave->setGeometry(42,0,20,SEPARATOR_DAY_HEIGHT);
 m_ButtonSave->setFlat( TRUE );
 m_ButtonSave->setPixmap(m_FileSave);
 QString str = tr("Enregistrer ce jour comme modèle de jour pour le ") + m_pCMoteurAgenda->dayOfWeek(date.dayOfWeek());
 QToolTip::add( m_ButtonSave,  str );

 connect( m_ButtonNewRDV, SIGNAL( Sign_ButtonClickedPtr (const char*, void *)  ),
          this ,          SLOT(   OnButtonNewRDVClickedPtr (const char*, void *)  )
        );
 connect( m_ButtonSave, SIGNAL(   Sign_ButtonClickedPtr (const char*, void *)  ),
          this ,          SLOT(   OnButtonSaveClickedPtr (const char*, void *)  )
        );
 if (CMoteurBase::IsThisDroitExist(G_pCApp->m_Droits, "agv")) {m_ButtonDate->setEnabled(TRUE); }
 else                                                         {m_ButtonDate->setEnabled(FALSE);}
 if (CMoteurBase::IsThisDroitExist(G_pCApp->m_Droits, "agc")) {m_ButtonSave->setEnabled(TRUE);  m_ButtonNewRDV->setEnabled(TRUE);}
 else                                                         {m_ButtonSave->setEnabled(FALSE); m_ButtonNewRDV->setEnabled(FALSE);}
 m_Default_labelColor = textLabel_Titre->paletteBackgroundColor();
 m_ButtonNewRDV->hide();
 m_ButtonSave->hide();
 m_Height = SEPARATOR_DAY_HEIGHT;
 resize(1278, m_Height );

}

//---------------------------------------- OnButtonSaveClickedPtr --------------------------------------------
void Wdg_AgendaDay::OnButtonSaveClickedPtr (const char*, void *)
{ if (m_pCMoteurAgenda->m_DataBase->isOpen()==FALSE && m_pCMoteurAgenda->m_DataBase->open()==FALSE) return ;  // forcer ouverture base

 m_pCMoteurAgenda->GotoDebug();
 //................ effacer toutes les entrées de ce jour de la semaine ........................
 m_pCMoteurAgenda->MASK_DayDelete( m_Date.dayOfWeek(), G_pCApp->m_SignUser);
 //.................. enregistrer tous les rendez-vous de ce jour ..............................
 //                   comme modele pour ce jour
 Wdg_RendezVous *pWdg_RendezVous;
 for ( pWdg_RendezVous = m_Wdg_RendezVous_LIST.first(); pWdg_RendezVous; pWdg_RendezVous = m_Wdg_RendezVous_LIST.next() )
     {m_pCMoteurAgenda->MASK_Append(*(pWdg_RendezVous->m_pRendezVous));
     }
}
//---------------------------------------- MaskDayToAgendaDay --------------------------------------------
int Wdg_AgendaDay::MaskDayToAgendaDay ()
{RDV_LIST rdvList;
 int nb = m_pCMoteurAgenda->MASK_GetDay_RDV_List(m_Date,  G_pCApp->m_SignUser, rdvList);

 //.................. enregistrer tous les rendez-vous modeles de ce jour de la semaine ..............................
 //                   comme rendez-vous pour cette date
 RendezVous *pRendezVous;
 for ( pRendezVous = rdvList.first(); pRendezVous; pRendezVous = rdvList.next() )
     {m_pCMoteurAgenda->RDV_Create(*pRendezVous);
     }
 if (nb)
    {RDV_Get_List(m_Date);
    }
 return nb;
}

//---------------------------------------- ExpandDialog --------------------------------------------
void Wdg_AgendaDay::ExpandDialog()
{
 if (m_Height==SEPARATOR_DAY_HEIGHT)
    //............................... SI déjà replié alors expandre et construire la liste des rendez vous .........................
    {int nb = m_RDV_List.count();
	{nb = RDV_Get_List(m_Date);               // soit il existe dejà des RDV pour cette journée et alors on les prend
         if (nb==0) nb = MaskDayToAgendaDay ();   // soit il en existe pas et on place le masque de la semaine prévu (si il existe)
         RecreateRendezVousListWidget(1);
        }
     m_Height = m_ExpandHeight;
     m_ButtonDate->setPixmap(m_DayIsExpand);
     m_ButtonNewRDV->show();
     m_ButtonSave->show();
     //QFont new_font(  textLabel_Titre->font() );
     //new_font.setBold( TRUE );
     //textLabel_Titre->setFont( new_font );
     textLabel_Titre->setPaletteBackgroundColor (QColor("#ddf5ff"));
    }
 else
    //............................... SI déjà expandé alors replier et détruire la liste des rendez vous .........................
    {m_Height = SEPARATOR_DAY_HEIGHT;
     m_ButtonDate->setPixmap(m_DayNoExpand);
     m_ButtonNewRDV->hide();
     m_ButtonSave->hide();
     //QFont new_font(  textLabel_Titre->font() );
     //new_font.setBold( FALSE );
     //textLabel_Titre->setFont( new_font );
     destroyAll_RDV();
     textLabel_Titre->setPaletteBackgroundColor (m_Default_labelColor);
    }
 if (CMoteurBase::IsThisDroitExist(G_pCApp->m_Droits, "agc")) {m_ButtonSave->setEnabled(TRUE);  m_ButtonNewRDV->setEnabled(TRUE);}
 else                                                         {m_ButtonSave->setEnabled(FALSE); m_ButtonNewRDV->setEnabled(FALSE);}

 resize(1278, m_Height );
}

//---------------------------------------- RecreateRendezVousListWidget --------------------------------------------
int Wdg_AgendaDay::RecreateRendezVousListWidget(int isToCreate)
{        RendezVous *pRendezVous;
         QDateTime referTime(m_Date, QTime(00,00));
	 QDateTime lastTimeEnd  = referTime;
         bool       firstTime   = TRUE;
         int  espace_libre      = 0;
         int dayHeight          = m_pCMoteurAgenda->GetDaysHeight();
         int spaceBetweenDay    = m_pCMoteurAgenda->GetSpaceBetwenDays();
         m_ExpandHeight         = SEPARATOR_DAY_HEIGHT;

	 for ( pRendezVous   = m_RDV_List.first(); pRendezVous; pRendezVous = m_RDV_List.next() )
             {//............... on cree le rendez vous .......................................
              Wdg_RendezVous * pWdg_RendezVous = new Wdg_RendezVous(this);
              pWdg_RendezVous->initDialog(pRendezVous, m_ResoPix, m_pColorProfils,  m_pCMoteurAgenda->GetMinDaysHeight(), m_pCMoteurAgenda->GetDaysHeight());  // cela positionne aussi sa hauteur en pixels
              m_Wdg_RendezVous_LIST.append( pWdg_RendezVous );
              //............... si première fois on determine le temps de reference au premier RDV (pour ne pas afficher les vides avant) ...............................
              if (firstTime)  {referTime   = pRendezVous->m_date; firstTime = FALSE; lastTimeEnd = referTime;}
              //.............. on postionne le rendez vous à sa place .............................................................
              //               à la suite de l'autre + l'espace libre
              //               à ce niveau m_ExpandHeight pointe apres le dernier RDV place .......................................
              if (spaceBetweenDay)
                 { espace_libre    = (lastTimeEnd.secsTo(pRendezVous->m_date)/60) * spaceBetweenDay;  // espace libre entre le dernier et celui actuel
                   m_ExpandHeight += espace_libre;
                 }
              pWdg_RendezVous->move(W_OFSET, m_ExpandHeight);
              pWdg_RendezVous->show();
              m_ExpandHeight   +=  pWdg_RendezVous->height();
              lastTimeEnd       =  pRendezVous->m_date.addSecs(pRendezVous->m_Duree*60);
              connect( pWdg_RendezVous, SIGNAL( Sign_RendezVousDeleteClicked(Wdg_RendezVous*)  ),
                       this ,           SLOT(   OnRendezVousDeleteClicked(Wdg_RendezVous*)  )
                     );
              connect( pWdg_RendezVous, SIGNAL( Sign_RendezVousChangeClicked(Wdg_RendezVous*)  ),
                       this ,           SLOT(   OnRendezVousChangeClicked(Wdg_RendezVous*)  )
                     );
              connect( pWdg_RendezVous, SIGNAL( Sign_RendezVousAccederClicked(Wdg_RendezVous*)  ),
                       this ,           SLOT(   OnRendezVousAccederClicked(Wdg_RendezVous*)  )
                     );
             }
         m_ExpandHeight += V_OFSET;
         return m_ExpandHeight;
}

//---------------------------------------- OnRendezVousAccederClicked --------------------------------------------
void Wdg_AgendaDay::OnRendezVousAccederClicked(Wdg_RendezVous *pWdg_RendezVous)
{emit Sign_RendezVousAccederClicked(pWdg_RendezVous);
}

//---------------------------------------- OnRendezVousDeleteClicked --------------------------------------------
void Wdg_AgendaDay::OnRendezVousDeleteClicked(Wdg_RendezVous *pWdg_RendezVous)
{        //.......... effacer de la base de données ..........................
         if (m_pCMoteurAgenda->m_DataBase->isOpen()==FALSE && m_pCMoteurAgenda->m_DataBase->open()==FALSE) return ;  // forcer ouverture base

         m_pCMoteurAgenda->RDV_Delete(pWdg_RendezVous->m_pRendezVous->m_PrimKey);
         //.......... effacer de la liste des RDV ............................
         m_RDV_List.remove(pWdg_RendezVous->m_pRendezVous);
         //.......... effacer de la liste des Widget .........................
         m_Wdg_RendezVous_LIST.remove(pWdg_RendezVous);
         pWdg_RendezVous->reparent (0, 0, QPoint(0,0), FALSE );
         delete   pWdg_RendezVous;    // pas besoin si autodelete
         //.......... rearanger les Widget ...................................
         QDateTime referTime(m_Date, QTime(00,00));
         QDateTime lastTimeEnd  = referTime;
         bool       firstTime   = TRUE;
         int  espace_libre      = 0;
         int dayHeight          = m_pCMoteurAgenda->GetDaysHeight();
         int spaceBetweenDay    = m_pCMoteurAgenda->GetSpaceBetwenDays();
         m_ExpandHeight         = SEPARATOR_DAY_HEIGHT;

         for ( pWdg_RendezVous = m_Wdg_RendezVous_LIST.first(); pWdg_RendezVous; pWdg_RendezVous = m_Wdg_RendezVous_LIST.next() )
             {//............... si première fois on determine le temps de reference au premier RDV (pour ne pas afficher les vides avant)...............................
              if (firstTime)  {referTime   = pWdg_RendezVous->m_pRendezVous->m_date; firstTime = FALSE; lastTimeEnd = referTime;}
              //.............. on postionne le rendez vous à sa place .............................................................
              //               à la suite de l'autre + l'espace libre
              //               à ce niveau m_ExpandHeight pointe apres le dernier RDV place .......................................
              if (spaceBetweenDay)
                 { espace_libre    = (lastTimeEnd.secsTo(pWdg_RendezVous->m_pRendezVous->m_date)/60) * spaceBetweenDay;  // espace libre entre le dernier et celui actuel
                   m_ExpandHeight += espace_libre;
                 }
              pWdg_RendezVous->move(W_OFSET, m_ExpandHeight);
              pWdg_RendezVous->show();
              m_ExpandHeight   +=  pWdg_RendezVous->height();
              lastTimeEnd       =  pWdg_RendezVous->m_pRendezVous->m_date.addSecs(pWdg_RendezVous->m_pRendezVous->m_Duree*60);
             }
        SetTitle();
        m_ExpandHeight += V_OFSET;
        m_Height        =  m_ExpandHeight;
        resize(1278, m_Height );
        emit Sign_DayChanged(this);
}

//---------------------------------------- OnButtonNewRDVClickedPtr --------------------------------------------
void Wdg_AgendaDay::OnButtonNewRDVClickedPtr (const char*, void*)
{if (m_pCMoteurAgenda->m_DataBase->isOpen()==FALSE && m_pCMoteurAgenda->m_DataBase->open()==FALSE) return ;  // forcer ouverture base
 Dlg_RDV_Manager *dlg = new Dlg_RDV_Manager(this, "RDV_Dialog", TRUE);

 if (dlg==0) return;
 RendezVous rendezVous(QDateTime(m_Date, QTime(8,00)),   // date
                       15,                               // duree
                       G_pCApp->m_LastNom,               // nom
                       G_pCApp->m_LastPrenom ,           // prenom,
                       G_pCApp->m_LastTel,               // tel,
                       "",                               // note,
                       G_pCApp->m_LastGUID,              // guid,
                       G_pCApp->m_User,                  // prisPar,
                       G_pCApp->m_SignUser,              // prisAvec,
                       "",                               // type,
                       ""                                // primKey
                      );
 dlg->initDialog(m_pCMoteurAgenda, &m_RDV_List, &rendezVous, m_pColorProfils, 1);   // mode = 1 pour création
 if (dlg->exec()== QDialog::Accepted)
    {QString pk = m_pCMoteurAgenda->RDV_IsThisRendezVousExist(rendezVous);
     if (pk.length()==0)
        {m_pCMoteurAgenda->RDV_Create(rendezVous);
        }
     else
        {rendezVous.m_PrimKey = pk;
         m_pCMoteurAgenda->RDV_Update(rendezVous);
        }
     SetTitle();
     destroyAll_RDV();
     RDV_Get_List(m_Date);
     RecreateRendezVousListWidget(1);
     m_Height = m_ExpandHeight;
     resize(1278, m_Height );
     emit Sign_DayChanged(this);
    }
 delete dlg;
}

//---------------------------------------- OnRendezVousChangeClicked --------------------------------------------
void Wdg_AgendaDay::OnRendezVousChangeClicked(Wdg_RendezVous *pWdg_RendezVous)
{if (m_pCMoteurAgenda->m_DataBase->isOpen()==FALSE && m_pCMoteurAgenda->m_DataBase->open()==FALSE) return ;  // forcer ouverture base
 Dlg_RDV_Manager *dlg = new Dlg_RDV_Manager(this, "RDV_Dialog", TRUE);

 if (dlg==0) return;

 //.......... si modif d'un RDV vide alors le renseigner avec le patient courant ...................
 //           cas des jours avec RDV masques préétablis
 if (pWdg_RendezVous->m_pRendezVous->m_Nom.length() == 0 )
    {pWdg_RendezVous->m_pRendezVous->m_GUID           = G_pCApp->m_LastGUID;
     pWdg_RendezVous->m_pRendezVous->m_Nom            = G_pCApp->m_LastNom;
     pWdg_RendezVous->m_pRendezVous->m_Prenom         = G_pCApp->m_LastPrenom;
     pWdg_RendezVous->m_pRendezVous->m_Tel            = G_pCApp->m_LastTel;
    }
 dlg->initDialog(m_pCMoteurAgenda, &m_RDV_List, pWdg_RendezVous->m_pRendezVous, m_pColorProfils, 0);   // mode = à pour Modification)
 RendezVous rendezVousSave = *pWdg_RendezVous->m_pRendezVous;

 if (dlg->exec()== QDialog::Accepted)
    {m_pCMoteurAgenda->RDV_Update(*pWdg_RendezVous->m_pRendezVous);
     destroyAll_RDV();
     RDV_Get_List(m_Date);
     RecreateRendezVousListWidget(1);
     m_Height = m_ExpandHeight;
     resize(1278, m_Height );
     SetTitle();
     emit Sign_DayChanged(this);
    }
 else
    {*pWdg_RendezVous->m_pRendezVous = rendezVousSave;
    }
 delete dlg;
}

//---------------------------------------- SetTitle -------------------------------------------------------------
QString Wdg_AgendaDay::SetTitle()
{QString str;
 QString str_date;
 if (m_Date==QDate::currentDate())
    {textLabel_Titre->setPaletteForegroundColor(QColor("#960101"));
     textLabel_Titre->setLineWidth ( 2);
     str = "<font color=\"#000000\">";      //002aff   001372 #340fd2 bleu     000000 noir      ff6a42 ORANGE
    }
 else
    {str = "<font color=\"#000000\">";
    }
 //............ affichage du titre du jour ......................................
 str_date = m_Date.toString("ddd dd MMMM yyyy\t") + "</font>";
 str     += str_date;
 RDV_LIST rdvList;
// int nb = m_pCMoteurAgenda->RDV_Get_List(m_Date, G_pCApp->m_SignUser, rdvList, CMoteurAgenda::DateWhithAnyName);
int nb = m_pCMoteurAgenda->RDV_Get_ListNb(m_Date, G_pCApp->m_SignUser);
 if (nb>0)
    {//str += "<font color=\"#340fd2\"><u>" + QString::number(nb) + tr(" rendez-vous pour cette date</u></font>");
     str +=  " = <font color=\"#000000\"><i>" + QString::number(nb) + tr(" rendez-vous pour cette date</i></font>");
    }
 if (str_date.left(3) == "sam")
    {textLabel_Titre->setPaletteBackgroundColor (QColor("#9fcebd"));
    }
 if (str_date.left(3) == "dim")
    {textLabel_Titre->setPaletteBackgroundColor (QColor("#49d1a1"));
    }
 textLabel_Titre->setText( str );
 return str;
}

//---------------------------------------- GetSize --------------------------------------------
void Wdg_AgendaDay::GetSize(int &w, int &h)
{w = 200;
 h = GetHeight();
}

//---------------------------------------- GetHeight --------------------------------------------
int Wdg_AgendaDay::GetHeight()
{ return m_Height;
}


//---------------------------------------- destroy --------------------------------------------
void Wdg_AgendaDay::destroy()
{destroyAll_RDV();
}

//---------------------------------------- destroyAll_RDV --------------------------------------------
void Wdg_AgendaDay::destroyAll_RDV()
{//.................. effacer la liste de widget des rendez vous .....................
 //          (les reparenter sur zero pour eviter plantage lors destruction agenda )
 Wdg_RendezVous *pWdg_RendezVous;
 for ( pWdg_RendezVous = m_Wdg_RendezVous_LIST.first(); pWdg_RendezVous; pWdg_RendezVous = m_Wdg_RendezVous_LIST.next() )
     {pWdg_RendezVous->reparent (0, 0, QPoint(0,0), FALSE );
      delete   pWdg_RendezVous;    // pas besoin si autodelete
     }
 m_Wdg_RendezVous_LIST.clear();
 m_RDV_List.clear();
}
