/*
 * ui.c
 *
 * ============================================================================
 * Copyright (c) Texas Instruments Inc 2005
 *
 * Use of this software is controlled by the terms and conditions found in the
 * license agreement under which this software has been supplied or provided.
 * ============================================================================
 */

/* Standard Linux headers */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <errno.h>

/* Demo headers */
#include <simplewidget.h>
#include "rotate_demo.h"
#include "ui.h"

/* The font size */
#define PTSIZE                20

/* Button pictures in different states */
#define FILE_CTRL             "data/pics/Buttons_SQ.png"
#define FILE_CTRLPAUSE        "data/pics/Pause_SQ_SEL.png"
#define FILE_CTRLPLAY         "data/pics/Play_SQ_SEL.png"
#define FILE_CTRLSTOP         "data/pics/Stop_SQ_SEL.png"

#define FILE_NAV              "data/pics/Button_DIAG.png"
#define FILE_NAVMINUS         "data/pics/Left_Diag_SEL.png"
#define FILE_NAVPLUS          "data/pics/Right_Diag_SEL.png"

#define FILE_INFO             "data/pics/INFO_RND.png"

#define FILE_WRONG            "data/pics/nowrongbutton.png"
#define FILE_WRONGPRESSED     "data/pics/wrongbutton.png"

/* The strings to draw on the screen */
#define ARMLOADSTRING         "ARM CPU load:"
#define DSPLOADSTRING         "DSP CPU load:"
#define FPSSTRING             "Video frame rate:"
#define TIMESTRING            "Time elapsed:"

#define DEMONAMESTRING        "Rotate Demo"
#define NOCODECSTRING         "Pass through video"
#define ALGOSTRING            "ROTATE_TI algorithm"
#define NTSCDISPLAYSTRING     "NTSC display"
#define PALDISPLAYSTRING      "PAL display"

/* Button placements on OSD */
#define CTRL_BUTTON_X         50
#define CTRL_BUTTON_Y         330

#define NAV_BUTTON_X          290
#define NAV_BUTTON_Y          310

#define INFO_BUTTON_X         570
#define INFO_BUTTON_Y         330

#define WRONG_BUTTON_X        325
#define WRONG_BUTTON_Y        205

/* Describes a ui button */
typedef struct Button {
    simplewidget_png  img;
    int               x;
    int               y;
    struct Button    *origBtn;
} Button; 

/* Local declarations */
static simplewidget_screen  simpleScreens[NUM_BUFS] = { NULL, NULL };
static Button buttons[BTNIDX_NUM];

/******************************************************************************
 * drawText
 ******************************************************************************/
static int drawText(char *string, int x, int y)
{
    if (uiDrawText(string, x, y, 0) == FAILURE) {
        return FAILURE;
    }

    if (uiDrawText(string, x, y, 1) == FAILURE) {
        return FAILURE;
    }

    return SUCCESS;
}

/******************************************************************************
 * createButton
 ******************************************************************************/
static int createButton(char *pressedBtnFileName, int x, int y,
                        BtnIdx pressedBtnIdx, BtnIdx origBtnIdx)
{
    Button *btnPtr = &buttons[pressedBtnIdx];

    btnPtr->x = x;
    btnPtr->y = y;

    if (simplewidget_png_create(pressedBtnFileName,
                                &btnPtr->img) == -1) {
        ERR("Failed to create png image\n");
        return FAILURE;
    }

    if (origBtnIdx == BTNIDX_INVALID) {
        if (simplewidget_png_show(btnPtr->img, simpleScreens[0],
                                  btnPtr->x, yScale(btnPtr->y)) == -1) {
            ERR("Failed to show button png image\n");
            return FAILURE;
        }

        if (simplewidget_png_show(btnPtr->img, simpleScreens[1],
                                  btnPtr->x, yScale(btnPtr->y)) == -1) {
            ERR("Failed to show button png image\n");
            return FAILURE;
        }

        btnPtr->origBtn = NULL;
    }
    else {
        btnPtr->origBtn = &buttons[origBtnIdx];
    }

    return SUCCESS;
}

/******************************************************************************
 * uiClearScreen
 ******************************************************************************/
void uiClearScreen(int x, int y, int w, int h, int screenIdx)
{
    simplewidget_screen_clear(simpleScreens[screenIdx], x, y, w, h);
}

/******************************************************************************
 * uiDrawText
 ******************************************************************************/
int uiDrawText(char *string, int x, int y, int screenIdx)
{
    simplewidget_text simpleText;    

    if (simplewidget_text_create(x, y, PTSIZE, string, &simpleText) == -1) {
        ERR("Failed to create dynamic text\n");
        return FAILURE;
    }

    if (simplewidget_text_show(simpleText, simpleScreens[screenIdx]) == -1) {
        ERR("Failed to draw dynamic text\n");
        return FAILURE;
    }

    simplewidget_text_delete(simpleText);

    return SUCCESS;
}

/******************************************************************************
 * uiPressButton
 ******************************************************************************/
int uiPressButton(BtnIdx btnIdx, int screenIdx)
{
    Button *btnPtr = &buttons[btnIdx];
    Button *origBtnPtr = btnPtr->origBtn;

    if (simplewidget_png_show(btnPtr->img, simpleScreens[screenIdx],
                              btnPtr->x, yScale(btnPtr->y)) == -1) {
        ERR("Failed to show button png image\n");
        return FAILURE;
    }

    usleep(REMOTECONTROLLATENCY);

    if (simplewidget_png_show(origBtnPtr->img, simpleScreens[screenIdx],
                              origBtnPtr->x, yScale(origBtnPtr->y)) == -1) {
        ERR("Failed to show button png image\n");
        return FAILURE;
    }

    return SUCCESS;
}

