/*  Grafx2 - The Ultimate 256-color bitmap paint program
    Copyright 2008 Peter Gordon
    Copyright 2008 Yves Rizoud
    Copyright 2008 Franck Charlet
    Copyright 2007 Adrien Destugues
    Copyright 1996-2001 Sunset Design (Guillaume Dorme & Karl Maritaud)
    Grafx2 is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    as published by the Free Software Foundation; version 2
    of the License.
    Grafx2 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.  See the
    GNU General Public License for more details.
    You should have received a copy of the GNU General Public License
    along with Grafx2; if not, see  or
    write to the Free Software Foundation, Inc.,
    59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/
#include 
#include 
#if defined(__WIN32__)
    #include 
#elif defined(__macosx__)
    #include 
    #include 
#elif defined (__linux__)
    #include 
#endif
#include "const.h"
#include "struct.h"
#include "global.h"
#include "divers.h"
#include "graph.h"
#include "moteur.h"
#include "tables_aide.h"
#include "aide.h"
#include "sdlscreen.h"
#include "texte.h"
#include "clavier.h"
#include "windows.h"
extern char SVNRevision[];
// Recherche un raccourci clavier:
word * Raccourci(word NumeroRaccourci)
{
  if (NumeroRaccourci & 0x100)
    return &(Bouton[NumeroRaccourci & 0xFF].Raccourci_gauche);
  if (NumeroRaccourci & 0x200)
    return &(Bouton[NumeroRaccourci & 0xFF].Raccourci_droite);
  return &(Config_Touche[NumeroRaccourci & 0xFF]);
}
// Nom de la touche actuallement assignée à un raccourci d'après son numéro
// de type 0x100+BOUTON_* ou SPECIAL_*
const char * Valeur_Raccourci_Clavier(word NumeroRaccourci)
{
  word * Pointeur = Raccourci(NumeroRaccourci);
  if (Pointeur == NULL)
    return "(Problem)";
  else if (*Pointeur == 0 || *Pointeur == 0xFFFF)
    return "None";
  else
    return Nom_touche(*Pointeur);
}
// -- Menu d'aide -----------------------------------------------------------
void Afficher_aide(void)
{
  short  X;                   // Indices d'affichage d'un caractère
  short  Y;
  short  Position_X;          // Parcours de remplissage du buffer de ligne
  short  Indice_de_ligne;     // 0-15 (16 lignes de textes)
  short  Indice_de_caractere; // Parcours des caractères d'une ligne
  short  Ligne_de_depart=Position_d_aide_en_cours;
  short  Repeat_Menu_Facteur_X;
  short  Repeat_Menu_Facteur_Y;
  short  Pos_Reel_X;
  short  Pos_Reel_Y;
  int    Curseur;
  short  Largeur;             // Largeur physique d'une ligne de texte
  char   TypeLigne;           // N: Normale, T: Titre, S: Sous-titre
                              // -: Ligne inférieur de sous-titre
  const char * Ligne;
  char   Buffer[44];          // Buffer texte utilisé pour formater les noms de 
                              // raccourcis clavier
  short  Position_lien=0;     // Position du premier caractère "variable"
  short  Taille_lien=0;       // Taille de la partie variable
  Pos_Reel_X=Fenetre_Pos_X+(13*Menu_Facteur_X);
  Pos_Reel_Y=Fenetre_Pos_Y+(19*Menu_Facteur_Y);
  for (Indice_de_ligne=0;Indice_de_ligne<16;Indice_de_ligne++)
  {
    // Raccourci au cas ou la section fait moins de 16 lignes
    if (Indice_de_ligne >= Table_d_aide[Section_d_aide_en_cours].Nombre_de_lignes)
    {
      Block (Pos_Reel_X,
           Pos_Reel_Y,
           44*6*Menu_Facteur_X,
           // 44 = Nb max de char (+1 pour éviter les plantages en mode X
           // causés par une largeur = 0)
           (Menu_Facteur_Y<<3) * (16 - Indice_de_ligne),
           CM_Noir);
      break;
    }
    // On affiche la ligne
    Ligne = Table_d_aide[Section_d_aide_en_cours].Table_aide[Ligne_de_depart + Indice_de_ligne].texte;
    TypeLigne = Table_d_aide[Section_d_aide_en_cours].Table_aide[Ligne_de_depart + Indice_de_ligne].type;
    // Si c'est une sous-ligne de titre, on utilise le texte de la ligne précédente
    if (TypeLigne == '-' && (Ligne_de_depart + Indice_de_ligne > 0))
      Ligne = Table_d_aide[Section_d_aide_en_cours].Table_aide[Ligne_de_depart + Indice_de_ligne - 1].texte;
    else if (TypeLigne == 'K')
    {
      const char *Lien;
      Position_lien = strstr(Ligne,"%s") - Ligne;
      Lien=Valeur_Raccourci_Clavier(Table_d_aide[Section_d_aide_en_cours].Table_aide[Ligne_de_depart + Indice_de_ligne].valeur);
      Taille_lien=strlen(Lien);
      sprintf(Buffer, Ligne, Lien);
      Ligne = Buffer;
    }
    
    // Calcul de la taille
    Largeur=strlen(Ligne);
    // Les lignes de titres prennent plus de place
    if (TypeLigne == 'T' || TypeLigne == '-')
      Largeur = Largeur*2;
    // Pour chaque ligne dans la fenêtre:
    for (Y=0;Y<8;Y++)
    {
      Position_X=0;
      // On crée une nouvelle ligne à splotcher
      for (Indice_de_caractere=0;Indice_de_caractere 315)
          Curseur = 1; // '!' affiché pour les caractères non prévus
        
        for (X=0;X<6;X++)
          for (Repeat_Menu_Facteur_X=0;Repeat_Menu_Facteur_X=Position_lien
              && Indice_de_caractere<(Position_lien+Taille_lien))
            {
              if (Couleur == CM_Clair)
                Couleur=CM_Blanc;
              else if (Couleur == CM_Fonce)
                Couleur=CM_Clair;
              else if (Y<7)
                Couleur=CM_Fonce;
            }
            Buffer_de_ligne_horizontale[Position_X++]=Couleur;
            if (Pixel_width==2)
              Buffer_de_ligne_horizontale[Position_X++]=Couleur;
          }
      }
      // On la splotche
      for (Repeat_Menu_Facteur_Y=0;Repeat_Menu_Facteur_YPosition=Position_d_aide_en_cours;
  Calculer_hauteur_curseur_jauge(Fenetre_Liste_boutons_scroller);
  Fenetre_Dessiner_jauge(Fenetre_Liste_boutons_scroller);
  Afficher_aide();
  Afficher_curseur();
}
void Bouton_Aide(void)
{
  short Numero_bouton;
  
  // Aide contextuelle
  if (Touche!=0)
  {
    Numero_bouton = Numero_bouton_sous_souris();
    if (Numero_bouton != -1)
    {
      Fenetre_aide(Numero_bouton, NULL);
      return;
    }
  }
  Fenetre_aide(-1, NULL);
}
// Ouvre l'ecran d'aide. Passer -1 pour la section par défaut (ou derniere,)
// Ou un nombre de l'enumération NUMEROS_DE_BOUTONS pour l'aide contextuelle.
void Fenetre_aide(int Section, const char *Sous_section)
{
  short Bouton_clicke;
  short Nb_lignes;
  if (Section!=-1)
  {
    Section_d_aide_en_cours = 4 + Section;
    Position_d_aide_en_cours = 0;
  }
  Nb_lignes=Table_d_aide[Section_d_aide_en_cours].Nombre_de_lignes;
  if (Section!=-1 && Sous_section!=NULL)
  {
    int Indice=0;
    for (Indice=0; Indice2)
        {
          Section_d_aide_en_cours=Bouton_clicke-3;
          Position_d_aide_en_cours=0;
          Nb_lignes=Table_d_aide[Section_d_aide_en_cours].Nombre_de_lignes;
          Fenetre_Liste_boutons_scroller->Position=0;
          Fenetre_Liste_boutons_scroller->Nb_elements=Nb_lignes;
          Calculer_hauteur_curseur_jauge(Fenetre_Liste_boutons_scroller);
          Fenetre_Dessiner_jauge(Fenetre_Liste_boutons_scroller);
        }
        else
          Position_d_aide_en_cours=Fenetre_Attribut2;
        Afficher_aide();
        Afficher_curseur();
    }
    // Gestion des touches de déplacement dans la liste
    switch (Touche)
    {
      case SDLK_UP : // Haut
        if (Position_d_aide_en_cours>0)
          Position_d_aide_en_cours--;
        Scroller_aide();
        break;
      case SDLK_DOWN : // Bas
        if (Position_d_aide_en_cours15)
          Position_d_aide_en_cours-=15;
        else
          Position_d_aide_en_cours=0;
        Scroller_aide();
        break;
      case SDLK_PAGEDOWN : // PageDown
        if (Position_d_aide_en_cours (100ULL*1024*1024*1024))
        sprintf(Buffer,"%d Gigabytes",(unsigned int)(freeRam/(1024*1024*1024)));
  else if(freeRam > (100*1024*1024))
        sprintf(Buffer,"%d Megabytes",(unsigned int)(freeRam/(1024*1024)));
  else if(freeRam > 100*1024)
        sprintf(Buffer,"%d Kilobytes",(unsigned int)(freeRam/1024));
  else
        sprintf(Buffer,"%d bytes",(unsigned int)freeRam);
  Print_dans_fenetre(114,51,Buffer,STATS_COULEUR_DONNEES,CM_Noir);
  // Affichage de l'espace disque libre
  sprintf(Buffer,"Free space on %c:",Principal_Repertoire_courant[0]);
  Print_dans_fenetre(10,67,Buffer,STATS_COULEUR_TITRES,CM_Noir);
#if defined(__WIN32__)
    {
      ULARGE_INTEGER tailleU;
      GetDiskFreeSpaceEx(Principal_Repertoire_courant,&tailleU,NULL,NULL);
      Taille = tailleU.QuadPart;
    }
#elif defined(__linux__) || (__macosx__)
    // Note: under MacOSX, both macros are defined anyway.
    {
      struct statfs Informations_Disque;
      statfs(Principal_Repertoire_courant,&Informations_Disque);
      Taille=(uint64_t) Informations_Disque.f_bfree * (uint64_t) Informations_Disque.f_bsize;
    }
#else
    // Free disk space is only for shows. Other platforms can display 0.
    Taille=0;
#endif
  
    if(Taille > (100ULL*1024*1024*1024))
        sprintf(Buffer,"%d Gigabytes",(unsigned int)(Taille/(1024*1024*1024)));
    else if(Taille > (100*1024*1024))
        sprintf(Buffer,"%d Megabytes",(unsigned int)(Taille/(1024*1024)));
    else if(Taille > (100*1024))
        sprintf(Buffer,"%d Kilobytes",(unsigned int)(Taille/1024));
    else 
        sprintf(Buffer,"%d bytes",(unsigned int)Taille);
    Print_dans_fenetre(146,67,Buffer,STATS_COULEUR_DONNEES,CM_Noir);
  // Affichage des informations sur l'image
  Print_dans_fenetre(10,83,"Picture info.:",STATS_COULEUR_TITRES,CM_Noir);
  // Affichage des dimensions de l'image
  Print_dans_fenetre(18,91,"Dimensions :",STATS_COULEUR_TITRES,CM_Noir);
  sprintf(Buffer,"%dx%d",Principal_Largeur_image,Principal_Hauteur_image);
  Print_dans_fenetre(122,91,Buffer,STATS_COULEUR_DONNEES,CM_Noir);
  // Affichage du nombre de couleur utilisé
  Print_dans_fenetre(18,99,"Colors used:",STATS_COULEUR_TITRES,CM_Noir);
  memset(Utilisation_couleur,0,sizeof(Utilisation_couleur));
  sprintf(Buffer,"%d",Palette_Compter_nb_couleurs_utilisees(Utilisation_couleur));
  Print_dans_fenetre(122,99,Buffer,STATS_COULEUR_DONNEES,CM_Noir);
  // Affichage des dimensions de l'écran
  Print_dans_fenetre(10,115,"Resolution:",STATS_COULEUR_TITRES,CM_Noir);
  sprintf(Buffer,"%dx%d",Largeur_ecran,Hauteur_ecran);
  Print_dans_fenetre(106,115,Buffer,STATS_COULEUR_DONNEES,CM_Noir);
  UpdateRect(Fenetre_Pos_X,Fenetre_Pos_Y,Menu_Facteur_X*310,Menu_Facteur_Y*174);
  Afficher_curseur();
  do
  {
    Bouton_clicke=Fenetre_Bouton_clicke();
  }
  while ( (Bouton_clicke!=1) && (Touche!=SDLK_RETURN) );
  Fermer_fenetre();
  Desenclencher_bouton(BOUTON_AIDE);
  Afficher_curseur();
}