/*
 * 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 "../inc/radio-popup.h"
#include "../inc/logger.h"
#include "../inc/ui-utils.h"

#include <string.h>
#include <efl_extension.h>

#define STR_OK "OK"
#define CONTENT_SIZE_RATIO 0.25

typedef struct
{
    char *text;
    int val;
    radio_popup *parent;
} genlist_item_data;

struct _radio_popup
{
    Evas_Object *parent;
    Evas_Object *popup;
    Evas_Object *genlist;
    Evas_Object *radio_group;
    Elm_Genlist_Item_Class *item_class;
    genlist_item_data *item_list;
    bool deleting;
    void *cb_user_data;
    radio_popup_item_selected_cb selected_cb;
    radio_popup_closed_cb closed_cb;
};

static Evas_Object *_popup_add(radio_popup *obj, Evas_Object *parent, Elm_Popup_Orient orient, const char *title);
static Evas_Object *_content_layout_add(radio_popup *obj, Evas_Object *parent);
static void _close(radio_popup *obj, bool result);

static char *_gl_text_get(void *data, Evas_Object *obj, const char *part);
static Evas_Object *_gl_content_get(void *data, Evas_Object *obj, const char *part);
static void _gl_delete(void *data, Evas_Object *obj);
static void _gl_select(void *data, Evas_Object *obj, void *event_info);

static void _on_main_layout_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info);
static void _on_ok_btn_cb(void *data, Evas_Object *obj, void *event_info);
static void _on_hw_back_btn_cb(void *data, Evas_Object *obj, void *event_info);

radio_popup *radio_popup_add(Evas_Object *parent, Elm_Popup_Orient orient, const char *title)
{
    radio_popup *obj = calloc(1, sizeof(radio_popup));
    if(obj)
    {
        obj->parent = parent;
        obj->popup = _popup_add(obj, parent, orient, title);
    }

    return obj;
}

void radio_popup_del(radio_popup *obj)
{
    if(obj && !obj->deleting)
    {
        obj->deleting = true;
        evas_object_event_callback_del(obj->popup, EVAS_CALLBACK_DEL, _on_main_layout_del_cb);
        elm_genlist_clear(obj->genlist);
        evas_object_del(obj->popup);
        free(obj);
    }
}

Elm_Object_Item * radio_popup_item_add(radio_popup *obj, const char *text, int val)
{
    Elm_Object_Item *result = NULL;
    if(obj)
    {
        genlist_item_data *item_data = calloc(1, sizeof(genlist_item_data));

        item_data->text = strdup(text);
        item_data->val = val;
        item_data->parent = obj;

        result = elm_genlist_item_append(obj->genlist, obj->item_class, item_data, NULL, ELM_GENLIST_ITEM_NONE, _gl_select, obj);
    }
    return result;
}

void radio_popup_select_item(radio_popup *obj, int radio_val)
{
    if(obj)
    {
        elm_radio_value_set(obj->radio_group, radio_val);
    }
}

void radio_popup_show(radio_popup *obj)
{
    evas_object_show(obj->popup);
}

void radio_popup_callback_set(radio_popup *obj, radio_popup_item_selected_cb selected_cb,
        radio_popup_closed_cb closed_cb, const void *user_data)
{
    if(obj)
    {
        obj->selected_cb = selected_cb;
        obj->closed_cb = closed_cb;
        obj->cb_user_data = (void*)user_data;
    }
}

int radio_popup_selected_item_value_get(const radio_popup *obj)
{
    return obj ? elm_radio_value_get(obj->radio_group) : 0;
}

static Evas_Object *_popup_add(radio_popup *obj, Evas_Object *parent, Elm_Popup_Orient orient, const char *title)
{
    Evas_Object *popup = elm_popup_add(parent);
    elm_popup_orient_set(popup, orient);

    evas_object_size_hint_weight_set(popup, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);

    elm_object_part_text_set(popup, "title,text", title ? title : "");
    evas_object_event_callback_add(popup, EVAS_CALLBACK_DEL, _on_main_layout_del_cb, obj);

    Evas_Object * button = elm_button_add(popup);
    elm_object_text_set(button, STR_OK);
    evas_object_smart_callback_add(button, "clicked", _on_ok_btn_cb, obj);
    elm_object_part_content_set(popup, "button1", button);

    eext_object_event_callback_add(popup, EEXT_CALLBACK_BACK, _on_hw_back_btn_cb, obj);

    Evas_Object *content = _content_layout_add(obj, popup);
    elm_object_content_set(popup, content);

    return popup;
}

static void _close(radio_popup *obj, bool result)
{
    if(obj->closed_cb)
    {
        obj->closed_cb(obj, result, obj->cb_user_data);
    }
}

static Evas_Object *_content_layout_add(radio_popup *obj, Evas_Object *parent)
{
    Evas_Object *box = elm_box_add(parent);
    evas_object_size_hint_weight_set(box, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_align_set(box, EVAS_HINT_FILL, EVAS_HINT_FILL);
    evas_object_show(box);

    int h = 0;
    evas_object_geometry_get(obj->parent, NULL, NULL, NULL, &h);

    evas_object_size_hint_min_set(box, 0, h * CONTENT_SIZE_RATIO);

    obj->genlist = elm_genlist_add(parent);

    elm_genlist_mode_set(obj->genlist, ELM_LIST_COMPRESS);
    elm_genlist_multi_select_set(obj->genlist, EINA_FALSE);
    evas_object_size_hint_weight_set(obj->genlist, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    evas_object_size_hint_align_set(obj->genlist, EVAS_HINT_FILL, EVAS_HINT_FILL);
    evas_object_show(obj->genlist);

    obj->item_class = elm_genlist_item_class_new();

    obj->item_class->item_style = NULL; // elm_list default style
    obj->item_class->func.text_get = _gl_text_get;
    obj->item_class->func.content_get = _gl_content_get;
    obj->item_class->func.state_get = NULL;
    obj->item_class->func.del = _gl_delete;

    obj->radio_group = elm_radio_add(obj->genlist);
    evas_object_hide(obj->radio_group);

    elm_box_pack_start(box, obj->genlist);

    return box;
}

static char *_gl_text_get(void *data, Evas_Object *obj, const char *part)
{
    genlist_item_data *item_data = data;

    if(item_data && strcmp(part, "elm.text") == 0)
    {
        return strdup(item_data->text);
    }
    return NULL;
}

static Evas_Object *_gl_content_get(void *data, Evas_Object *obj, const char *part)
{
    genlist_item_data *item_data = data;

    if(item_data && strcmp(part, "elm.swallow.icon") == 0)
    {
        Evas_Object *rd = elm_radio_add(obj);
        evas_object_show(rd);
        elm_radio_state_value_set(rd, item_data->val);
        elm_radio_group_add(rd, item_data->parent->radio_group);

        evas_object_freeze_events_set(rd, EINA_TRUE);
        evas_object_repeat_events_set(rd, EINA_TRUE);
        return rd;
    }

    return NULL;
}

static void _gl_delete(void *data, Evas_Object *obj)
{
    genlist_item_data *item_data = data;
    RETM_IF(!item_data, "item_data is null");

    free(item_data->text);
    free(item_data);
}

static void _gl_select(void *data, Evas_Object *obj, void *event_info)
{
    Elm_Object_Item *it = elm_genlist_selected_item_get(obj);
    if(it)
    {
        elm_genlist_item_selected_set(it, EINA_FALSE);

        genlist_item_data *item_data = elm_object_item_data_get(it);
        if(item_data && item_data->parent)
        {
            Evas_Object *radio_group = item_data->parent->radio_group;
            elm_radio_value_set(radio_group, item_data->val);

            if(item_data->parent->selected_cb)
            {
                item_data->parent->selected_cb(item_data->parent, item_data->parent->cb_user_data);
            }
        }
    }
}

static void _on_hw_back_btn_cb(void *data, Evas_Object *obj, void *event_info)
{
    radio_popup *popup = data;
    if(popup)
    {
        _close(popup, false);
    }
}

static void _on_main_layout_del_cb(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
    radio_popup *popup = data;
    if(popup)
    {
        radio_popup_del(popup);
    }
}

static void _on_ok_btn_cb(void *data, Evas_Object *obj, void *event_info)
{
    radio_popup *popup = data;
    if(popup)
    {
        _close(popup, true);
    }
}

