#include <Arduino.h>

// pour obtenir ces valeurs simplement, ouvrir une image bmp565 320x240 (ok) avec l'éditeur Hexa ImHex (Linux)
// sélectionner la partie entête, puis File/export/Text Formatted Bytes/C++ Array
// ce qui est vachement pratique !
const uint8_t bmp565_header[] PROGMEM = 
{
    0x42, 0x4D, 0x8A, 0x58, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x00, 0x00, 0x7C, 0x00, 
    0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0xF0, 0x00, 0x00, 0x00, 0x01, 0x00, 0x10, 0x00, 0x03, 0x00, 
    0x00, 0x00, 0x00, 0x58, 0x02, 0x00, 0x23, 0x2E, 0x00, 0x00, 0x23, 0x2E, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF8, 0x00, 0x00, 0xE0, 0x07, 0x00, 0x00, 0x1F, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x42, 0x47, 0x52, 0x73, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
};
// soit 138 octets


/** ***********************************************************************************
	CLASS 			
***************************************************************************************/

class TOUCH_BOUTON
{
    protected:
        uint8_t dx;
        uint8_t dy;
        uint8_t dr; // rayon de courbure des angles

    public:
        uint16_t x0;
        uint16_t y0;
        uint16_t couleur;

        String label;
        boolean cliked;
        boolean selected;

        uint8_t read_dx();
        uint8_t read_dy();

        TOUCH_BOUTON(); // constructeur

        void init(uint16_t x_i, uint16_t y_i, uint8_t dx_i, uint8_t dy_i, uint8_t dr_i, uint16_t couleur_i);
        void affiche(uint16_t coul_fill_select, uint8_t n_font);

    private:

};



class TOUCH_BOUTON_PRESET : public TOUCH_BOUTON
{
    public:
        uint32_t frequence_SW; // 4 octets
        uint32_t frequence_FM; // 4 octets
        uint32_t frequence_AIR;// 4 octets
       // String nom;
   
        TOUCH_BOUTON_PRESET(); // constructeur

    private:
};



class TOUCH_BOUTON_SW : public TOUCH_BOUTON
{
    public:
        uint32_t freq_A; // 4 octets - fréquence de départ
        uint32_t freq_B; // fréquence de fin de la bande, sans trou
        uint16_t lambda; // longueur d'onde en m
   
        TOUCH_BOUTON_SW(); // constructeur

    private:
};



/** ***************************************************************************************
	CLASS PRESET_PAD  // objet 8 touches d'accès rapide à 8 fréquences favorites adns chaque gamme
********************************************************************************************/
class PRESET_PAD
{
    protected:
        uint8_t dx;
        uint8_t dy;

    public:
        uint8_t x0;
        uint8_t y0;

        TOUCH_BOUTON_PRESET bt_preset[8];
        
        PRESET_PAD(); // constructeur

        void init(uint16_t x0, uint16_t y0);
        uint8_t read_dx();
        uint8_t read_dy();
        void set_frequences_PRST();
        void set_couleurs();

        void deselect_boutons();
        uint8_t test_clic();
        //void traite_presetPad(uint8_t n_touch);

    private:
   
};

/** ***************************************************************************************
	CLASS SW_PAD  // objet 14 boutons de sélection de bandes SW (ondes courtes)
********************************************************************************************/
class SW_PAD
{
    protected:
        uint8_t dx;
        uint8_t dy;

    public:
        uint8_t x0;
        uint8_t y0;

        TOUCH_BOUTON_SW bt_SW[14];
        
        SW_PAD(); // constructeur

        void init(uint16_t x0, uint16_t y0);
        void set_frequences_SW();

        void deselect_boutons();
        uint8_t test_clic();

    private:
   
};

/** ***************************************************************************************
	CLASS NUM_PAD  // objet clavier numérique
********************************************************************************************/

class NUM_PAD
{
    protected:
    

    public:
        uint8_t x0;
        uint8_t y0;

        TOUCH_BOUTON bt_pad[10];
        
