// Ces trois bibliothèques sont indispensables pour le shield
#include <SPI.h>
#include <Ethernet.h>
#include <SD.h>  // Pour la communication avec la carte SD

// Fonctions permettant la lecture de fichiers html sur la carte SD
// et leur envoi (avec modifications éventuelles) sur le port éthernet
#include "trthtml.h"

// Broche CS de la carte SD
const byte SDCARD_CS_PIN = 4; // pour Arduino UNO c'est quelquefois indiqué 10

// L'adresse MAC du shield
byte mac[] = { 0x90, 0xA2, 0xDA, 0xHH, 0xHH, 0xHH };

// L'adresse IP que prendra le shield
IPAddress ip (192, 168, n1, n2);

// Notre serveur écoutera sur le port 80
EthernetServer serveur (80);

// valeur numérique convertie en chaine de caractères
char valconv [10];

// valeurs des mesures
int vit_vent;
int dir_vent, angle_rel;


// affiche l'adresse IP sur le moniteur série
void affiche_ip ()
{
    int i;

    for (i = 0; i < 4; )
    {
        Serial.print (ip [i]);

        if (++ i < 4)
             Serial.print (F("."));
    }

    Serial.println ();
}


// pour convertir une valeur entière en chaine de caractères

char *conv_int_str (int valeur)
{
    sprintf (valconv, "%d", valeur);
    return (valconv);
}


// pour convertir une valeur décimale en chaine de caractères

char *conv_float_str (float valeur)
{
    // sprintf (valconv, "%3.1f", valeur);  // Ne marche pas !
    sprintf (valconv, "%d", (int) valeur);
    return (valconv);
}


// mesures

int mesure_vit_vent ()
{
    // mesure fictive
    return (14);
}

int mesure_dir_vent ()
{
    int mesure;


    // mesure et conversion en angle
    mesure = analogRead (A0) * 360.0 / 1023;

    return (mesure);
}


// origine du vent sous forme textuelle

char * orig_vent (int angle)
{
    // on diminue la précision
    angle = (angle + 22.5) / 45;

    switch (angle)
    {
        case 0 : return ("nord");
                  break;

        case 1 : return ("nord est");
                  break;

        case 2 : return ("est");
                  break;

        case 3 : return ("sud est");
                  break;

        case 4 : return ("sud");
                  break;

        case 5 : return ("sud ouest");
                  break;

        case 6 : return ("ouest");
                  break;

        case 7 : return ("nord ouest");
                  break;

        case 8 : return ("nord");
                  break;

        default : return ("erreur conversion");
    }
}


void setup ()
{
    // On démarre la voie série pour déboguer
    Serial.begin (9600);

    // On démarre le shield Ethernet avec l'adresse IP et l'adresse MAC
    Ethernet.begin (mac, ip);
    Serial.println (F("ethernet ok "));

    // afficher l'adresse IP
    affiche_ip ();

    // Initialisation du port SPI
    pinMode (SDCARD_CS_PIN, OUTPUT);

    // Initialisation de la carte SD
    Serial.print (F("Initialisation carte SD   "));

    if (!SD.begin (SDCARD_CS_PIN))
        Serial.println (F("Echec !"));
    else
        Serial.println (F("Succès"));

    // laisse du temps au shield pour s'initialiser
    delay (100);

    // on lance le serveur
    serveur.begin ();
    delay (100);

    Serial.println (F("Pret !"));
}


void loop ()
{
    EthernetClient client;
    char fic_html [] = "metvent.htm";
    File descfic;


    // Regarde si un client est connecté et attend une réponse
    client = serveur.available ();

    // si c'est le cas, quelqu'un est connecté
    if (client)
    {
        // récupérer ce qu'il a envoyé
        lire_trame_client (client);

        // envoi de l'entête de la page web
        envoie_entete_reponse (client);

        // tenter d'accéder à au fichier HTML
        descfic = SD.open (fic_html, FILE_READ);

        // si on n'a pas réussi, tenter la page d'erreur
        if (! descfic)
            descfic = SD.open (F("err404.htm"), FILE_READ);

        // si on accède au fichier html
        if (descfic)
        {
            // faire les mesures
            vit_vent = mesure_vit_vent ();
            dir_vent = mesure_dir_vent ();

            // angle du vent sous forme relative
            angle_rel = dir_vent;

            if (angle_rel > 180)
                angle_rel = angle_rel - 360;

            // envoi de la page
            coprep_chaine (descfic, client, "XXXVIT",  conv_int_str (vit_vent));
            coprep_chaine (descfic, client, "XXXANGLE", conv_int_str (angle_rel));
            coprep_chaine (descfic, client, "XXXORIGV", orig_vent (dir_vent));
            copie_jusque_fin (descfic, client);

            // ferner le fichier HTML
            descfic.close ();
        }
        // sinon message d'erreur
        else
            client.println (F("Probleme probable d'acces a la carte SD"));

        Serial.println (F("Page envoyée\n"));

        // Donne le temps au client de prendre les données
        delay (10);

        // Ferme la connexion avec le client
        client.stop ();
    }
}