#include "plugin.h"

#if !defined(SIMULATOR)

PLUGIN_HEADER

#if (CONFIG_KEYPAD == IPOD_4G_PAD) || \
      (CONFIG_KEYPAD == IPOD_3G_PAD)
#define PIEZO_QUIT BUTTON_MENU
#define PIEZO_PLAYPAUSE BUTTON_PLAY
#define PIEZO_PITCH_UP BUTTON_SCROLL_FWD
#define PIEZO_PITCH_DOWN BUTTON_SCROLL_BACK
#define PIEZO_PITCH_JUMP_UP BUTTON_RIGHT
#define PIEZO_PITCH_JUMP_DOWN BUTTON_LEFT
#define PIEZO_TAP BUTTON_SELECT
#else
#warning Not for non-ipods
#endif

#define PIEZO_MIN_RATE 1
#define PIEZO_MAX_RATE 4000
#define PIEZO_JUMP 10

static struct plugin_api* rb;

unsigned int piezo_period = 200;

static bool piezo_active = false;
static char buffer[30];

void draw_display(void)
{
    rb->lcd_clear_display();

    rb->lcd_setfont(FONT_SYSFIXED);
    rb->lcd_putsxy(1, 1, "Piezo TEST");
    rb->lcd_puts(0, 4, "Select to beep");
    rb->lcd_puts(0, 6, "Play to toggle");

    
    rb->snprintf(buffer, sizeof(buffer), "period: %d ", piezo_period);
    rb->lcd_puts(0,8, buffer);

    rb->snprintf(buffer, sizeof(buffer), "~hz: %d ", rb->piezo_hz(piezo_period));
    rb->lcd_puts(0,10, buffer);

    rb->snprintf(buffer, sizeof(buffer), "%s", (piezo_active)?"On":"Off");
    rb->lcd_puts(10, 12, buffer);


    rb->lcd_update();

}

void update_period(int increment)
{
    piezo_period = piezo_period + increment;
    if (piezo_period <= PIEZO_MIN_RATE)
        piezo_period = PIEZO_MIN_RATE;
    else if (piezo_period > PIEZO_MAX_RATE)
        piezo_period = PIEZO_MAX_RATE;
    if (piezo_active)
    {
        rb->piezo_stop();
        rb->piezo_play(piezo_period);
    }
    draw_display();
}

enum plugin_status plugin_start(struct plugin_api* api, void* parameter)
{
    int button;

    (void)parameter;
    rb = api;

    draw_display();

    /* main loop */
    while (true){
                    
        button = rb->button_get(true);

        switch (button) {

            case PIEZO_QUIT:
                /* get out of here */
                rb->piezo_clear();
                rb->piezo_stop();
                return PLUGIN_OK;

            case PIEZO_PLAYPAUSE:
                if (piezo_active)
                {
                    rb->piezo_stop();
                    piezo_active = false;
                    draw_display();
                }
                else
                {
                    rb->piezo_play(piezo_period);
                    piezo_active = true;
                    draw_display();
                }
                break;

            case PIEZO_TAP:
            case PIEZO_TAP | BUTTON_REPEAT:
                if (!piezo_active)
                {
                    rb->piezo_play(piezo_period);
                    piezo_active = true;
                    draw_display();
                }
                break;

            case PIEZO_TAP | BUTTON_REL:
                if (piezo_active)
                {
                    rb->piezo_stop();
                    piezo_active = false;
                    draw_display();
                }
                break; 

            case PIEZO_PITCH_UP | BUTTON_REPEAT:
                update_period(1);
                break;

            case PIEZO_PITCH_DOWN | BUTTON_REPEAT:
                update_period(-1);
                break;

            case PIEZO_PITCH_JUMP_UP:
            case PIEZO_PITCH_JUMP_UP | BUTTON_REPEAT:
                update_period(PIEZO_JUMP);
                break;

            case PIEZO_PITCH_JUMP_DOWN:
            case PIEZO_PITCH_JUMP_DOWN | BUTTON_REPEAT:
                update_period(-PIEZO_JUMP);
                break;

            default:
                if (rb->default_event_handler(button) == SYS_USB_CONNECTED)
                    return PLUGIN_USB_CONNECTED;
                break;

        }
    }
}
#endif /* #ifndef SIMULATOR */
