/*
 * Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
 *
 * Licensed under the Apache License, Version 2.0 (the License);
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "config.h"
#include "../inc/tone-player-view.h"
#include "../../common/inc/main-app.h"

#include <tone_player.h>
#include <Elementary.h>
#include <Ecore.h>

#define BUTTON_DTMF_KEY "DTMF"
#define TIMER_TIME 0.195
#define MAX_TONE_DURATION 5000
#define MIN_TONE_DURATION 200
#define TONE_VOLUME 1.0
#define TABLE_PADDING_VERTICAL 20
#define TABLE_PADDING_HORIZONTAL 20

struct _tone_player_view
{
    Elm_Object_Item *frame_item;
    Evas_Object *navi;
    Evas_Object *layout;
    app_data *app;
    int tone_handle;
    int play_index;
    Ecore_Timer *timer;

    Evas_Object *play_btn;
    Evas_Object *stop_btn;
    Evas_Object *pause_btn;
};

static const tone_type_e _tone_list[] =
{
    TONE_TYPE_DTMF_0,
    TONE_TYPE_DTMF_1,
    TONE_TYPE_DTMF_2,
    TONE_TYPE_DTMF_3,
    TONE_TYPE_DTMF_4,
    TONE_TYPE_DTMF_5,
    TONE_TYPE_DTMF_6,
    TONE_TYPE_DTMF_7,
    TONE_TYPE_DTMF_8,
    TONE_TYPE_DTMF_9,
    TONE_TYPE_DTMF_S,
    TONE_TYPE_DTMF_P,
    TONE_TYPE_DTMF_A,
    TONE_TYPE_DTMF_B,
    TONE_TYPE_DTMF_C,
    TONE_TYPE_DTMF_D
};

static int _tone_list_size = sizeof(_tone_list) / sizeof(tone_type_e);

static void _push(tone_player_view *view);
static void _register_app_cbs(tone_player_view *view);
static void _destroy(tone_player_view *view);
static Evas_Object *_add_main_layout(tone_player_view *view, Evas_Object *parent);
static Evas_Object *_add_keypad_layout(tone_player_view *view, Evas_Object *parent);
static Evas_Object *_add_control_layout(tone_player_view *view, Evas_Object *parent);

static Evas_Object *_add_btn(tone_player_view *view, Evas_Object *parent, const char *name, Evas_Smart_Cb cb);
static Evas_Object *_add_control_btn(tone_player_view *view, Evas_Object *parent, const char *name, Evas_Smart_Cb cb);
static Evas_Object *_add_keypad_btn(tone_player_view *view, Evas_Object *parent, const char *name, tone_type_e tone);
static void _disable_control_button(tone_player_view *view, bool play, bool pause, bool stop);

static void _on_main_layout_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _on_keypad_btn_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _on_keypad_btn_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static Eina_Bool _on_timer_cb(void *data);

static void _on_pause_cb(void *user_data);
static void _on_pause_btn_pressed_cb(void *data, Evas_Object *obj, void *event_info);
static void _on_stop_btn_pressed_cb(void *data, Evas_Object *obj, void *event_info);
static void _on_play_btn_pressed_cb(void *data, Evas_Object *obj, void *event_info);

static void _play_tone_list(tone_player_view *view);
static void _pause_tone_list(tone_player_view *view);
static void _stop_tone_list(tone_player_view *view);

tone_player_view *tone_player_view_add(app_data *app, Evas_Object *navi)
{
    tone_player_view *view = calloc(1, sizeof(tone_player_view));
    if(view)
    {
        view->navi = navi;
        view->app = app;
        view->layout = _add_main_layout(view, navi);

        if(view->layout)
        {
            _register_app_cbs(view);
            view->timer = ecore_timer_add(TIMER_TIME, _on_timer_cb, view);
            ecore_timer_freeze(view->timer);
            evas_object_event_callback_add(view->layout, EVAS_CALLBACK_DEL, _on_main_layout_del_cb, view);
            _push(view);
        }
        else
        {
            _destroy(view);
            return NULL;
        }
    }

    return view;
}

static void _register_app_cbs(tone_player_view *view)
{
    app_cbs cbs =
    {
       .pause = _on_pause_cb,
       .resume = NULL
    };

    app_set_cbs(view->app, cbs, view);
}

static void _destroy(tone_player_view *view)
{
    app_reset_cbs(view->app);
    if(view->timer)
    {
        ecore_timer_del(view->timer);
    }
    free(view);
}

static void _push(tone_player_view *view)
{
    Elm_Object_Item *item = elm_naviframe_item_push(view->navi, "Tone player", NULL, NULL, view->layout, NULL);
    view->frame_item = item;
}

static void _play_tone_list(tone_player_view *view)
{
    ecore_timer_reset(view->timer);
    ecore_timer_thaw(view->timer);
    _disable_control_button(view, true, false, false);
}

static void _pause_tone_list(tone_player_view *view)
{
    ecore_timer_freeze(view->timer);
    _disable_control_button(view, false, true, false);
}

static void _stop_tone_list(tone_player_view *view)
{
    ecore_timer_freeze(view->timer);
    view->play_index = 0;
    _disable_control_button(view, false, true, true);
}

static Eina_Bool _on_timer_cb(void *data)
{
    tone_player_view *view = data;

    if(view)
    {
        int handle = 0;
        tone_player_start(_tone_list[view->play_index], SOUND_TYPE_MEDIA, MIN_TONE_DURATION, &handle);
        ++view->play_index;

        if(view->play_index == _tone_list_size)
        {
            view->play_index = 0;
            ecore_timer_freeze(view->timer);
            _disable_control_button(view, false, true, true);
        }
    }

    return EINA_TRUE;
}

static Evas_Object *_add_btn(tone_player_view *view, Evas_Object *parent, const char *name, Evas_Smart_Cb cb)
{
    Evas_Object *btn = elm_button_add(parent);
    elm_object_text_set(btn, name);
    evas_object_show(btn);
    evas_object_smart_callback_add(btn, "clicked", cb, view);
    return btn;
}

static Evas_Object *_add_keypad_btn(tone_player_view *view, Evas_Object *parent, const char *name, tone_type_e tone)
{
    Evas_Object *btn = _add_btn(view, parent, name, NULL);

    evas_object_size_hint_expand_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_fill_set(btn, EVAS_HINT_FILL, 0.5);

    evas_object_event_callback_add(btn, EVAS_CALLBACK_MOUSE_DOWN, _on_keypad_btn_down_cb, view);
    evas_object_event_callback_add(btn, EVAS_CALLBACK_MOUSE_UP, _on_keypad_btn_up_cb, view);

    evas_object_data_set(btn, BUTTON_DTMF_KEY, (void*)tone);
    return btn;
}

static Evas_Object *_add_control_btn(tone_player_view *view, Evas_Object *parent, const char *name, Evas_Smart_Cb cb)
{
    Evas_Object *btn = _add_btn(view, parent, name, cb);

    evas_object_size_hint_expand_set(btn, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_fill_set(btn, EVAS_HINT_FILL, 0.0);

    return btn;
}

static void _on_keypad_btn_down_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
    tone_player_view *view = data;
    if(view)
    {
        tone_player_stop(view->tone_handle);

        tone_type_e tone = (tone_type_e)evas_object_data_get(obj, BUTTON_DTMF_KEY);
        tone_player_start(tone, SOUND_TYPE_MEDIA, MAX_TONE_DURATION, &view->tone_handle);
    }
}

static void _on_keypad_btn_up_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
    tone_player_view *view = data;
    if(view)
    {
        tone_player_stop(view->tone_handle);
    }
}

static Evas_Object *_add_keypad_layout(tone_player_view *view, Evas_Object *parent)
{
    Evas_Object *table = elm_table_add(parent);

    evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
    evas_object_show(table);

    elm_table_padding_set(table, TABLE_PADDING_HORIZONTAL, TABLE_PADDING_VERTICAL);

    Evas_Object *btn;

    btn = _add_keypad_btn(view, table, "1", TONE_TYPE_DTMF_1);
    elm_table_pack(table, btn, 0, 0, 1, 1);

    btn = _add_keypad_btn(view, table, "2", TONE_TYPE_DTMF_2);
    elm_table_pack(table, btn, 1, 0, 1, 1);

    btn = _add_keypad_btn(view, table, "3", TONE_TYPE_DTMF_3);
    elm_table_pack(table, btn, 2, 0, 1, 1);

    btn = _add_keypad_btn(view, table, "4", TONE_TYPE_DTMF_4);
    elm_table_pack(table, btn, 0, 1, 1, 1);

    btn = _add_keypad_btn(view, table, "5", TONE_TYPE_DTMF_5);
    elm_table_pack(table, btn, 1, 1, 1, 1);

    btn = _add_keypad_btn(view, table, "6", TONE_TYPE_DTMF_6);
    elm_table_pack(table, btn, 2, 1, 1, 1);

    btn = _add_keypad_btn(view, table, "7", TONE_TYPE_DTMF_7);
    elm_table_pack(table, btn, 0, 2, 1, 1);

    btn = _add_keypad_btn(view, table, "8", TONE_TYPE_DTMF_8);
    elm_table_pack(table, btn, 1, 2, 1, 1);

    btn = _add_keypad_btn(view, table, "9", TONE_TYPE_DTMF_9);
    elm_table_pack(table, btn, 2, 2, 1, 1);

    btn = _add_keypad_btn(view, table, "*", TONE_TYPE_DTMF_S);
    elm_table_pack(table, btn, 0, 3, 1, 1);

    btn = _add_keypad_btn(view, table, "0", TONE_TYPE_DTMF_0);
    elm_table_pack(table, btn, 1, 3, 1, 1);

    btn = _add_keypad_btn(view, table, "#", TONE_TYPE_DTMF_P);
    elm_table_pack(table, btn, 2, 3, 1, 1);

    return table;
}

static Evas_Object *_add_control_layout(tone_player_view *view, Evas_Object *parent)
{
    Evas_Object *table = elm_table_add(parent);

    evas_object_size_hint_weight_set(table, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_align_set(table, EVAS_HINT_FILL, EVAS_HINT_FILL);
    evas_object_show(table);

    elm_table_padding_set(table, TABLE_PADDING_HORIZONTAL, TABLE_PADDING_VERTICAL);

    view->play_btn = _add_control_btn(view, table, "Play", _on_play_btn_pressed_cb);
    elm_table_pack(table, view->play_btn, 0, 0, 1, 1);

    view->pause_btn = _add_control_btn(view, table, "Pause", _on_pause_btn_pressed_cb);
    elm_object_disabled_set(view->pause_btn, EINA_TRUE);
    elm_table_pack(table, view->pause_btn, 1, 0, 1, 1);

    view->stop_btn = _add_control_btn(view, table, "Stop", _on_stop_btn_pressed_cb);
    elm_object_disabled_set(view->stop_btn, EINA_TRUE);
    elm_table_pack(table, view->stop_btn, 2, 0, 1, 1);

    return table;
}

static Evas_Object *_add_main_layout(tone_player_view *view, Evas_Object *parent)
{
    Evas_Object *layout = elm_layout_add(parent);

    elm_layout_file_set(layout, TONEEDJ, "tone_player");
    evas_object_show(layout);

    Evas_Object *number = _add_keypad_layout(view, layout);
    elm_object_part_content_set(layout, "keypad_part", number);

    Evas_Object *control = _add_control_layout(view, layout);
    elm_object_part_content_set(layout, "controlr_part", control);

    return layout;
}

static void _on_main_layout_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
    tone_player_view *view = data;

    if(view)
    {
        _destroy(view);
    }
}

static void _on_pause_btn_pressed_cb(void *data, Evas_Object *obj, void *event_info)
{
    if(data)
    {
        _pause_tone_list(data);
    }
}

static void _on_stop_btn_pressed_cb(void *data, Evas_Object *obj, void *event_info)
{
    if(data)
    {
        _stop_tone_list(data);
    }
}

static void _on_play_btn_pressed_cb(void *data, Evas_Object *obj, void *event_info)
{
    if(data)
    {
        _play_tone_list(data);
    }
}

static void _on_pause_cb(void *user_data)
{
    if(user_data)
    {
        _pause_tone_list(user_data);
    }
}

static void _disable_control_button(tone_player_view *view, bool play, bool pause, bool stop)
{
    elm_object_disabled_set(view->play_btn, play);
    elm_object_disabled_set(view->pause_btn, pause);
    elm_object_disabled_set(view->stop_btn, stop);
}