        TOUCH_BOUTON bt_point;
	    TOUCH_BOUTON bt_ok;

        NUM_PAD(); // constructeur

        void init(uint16_t x0, uint16_t y0, boolean fond);
        uint8_t test_clic();

    private:
   
};

/** ***************************************************************************************
	CLASS GRID_PAD  // objet grille de boutons
********************************************************************************************/

class GRID_PAD
{
    protected:
    

    public:
        uint8_t x0;
        uint8_t y0;
        uint8_t dxt = 16; // taille x d'un bouton
	    uint8_t dyt = 16; // taille y d'un bouton
        static const uint8_t nb_bt_x = 8; // nombre de boutons x
        static const uint8_t nb_bt_y = 4; // nombre de boutons y
        static const uint8_t nb_t = nb_bt_x * nb_bt_y; //total nombre de boutons

        TOUCH_BOUTON bt_grid[nb_t];

        GRID_PAD(); // constructeur

        void init(uint16_t x0, uint16_t y0);
        void set_couleurs();
        void affiche();
        uint8_t test_clic();

    private:
   
};




/** ***************************************************************************************
	CLASS GROUPE_FREQUENCES  // objet image d'un bloc mémoire en SD
	permet diverses manipulations en RAM (tri...) sans toucher à la mémoire SD (qui est en mémoire flash)				
********************************************************************************************/
class GROUPE_FREQUENCES
{
    public:
        uint32_t G_freq[100];
        uint16_t adr_1ere_frq; // après un tri les F=0 se retrouvent en haut de liste. La 1ere F se retrouve donc bien plus bas
        uint16_t nb_freq; // nombre de fréquences !=0 enregistées
        uint16_t num_F_actuelle;
        String filename; // du fichier en mémoire SD (par exemple "/FRQ_FM.txt")

        GROUPE_FREQUENCES(); // constructeur

        void RAZ();
        void load_bloc(); // depuis SD
        void bloc_to_serial();  // pour tests
        void affiche_bloc(String nom, uint16_t x);
        void tri_bloc(); // par valeur numérique des fréquences
        void add_frq(uint32_t Fi);
        void erase_1_freq(uint32_t Fi);

        boolean test_Frq_presente(uint32_t F_i);
 
    private:

};


// ************************************************************************************


void setup();
void loop();
void printTouchToDisplay(); 
void init_sprites();
void efface_box_entete1();
void efface_box_entete2();
void efface_box_entete3();
void init_affichages();
void affi_image_from_SD(String filename, uint16_t x0, uint16_t y0);
void write_fichier_params(); 
void load_GRP_FREQ_SD(); 
String read_line_params(uint16_t line_num);
int32_t extract_params(String ligne, String label);
void affiche_unit(String s);
void affiche_band(String s);
void affiche_numero_frq(String s1, String s2);
void efface_box_entete2();
void efface_box_entete3();
//void affiche_box_choix_couleur();
//void affi_valeurs_RGB();
void affiche_box_FRQ(uint16_t couleur);
void affiche_box_presets();
void deselect_boutons_presets();
void traite_boutons_presetPad(uint8_t n_bt);
void affi_message(String L1, String L2, String L3, String L4, String L5);
void affiche_box_GROUPE();
void efface_box_GROUPE();
void affiche_box_SD();
void affiche_box_FRQ(uint16_t couleur);
void affiche_frequence(uint32_t frq); // en kHz
void affiche_index_frq();
void affiche_force_signal();
void clic_logiciel_bouton(TOUCH_BOUTON *bouton_i);
void dessine_VuMetre();
void affi_page_info();
void init_box_info();
void test_clic_boutons_BANDE();
void test_clic_bouton_TEST();
void read_FRQ_File(); // en mémoire SD
void scan_frq(uint32_t freq_iA, uint32_t freq_iB, String band_name);
void attente_clic();
void attente_clic2();
void Set_Volume(int v);
void get_XY_touch();
void TS_calibrate();
void liste_codes_PI_RDS();
void retour_normal();