/******************************************************************************
 * uiCreate
 ******************************************************************************/
int uiCreate(UIParams *uiParams)
{
    char imageSizeString[20];

    memset(buttons, 0, sizeof(Button) * BTNIDX_NUM);

    /* Initialize the screens on which to draw widgets */
    if (simplewidget_screen_init(uiParams->osdDisplays[0], D1_WIDTH,
                                 D1_HEIGHT, &simpleScreens[0]) == -1) {
        ERR("Failed to initialize simplewidget screen\n");
        return FAILURE;
    }

    if (simplewidget_screen_init(uiParams->osdDisplays[1], D1_WIDTH,
                                 D1_HEIGHT, &simpleScreens[1]) == -1) {
        ERR("Failed to initialize simplewidget screen\n");
        uiDelete();
        return FAILURE;
    }

    /* Clear the OSD screens */
    simplewidget_screen_clear(simpleScreens[0], 0, 0, D1_WIDTH, D1_HEIGHT);
    simplewidget_screen_clear(simpleScreens[1], 0, 0, D1_WIDTH, D1_HEIGHT);

    if (createButton(FILE_CTRL, CTRL_BUTTON_X, CTRL_BUTTON_Y,
                     BTNIDX_CTRL, BTNIDX_INVALID) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (createButton(FILE_CTRLPLAY, CTRL_BUTTON_X, CTRL_BUTTON_Y,
                     BTNIDX_CTRLPLAY, BTNIDX_CTRL) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (createButton(FILE_CTRLSTOP, CTRL_BUTTON_X, CTRL_BUTTON_Y,
                     BTNIDX_CTRLSTOP, BTNIDX_CTRL) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (createButton(FILE_CTRLPAUSE, CTRL_BUTTON_X, CTRL_BUTTON_Y,
                     BTNIDX_CTRLPAUSE, BTNIDX_CTRL) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (createButton(FILE_NAV, NAV_BUTTON_X, NAV_BUTTON_Y,
                     BTNIDX_NAV, BTNIDX_INVALID) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (createButton(FILE_NAVMINUS, NAV_BUTTON_X, NAV_BUTTON_Y,
                     BTNIDX_NAVMINUS, BTNIDX_NAV) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (createButton(FILE_NAVPLUS, NAV_BUTTON_X, NAV_BUTTON_Y,
                     BTNIDX_NAVPLUS, BTNIDX_NAV) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (createButton(FILE_INFO, INFO_BUTTON_X, INFO_BUTTON_Y,
                     BTNIDX_INFO, BTNIDX_INVALID) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (createButton(FILE_WRONG, WRONG_BUTTON_X, WRONG_BUTTON_Y,
                     BTNIDX_WRONG, BTNIDX_INVALID) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (createButton(FILE_WRONGPRESSED, WRONG_BUTTON_X, WRONG_BUTTON_Y,
                     BTNIDX_WRONGPRESSED, BTNIDX_WRONG) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    /* Create the text strings to be displayed at the top of the screen */
    if (drawText(ARMLOADSTRING, COLUMN_1, ROW_1) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (drawText(DSPLOADSTRING, COLUMN_1, ROW_2) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (drawText(FPSSTRING, COLUMN_1, ROW_3) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (drawText(TIMESTRING, COLUMN_1, ROW_5) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (drawText(DEMONAMESTRING, COLUMN_3, ROW_1) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (uiParams->passThrough) {
        if (drawText(NOCODECSTRING, COLUMN_3, ROW_2) == FAILURE) {
            uiDelete();
            return FAILURE;
        }
    }
    else {
        if (drawText(ALGOSTRING, COLUMN_3, ROW_2) == FAILURE) {
            uiDelete();
            return FAILURE;
        }
    }

    sprintf(imageSizeString, "%dx%d", uiParams->imageWidth,
                                      uiParams->imageHeight);

    if (drawText(imageSizeString, COLUMN_3, ROW_4) == FAILURE) {
        uiDelete();
        return FAILURE;
    }

    if (gblGetYFactor() == NTSCSTD) {
        if (drawText(NTSCDISPLAYSTRING, COLUMN_3, ROW_3) == FAILURE) {
            uiDelete();
            return FAILURE;
        }
    }
    else {                                                  /* PAL */
        if (drawText(PALDISPLAYSTRING, COLUMN_3, ROW_3) == FAILURE) {
            uiDelete();
            return FAILURE;
        }
    }

    return SUCCESS;
}

/******************************************************************************
 * uiDelete
 ******************************************************************************/
int uiDelete(void)
{
    int i;

    for (i=0; i<BTNIDX_NUM; i++) {
        if (buttons[i].img) {
            simplewidget_png_delete(buttons[i].img);
            buttons[i].img = NULL;
        }
    }

    if (simpleScreens[0]) {
        simplewidget_screen_exit(simpleScreens[0]);
        simpleScreens[0] = NULL;
    }

    if (simpleScreens[1]) {
        simplewidget_screen_exit(simpleScreens[1]);
        simpleScreens[1] = NULL;
    }

    return SUCCESS;
}

