/**
  ******************************************************************************
  * @file demo_pwm.c
  * @brief This file contains all the functions for the PWM demo.
  * @author STMicroelectronics - MCD Application Team
  * @version V1.1.0
  * @date    09/14/2009
  ******************************************************************************
  *
  */

// Includes ------------------------------------------------------------------
#include "demo_pwm.h"

// Private typedef -----------------------------------------------------------
// Private define ------------------------------------------------------------
// Private macro -------------------------------------------------------------
// Private variables ---------------------------------------------------------
// Private function prototypes -----------------------------------------------
// Private functions ---------------------------------------------------------
#define NB_NOTES (15)

uint8_t NotesPos[NB_NOTES];
uint8_t ModifEnabled;

  // * @addtogroup Demo_Functions
void PWMDEMO_Exec(void)
{

    JOYSTICK_ID_T KeyJ1, KeyJ2;
    const Melody_TypeDef *pMelody;
    const /*static*/ Melody_TypeDef *pMelody_old;
    uint8_t max;
    uint8_t melody_index;
    uint8_t Melody_played =0;
				
    LCD_Clear();
		WaitDelay(50);
    LCD_PrintString(LCD_LINE1, ENABLE, DISABLE, " Select Melody");

    // Search how many melodies are present 
    pMelody = MELODIES;
    max = 0;
    while (pMelody->Name != 0)
    {
        max++;
        pMelody++;
    }

    pMelody = MELODIES;
    pMelody_old = MELODIES + 1;
    melody_index = 0;

    while (1)
    {
        if (pMelody != pMelody_old)
        {
            LCD_ClearLine(LCD_LINE2);
            LCD_SetCursorPos(LCD_LINE2, 0);
            LCD_PrintString(LCD_LINE2, ENABLE, DISABLE, pMelody->Name);
            pMelody_old = pMelody;
        }

        KeyJ1 = ReadJoystick();

        if (KeyJ1 == UP)
        {
            MenuUpdate(UP);
						LEDS_OFF();
            return;
        }

        if (KeyJ1 == LEFT)
        {
            if (pMelody == MELODIES) /* begin of list */
            {
                pMelody = MELODIES + (max - 1); /* point to last melody */
                melody_index = (uint8_t)(max - 1);
            }
            else
            {
                pMelody--;
                melody_index--;
            }
        }

        if (KeyJ1 == RIGHT)
        {
            pMelody++;
            melody_index++;
            if (pMelody->Name == 0) /* end of list */
            {
                pMelody = MELODIES; /* point to the first melody */
                melody_index = 0;
            }
        }

        if (KeyJ1 == SEL)
        {
					  LEDS_OFF();
						LED4_ON();
            LCD_ClearLine(LCD_LINE1);
            LCD_SetCursorPos(LCD_LINE1, 0);
            LCD_PrintString(LCD_LINE1, ENABLE, DISABLE, "Play...");

            PlayMelody(pMelody->Notes);

            LCD_ClearLine(LCD_LINE1);
            LCD_SetCursorPos(LCD_LINE1, 0);
            LCD_PrintString(LCD_LINE1, ENABLE, DISABLE, " Select Melody");
						Melody_played = 1;
        }
				while ((KeyJ1 == J_NONE )&&(Melody_played ==1))
        {
				LEDS_OFF();
				LED4_ON();
				LED3_ON();
				KeyJ2 = ReadJoystick();
				WaitDelay(50);
				if (KeyJ2 != J_NONE)
        {
				Melody_played =0;
			  }
        }
    }
}

void PwmPlayMelody(uint8_t *notes, uint8_t dn)
{

    uint8_t pos = 0;
    uint8_t octave = 4;
    uint16_t duration;
    uint16_t duration_short = DURATION_2;
    uint16_t duration_long = DURATION_3;
    uint8_t *pNote;
    uint8_t note_to_play;
    JOYSTICK_ID_T Key;
    uint8_t Counter = 0;

    pNote = notes;

    while (1)
    {

        if (dn == 1)
        {
            PwmDisplayNotesPos(pos);
        }
#ifdef ENABLE_MELODY_CALLBACK
        else
        {
            MelodyCallBack();
        }
#endif

        if ((pNote[0] == MELODY_END_CHAR) || (pNote[0] == MELODY_LOOP_CHAR))
        {
            return;
        }

        if (*pNote > (uint8_t)0x60) /* lower-case letters */
        {
            duration = duration_short;
            note_to_play = *pNote;
        }
        else /* upper-case letters */
        {
            duration = duration_long;
            note_to_play = (uint8_t)(*pNote + (uint8_t)0x20); /* Change in lower-case */
        }

        // The note letter is changed in lower-case 
        PlayNote(note_to_play, octave, duration);

        pNote++;
        pos++;

        if (*pNote == MELODY_END_CHAR) /* end melody */
        {
            return;
        }

        if ((*pNote == MELODY_LOOP_CHAR) || (*pNote == MELODY_NULL_CHAR)) /* loop melody */
        {
            pNote = notes;
            pos = 0;
            switch (Counter)
            {
            case 0:
                octave = 3;
                duration_short = DURATION_2;
                duration_long = DURATION_3;
                break;
            case 1:
                octave = 4;
                duration_short = DURATION_3;
                duration_long = DURATION_4;
                break;
            case 2:
                octave = 3;
                duration_short = DURATION_3;
                duration_long = DURATION_4;
                break;
            case 3:
                octave = 4;
                duration_short = DURATION_1;
                duration_long = DURATION_2;
                break;
            case 4:
                octave = 3;
                duration_short = DURATION_1;
                duration_long = DURATION_2;
                break;
            case 5:
                octave = 4;
                duration_short = DURATION_1;
                duration_long = DURATION_1;
                break;
            default:
                Counter = 0;
                octave = 4;
                duration_short = DURATION_2;
                duration_long = DURATION_3;
                break;
            }
            Counter++;
        }

        // Exit melody 
        Key = ReadJoystick();
        if ((Key != J_NONE) && (Key != J_RELEASED))
        {
            return;
        }

    }

}
void PwmDisplayNotesPos(uint8_t pos)
{
    uint8_t i;
    if (pos > (NB_NOTES - 1))
    {
        pos = (NB_NOTES - 1);
    }
    for (i = 0; i < NB_NOTES; i++)
    {
        NotesPos[i] = ' ';
    }
    if (ModifEnabled == 0)
    {
        NotesPos[pos] = 'x';
    }
    else
    {
        NotesPos[pos] = 'o';
    }
    LCD_ClearLine(LCD_LINE1);
    LCD_SetCursorPos(LCD_LINE1, 0);
    LCD_PrintString(LCD_LINE1, DISABLE, DISABLE, NotesPos);
}

