/*
 * Copyright (C) 2008 INdT - Instituto Nokia de Tecnologia
 * Copyright (C) 2009, 2010 ProFUSION embedded systems
 * Copyright (C) 2009, 2010, 2011 Samsung Electronics
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#include "EWebKit.h"

#include <ctype.h>
#include <Ecore.h>
#include <Ecore_Evas.h>
#include <Ecore_File.h>
#include <Ecore_Getopt.h>
#include <Ecore_X.h>
#include <Edje.h>
#include <Evas.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#define DEFAULT_WIDTH      800
#define DEFAULT_HEIGHT     600
#define DEFAULT_ZOOM_INIT  1.0

#define info(format, args...)       \
    do {                            \
        if (verbose)                \
            printf(format, ##args); \
    } while (0)

#define MIN_ZOOM_LEVEL 0
#define DEFAULT_ZOOM_LEVEL 5
#define MAX_ZOOM_LEVEL 13

static int currentZoomLevel = DEFAULT_ZOOM_LEVEL;
static float currentZoom = 1.0;

// the zoom values are chosen to be like in Mozilla Firefox 3
static int zoomLevels[] = {30, 50, 67, 80, 90,
                            100,
                            110, 120, 133, 150, 170, 200, 240, 300};

static int verbose = 0;

static Eina_List *windows = NULL;

static char *themePath = NULL;

static const char *backingStores[] = {
    "tiled",
    "single",
    NULL
};

typedef struct _Window_Properties {
    Eina_Bool toolbarsVisible:1;
    Eina_Bool statusbarVisible:1;
    Eina_Bool scrollbarsVisible:1;
    Eina_Bool menubarVisible:1;
} Window_Properties;

Window_Properties windowProperties = { /* Pretend we have them and they are initially visible */
    EINA_TRUE,
    EINA_TRUE,
    EINA_TRUE,
    EINA_TRUE
};

static const Ecore_Getopt options = {
    "EWebLauncher",
    "%prog [options] [url]",
    "0.0.1",
    "(C)2008 INdT (The Nokia Technology Institute)\n"
    "(C)2009, 2010 ProFUSION embedded systems\n"
    "(C)2009, 2010, 2011 Samsung Electronics",
    "GPL",
    "Test Web Browser using the Enlightenment Foundation Libraries of WebKit",
    EINA_TRUE, {
        ECORE_GETOPT_STORE_STR
            ('e', "engine", "ecore-evas engine to use."),
        ECORE_GETOPT_CALLBACK_NOARGS
            ('E', "list-engines", "list ecore-evas engines.",
             ecore_getopt_callback_ecore_evas_list_engines, NULL),
        ECORE_GETOPT_CHOICE
            ('b', "backing-store", "choose backing store to use.", backingStores),
        ECORE_GETOPT_STORE_DEF_BOOL
            ('f', "flattening", "frame flattening.", 0),
        ECORE_GETOPT_STORE_DEF_BOOL
            ('F', "fullscreen", "fullscreen mode.", 0),
        ECORE_GETOPT_CALLBACK_ARGS
            ('g', "geometry", "geometry to use in x:y:w:h form.", "X:Y:W:H",
             ecore_getopt_callback_geometry_parse, NULL),
        ECORE_GETOPT_STORE_STR
            ('t', "theme", "path to read the theme file from."),
        ECORE_GETOPT_STORE_STR
            ('U', "user-agent", "custom user agent string to use."),
        ECORE_GETOPT_STORE_DEF_BOOL
            ('S', "sudo-workaround", "Workaround mode for making Flash work with sudo.", 0),
        ECORE_GETOPT_COUNT
            ('v', "verbose", "be more verbose."),
        ECORE_GETOPT_VERSION
            ('V', "version"),
        ECORE_GETOPT_COPYRIGHT
            ('R', "copyright"),
        ECORE_GETOPT_LICENSE
            ('L', "license"),
        ECORE_GETOPT_HELP
            ('h', "help"),
        ECORE_GETOPT_SENTINEL
    }
};

typedef struct _Viewport {
    int w;
    int h;
    float initScale;
    float minScale;
    float maxScale;
    float devicePixelRatio;
    Eina_Bool userScalable;
} Viewport;

typedef struct _ELauncher {
    Ecore_Evas *ee;
    Evas *evas;
    Evas_Object *bg;
    Evas_Object *browser;
    const char *theme;
    const char *userAgent;
    const char *backingStore;
    unsigned char isFlattening;
    Viewport viewport;
} ELauncher;

static void browserDestroy(Ecore_Evas *ee);
static void closeWindow(Ecore_Evas *ee);
static int browserCreate(const char *url, const char *theme, const char *userAgent, Eina_Rectangle geometry, const char *engine, const char *backingStore, unsigned char isFlattening, unsigned char isFullscreen, const char *databasePath);

static void
print_history(Eina_List *list)
{
    Eina_List *l;
    void *d;

    if (!verbose)
       return;

    printf("Session history contains:\n");

    EINA_LIST_FOREACH(list, l, d) {
       Ewk_History_Item *item = (Ewk_History_Item*)d;
       cairo_surface_t *cs = ewk_history_item_icon_surface_get(item);
       char buf[PATH_MAX];
       int s = snprintf(buf, sizeof(buf), "/tmp/favicon-%s.png", ewk_history_item_uri_original_get(item));
       for (s--; s >= (int)sizeof("/tmp/favicon-"); s--) {
           if (!isalnum(buf[s]) && buf[s] != '.')
               buf[s] = '_';
       }
       cs = ewk_history_item_icon_surface_get(item);

       if (cs && cairo_surface_status(cs) == CAIRO_STATUS_SUCCESS)
           cairo_surface_write_to_png(cs, buf);
       else
           buf[0] = '\0';

       printf("* '%s' title='%s' icon='%s'\n",
              ewk_history_item_uri_original_get(item),
              ewk_history_item_title_get(item), buf);
    }
}

static int
nearest_zoom_level_get(float factor)
{
    int i, intFactor = (int)(factor * 100.0);
    for (i = 0; zoomLevels[i] <= intFactor; i++) { }
    printf("factor=%f, intFactor=%d, zoomLevels[%d]=%d, zoomLevels[%d]=%d\n",
           factor, intFactor, i-1, zoomLevels[i-1], i, zoomLevels[i]);
    if (intFactor - zoomLevels[i-1] < zoomLevels[i] - intFactor)
        return i - 1;
    return i;
}

static Eina_Bool
zoom_level_set(Evas_Object *webview, int level)
{
    float factor = ((float) zoomLevels[level]) / 100.0;
    Evas_Coord ox, oy, mx, my, cx, cy;
    evas_pointer_canvas_xy_get(evas_object_evas_get(webview), &mx, &my);
    evas_object_geometry_get(webview, &ox, &oy, NULL, NULL);
    cx = mx - ox;
    cy = my - oy;
    return ewk_view_zoom_animated_set(webview, factor, 0.5, cx, cy);
}

static void
on_ecore_evas_resize(Ecore_Evas *ee)
{
    Evas_Object *webview;
    Evas_Object *bg;
    int w, h;

    ecore_evas_geometry_get(ee, NULL, NULL, &w, &h);

    bg = evas_object_name_find(ecore_evas_get(ee), "bg");
    evas_object_move(bg, 0, 0);
    evas_object_resize(bg, w, h);

    webview = evas_object_name_find(ecore_evas_get(ee), "browser");
    evas_object_move(webview, 10, 10);
    evas_object_resize(webview, w - 20, h - 20);
}

static void
title_set(Ecore_Evas *ee, const char *title, int progress)
{
    const char *appname = "EFL Test Launcher";
    const char *separator = " - ";
    char label[4096];
    int size;

    if (!title || !strcmp(title, "")) {
        ecore_evas_title_set(ee, appname);
        return;
    }

    if (progress < 100)
        size = snprintf(label, sizeof(label), "%s (%d%%)%s%s", title, progress, separator, appname);
    else
        size = snprintf(label, sizeof(label), "%s %s%s", title, separator, appname);

    if (size >= (int)sizeof(label))
        return;

    ecore_evas_title_set(ee, label);
}

/**
 * This is en example function to adjust viewport via viewport tag's arguments.
 * Application can invoke this function in order to adjust viewport tag when it is required.
 */
static void
viewport_set()
{
    ELauncher *app;
    app = (ELauncher*) eina_list_data_get(windows);

    ewk_view_fixed_layout_size_set(app->browser, app->viewport.w, app->viewport.h);
    ewk_view_zoom_set(app->browser, app->viewport.initScale, 0, 0);
    if (!ewk_view_zoom_range_set(app->browser, app->viewport.minScale, app->viewport.maxScale))
        info(" Fail to set zoom range. minScale = %f, maxScale = %f\n", app->viewport.minScale, app->viewport.maxScale);
    ewk_view_user_scalable_set(app->browser, app->viewport.userScalable);
}

static void
on_title_changed(void *user_data, Evas_Object *webview, void *event_info)
{
    ELauncher *app = (ELauncher *)user_data;
    const char *title = (const char *)event_info;

    title_set(app->ee, title, 100);
}

static void
on_progress(void *user_data, Evas_Object *webview, void *event_info)
{
    ELauncher *app = (ELauncher *)user_data;
    double *progress = (double *)event_info;

    title_set(app->ee, ewk_view_title_get(app->browser), *progress * 100);
}

static void
on_load_finished(void *user_data, Evas_Object *webview, void *event_info)
{
    const Ewk_Frame_Load_Error *err = (const Ewk_Frame_Load_Error *)event_info;

    if (!err)
        info("Succeeded loading page.\n");
    else if (err->is_cancellation)
        info("Load was cancelled.\n");
    else
        info("Failed loading page: %d %s \"%s\", url=%s\n",
             err->code, err->domain, err->description, err->failing_url);

    currentZoom = ewk_view_zoom_get(webview);
    currentZoomLevel = nearest_zoom_level_get(currentZoom);
    info("WebCore Zoom=%f, currentZoomLevel=%d\n", currentZoom, currentZoomLevel);
}

static void
on_toolbars_visible_set(void* user_data, Evas_Object* webview, void* event_info)
{
    Eina_Bool *visible = (Eina_Bool *)event_info;
    if (*visible) {
        info("Toolbars visible changed: show");
        windowProperties.toolbarsVisible = EINA_TRUE;
    } else {
        info("Toolbars visible changed: hide");
        windowProperties.toolbarsVisible = EINA_FALSE;
    }
}

static void
on_toolbars_visible_get(void* user_data, Evas_Object* webview, void* event_info)
{
    Eina_Bool *visible = (Eina_Bool *)event_info;
    *visible = windowProperties.toolbarsVisible;
}

static void
on_statusbar_visible_set(void* user_data, Evas_Object* webview, void* event_info)
{
    Eina_Bool *visible = (Eina_Bool *)event_info;
    if (*visible) {
        info("Statusbar visible changed: show");
        windowProperties.statusbarVisible = EINA_TRUE;
    } else {
        info("Statusbar visible changed: hide");
        windowProperties.statusbarVisible = EINA_FALSE;
    }
}

static void
on_statusbar_visible_get(void* user_data, Evas_Object* webview, void* event_info)
{
    Eina_Bool *visible = (Eina_Bool *)event_info;
    *visible = windowProperties.statusbarVisible;
}

static void
on_scrollbars_visible_set(void* user_data, Evas_Object* webview, void* event_info)
{
    Eina_Bool *visible = (Eina_Bool *)event_info;
    if (*visible) {
        info("Scrollbars visible changed: show");
        windowProperties.scrollbarsVisible = EINA_TRUE;
    } else {
        info("Scrollbars visible changed: hide");
        windowProperties.scrollbarsVisible = EINA_FALSE;
    }
}

static void
on_scrollbars_visible_get(void* user_data, Evas_Object* webview, void* event_info)
{
    Eina_Bool *visible = (Eina_Bool *)event_info;
    *visible = windowProperties.scrollbarsVisible;
}

static void
on_menubar_visible_set(void* user_data, Evas_Object* webview, void* event_info)
{
    Eina_Bool *visible = (Eina_Bool *)event_info;
    if (*visible) {
        info("Menubar visible changed: show");
        windowProperties.menubarVisible = EINA_TRUE;
    } else {
        info("Menubar visible changed: hide");
        windowProperties.menubarVisible = EINA_FALSE;
    }
}

static void
on_menubar_visible_get(void* user_data, Evas_Object* webview, void* event_info)
{
    Eina_Bool *visible = (Eina_Bool *)event_info;
    *visible = windowProperties.menubarVisible;
}

static void
on_tooltip_text_set(void* user_data, Evas_Object* webview, void* event_info)
{
    const char *text = (const char *)event_info;
    if (text && *text != '\0')
        info("%s\n", text);
}

static void
on_inputmethod_changed(void* user_data, Evas_Object* webview, void* event_info)
{
    Eina_Bool active = (Eina_Bool)(long)event_info;
    unsigned int imh;
    info("Keyboard changed: %d\n", active);

    if (!active)
        return;

    imh = ewk_view_imh_get(webview);
    info("    Keyboard flags: %#.2x\n", imh);

}

/**
 * "viewport,changed" signal will be always emitted regardless of the viewport existence.
 *
 * If you don't want to process the viewport tag, you can either do nothing in this callback
 * or simply ignore the signal in your application.
 * 
 * More information about this can be found at http://developer.apple.com/safari/library/docum
 * entation/appleapplications/reference/safariwebcontent/usingtheviewport/usingtheviewport.html
 */
static void
on_viewport_changed(void* user_data, Evas_Object* webview, void* event_info)
{
    ELauncher *app = (ELauncher *)user_data;

    float w, h, initScale, minScale, maxScale, devicePixelRatio;
    Eina_Bool userScalable;

    ewk_view_viewport_attributes_get(webview, &w, &h, &initScale, &maxScale, &minScale, &devicePixelRatio, &userScalable);

    /**
     * If there is no argument in viewport tag, argument's value is -1.
     */
    if ((int)w == -1)
        w = DEFAULT_WIDTH;
    if ((int)h == -1)
        h = DEFAULT_HEIGHT;
    if ((int)initScale == -1)
        initScale = DEFAULT_ZOOM_INIT; // There's no scale separated from zooming in webkit-efl.
    if ((int)minScale == -1)
        minScale = ewk_view_zoom_range_min_get(webview);
    if ((int)maxScale == -1)
        maxScale = ewk_view_zoom_range_max_get(webview);
    if ((int)devicePixelRatio == -1)
        devicePixelRatio = ewk_view_device_pixel_ratio_get(webview);
    if ((int)userScalable == -1)
        userScalable = EINA_TRUE;

    app->viewport.w = (int)w;
    app->viewport.h = (int)h;
    app->viewport.initScale = initScale;
    app->viewport.minScale = minScale;
    app->viewport.maxScale = maxScale;
    app->viewport.devicePixelRatio = devicePixelRatio;
    app->viewport.userScalable = userScalable;
    viewport_set();
}

static void
on_mouse_down(void* data, Evas* e, Evas_Object* webview, void* event_info)
{
    Evas_Event_Mouse_Down *ev = (Evas_Event_Mouse_Down*) event_info;
    if (ev->button == 2)
        evas_object_focus_set(webview, !evas_object_focus_get(webview));
}

static void
on_focus_out(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
    info("the webview lost keyboard focus\n");
}

static void
on_focus_in(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
    info("the webview gained keyboard focus\n");
}

static void
on_key_down(void *data, Evas *e, Evas_Object *obj, void *event_info)
{
    Evas_Event_Key_Down *ev = (Evas_Event_Key_Down*) event_info;
    ELauncher *app = data;
    static const char *encodings[] = {
        "ISO-8859-1",
        "UTF-8",
        NULL
    };
    static int currentEncoding = -1;

    if (!strcmp(ev->key, "Escape")) {
        closeWindow(app->ee);
    } else if (!strcmp(ev->key, "F1")) {
        info("Back (F1) was pressed\n");
        if (ewk_view_back_possible(obj)) {
            Ewk_History *history = ewk_view_history_get(obj);
            Eina_List *list = ewk_history_back_list_get(history);
            print_history(list);
            ewk_history_item_list_free(list);
            ewk_view_back(obj);
        } else
            info("Back ignored: No back history\n");
    } else if (!strcmp(ev->key, "F2")) {
        info("Forward (F2) was pressed\n");
        if (ewk_view_forward_possible(obj)) {
            Ewk_History *history = ewk_view_history_get(obj);
            Eina_List *list = ewk_history_forward_list_get(history);
            print_history(list);
            ewk_history_item_list_free(list);
            ewk_view_forward(obj);
        } else
            info("Forward ignored: No forward history\n");
    } else if (!strcmp(ev->key, "F3")) {
        currentEncoding++;
        currentEncoding %= (sizeof(encodings) / sizeof(encodings[0]));
        info("Set encoding (F3) pressed. New encoding to %s", encodings[currentEncoding]);
        ewk_view_setting_encoding_custom_set(obj, encodings[currentEncoding]);
    } else if (!strcmp(ev->key, "F4")) {
        Evas_Object *frame = ewk_view_frame_main_get(obj);
        Evas_Coord x, y;
        Ewk_Hit_Test *ht;

        evas_pointer_canvas_xy_get(evas_object_evas_get(obj), &x, &y);
        ht = ewk_frame_hit_test_new(frame, x, y);
        if (!ht)
            printf("No hit test returned for point %d,%d\n", x, y);
        else {
            printf("Hit test for point %d,%d\n"
                   "  pos=%3d,%3d\n"
                   "  bounding_box=%d,%d + %dx%d\n"
                   "  title='%s'\n"
                   "  alternate_text='%s'\n"
                   "  frame=%p (%s)\n"
                   "  link {\n"
                   "    text='%s'\n"
                   "    url='%s'\n"
                   "    title='%s'\n"
                   "    target frame=%p (%s)\n"
                   "  }\n"
                   "  flags {\n"
                   "    editable=%hhu\n"
                   "    selected=%hhu\n"
                   "  }\n",
                   x, y,
                   ht->x, ht->y,
                   ht->bounding_box.x, ht->bounding_box.y, ht->bounding_box.w, ht->bounding_box.h,
                   ht->title,
                   ht->alternate_text,
                   ht->frame, evas_object_name_get(ht->frame),
                   ht->link.text,
                   ht->link.url,
                   ht->link.title,
                   ht->link.target_frame, evas_object_name_get(ht->link.target_frame),
                   ht->flags.editable,
                   ht->flags.selected);
            ewk_frame_hit_test_free(ht);
        }

    } else if (!strcmp(ev->key, "F5")) {
        info("Reload (F5) was pressed, reloading.\n");
        ewk_view_reload(obj);
    } else if (!strcmp(ev->key, "F6")) {
        info("Stop (F6) was pressed, stop loading.\n");
        ewk_view_stop(obj);
    } else if (!strcmp(ev->key, "F12")) {
        Eina_Bool status = ewk_view_setting_spatial_navigation_get(obj);
        ewk_view_setting_spatial_navigation_set(obj, !status);
        info("Command::keyboard navigation toggle\n");
    } else if (!strcmp(ev->key, "F7")) {
        info("Zoom out (F7) was pressed.\n");
        if (currentZoomLevel > MIN_ZOOM_LEVEL && zoom_level_set(obj, currentZoomLevel - 1))
            currentZoomLevel--;
    } else if (!strcmp(ev->key, "F8")) {
        info("Zoom in (F8) was pressed.\n");
        if (currentZoomLevel < MAX_ZOOM_LEVEL && zoom_level_set(obj, currentZoomLevel + 1))
            currentZoomLevel++;
    } else if (!strcmp(ev->key, "F9")) {
        info("Create new window (F9) was pressed.\n");
        Eina_Rectangle geometry = {0, 0, 0, 0};
        browserCreate("http://www.google.com",
                       app->theme, app->userAgent, geometry, app-> backingStore,
                       NULL, app->isFlattening, 0, NULL);
    } else if (!strcmp(ev->key, "F10")) {
        Evas_Coord x, y, w, h;
        Evas_Object *frame = ewk_view_frame_main_get(obj);
        float zoom = zoomLevels[currentZoomLevel] / 100.0;

        ewk_frame_visible_content_geometry_get(frame, EINA_FALSE, &x, &y, &w, &h);
        x -= w;
        y -= h;
        w *= 4;
        h *= 4;
        info("Pre-render %d,%d + %dx%d\n", x, y, w, h);
        ewk_view_pre_render_region(obj, x, y, w, h, zoom);
    } else if (!strcmp(ev->key, "F11")) {
        info("Pre-render 1 extra column/row with current zoom");
        ewk_view_pre_render_relative_radius(obj, 1);
    } else if (!strcmp(ev->key, "d")) {
        info("Render suspended");
        ewk_view_disable_render(obj);
    } else if (!strcmp(ev->key, "e")) {
        info("Render resumed");
        ewk_view_enable_render(obj);
    }
}

static void
on_browser_del(void *data, Evas *evas, Evas_Object *browser, void *event)
{
    ELauncher *app = (ELauncher*) data;

    evas_object_event_callback_del(app->browser, EVAS_CALLBACK_KEY_DOWN, on_key_down);
    evas_object_event_callback_del(app->browser, EVAS_CALLBACK_MOUSE_DOWN, on_mouse_down);
    evas_object_event_callback_del(app->browser, EVAS_CALLBACK_FOCUS_IN, on_focus_in);
    evas_object_event_callback_del(app->browser, EVAS_CALLBACK_FOCUS_OUT, on_focus_out);
    evas_object_event_callback_del(app->browser, EVAS_CALLBACK_DEL, on_browser_del);
}

static void
on_closeWindow(Ecore_Evas *ee)
{
    browserDestroy(ee);
}

static int
quit(Eina_Bool success, const char *msg)
{
    edje_shutdown();
    ecore_evas_shutdown();

    if (msg)
        fputs(msg, (success) ? stdout : stderr);

    if (themePath) {
        free(themePath);
        themePath = NULL;
    }

    if (!success)
        return EXIT_FAILURE;

    return EXIT_SUCCESS;
}

static int
browserCreate(const char *url, const char *theme, const char *userAgent, Eina_Rectangle geometry, const char *engine, const char *backingStore, unsigned char isFlattening, unsigned char isFullscreen, const char *databasePath)
{
    if ((geometry.w <= 0) && (geometry.h <= 0)) {
        geometry.w = DEFAULT_WIDTH;
        geometry.h = DEFAULT_HEIGHT;
    }

    ELauncher *app = (ELauncher*) malloc(sizeof(ELauncher));
    if (!app)
        return quit(EINA_FALSE, "ERROR: could not create EWebLauncher window\n");

    app->ee = ecore_evas_new(engine, 0, 0, geometry.w, geometry.h, NULL);

    if (!app->ee)
        return quit(EINA_FALSE, "ERROR: could not construct evas-ecore\n");

    if (isFullscreen)
        ecore_evas_fullscreen_set(app->ee, EINA_TRUE);

    ecore_evas_title_set(app->ee, "EFL Test Launcher");
    ecore_evas_callback_resize_set(app->ee, on_ecore_evas_resize);
    ecore_evas_callback_delete_request_set(app->ee, closeWindow);

    app->evas = ecore_evas_get(app->ee);

    if (!app->evas)
        return quit(EINA_FALSE, "ERROR: could not get evas from evas-ecore\n");

    app->theme = theme;
    app->userAgent = userAgent;
    app->backingStore = backingStore;
    app->isFlattening = isFlattening;

    app->bg = evas_object_rectangle_add(app->evas);
    evas_object_name_set(app->bg, "bg");
    evas_object_color_set(app->bg, 255, 0, 255, 255);
    evas_object_move(app->bg, 0, 0);
    evas_object_resize(app->bg, geometry.w, geometry.h);
    evas_object_layer_set(app->bg, EVAS_LAYER_MIN);
    evas_object_show(app->bg);

    if (backingStore && !strcasecmp(backingStore, "tiled")) {
        app->browser = ewk_view_tiled_add(app->evas);
        info("backing store: tiled\n");
    } else {
        app->browser = ewk_view_single_add(app->evas);
        info("backing store: single\n");
    }

    ewk_view_theme_set(app->browser, theme);
    if (userAgent)
        ewk_view_setting_user_agent_set(app->browser, userAgent);
    ewk_view_setting_local_storage_database_path_set(app->browser, databasePath);
    ewk_view_setting_enable_frame_flattening_set(app->browser, isFlattening);
    
    evas_object_name_set(app->browser, "browser");

    evas_object_smart_callback_add(app->browser, "title,changed", on_title_changed, app);
    evas_object_smart_callback_add(app->browser, "load,progress", on_progress, app);
    evas_object_smart_callback_add(app->browser, "load,finished", on_load_finished, app);
    evas_object_smart_callback_add(app->browser, "viewport,changed", on_viewport_changed, app);

    evas_object_smart_callback_add(app->browser, "toolbars,visible,set", on_toolbars_visible_set, app);
    evas_object_smart_callback_add(app->browser, "toolbars,visible,get", on_toolbars_visible_get, app);
    evas_object_smart_callback_add(app->browser, "statusbar,visible,set", on_statusbar_visible_set, app);
    evas_object_smart_callback_add(app->browser, "statusbar,visible,get", on_statusbar_visible_get, app);
    evas_object_smart_callback_add(app->browser, "scrollbars,visible,set", on_scrollbars_visible_set, app);
    evas_object_smart_callback_add(app->browser, "scrollbars,visible,get", on_scrollbars_visible_get, app);
    evas_object_smart_callback_add(app->browser, "menubar,visible,set", on_menubar_visible_set, app);
    evas_object_smart_callback_add(app->browser, "menubar,visible,get", on_menubar_visible_get, app);
    evas_object_smart_callback_add(app->browser, "tooltip,text,set", on_tooltip_text_set, app);
    evas_object_smart_callback_add(app->browser, "inputmethod,changed", on_inputmethod_changed, app);

/*     ewk_callback_resize_requested_add(app->browser, on_resize_requested, app->ee); */

    evas_object_event_callback_add(app->browser, EVAS_CALLBACK_KEY_DOWN, on_key_down, app);
    evas_object_event_callback_add(app->browser, EVAS_CALLBACK_MOUSE_DOWN, on_mouse_down, app);
    evas_object_event_callback_add(app->browser, EVAS_CALLBACK_FOCUS_IN, on_focus_in, app);
    evas_object_event_callback_add(app->browser, EVAS_CALLBACK_FOCUS_OUT, on_focus_out, app);
    evas_object_event_callback_add(app->browser, EVAS_CALLBACK_DEL, on_browser_del, app);

    evas_object_move(app->browser, 10, 10);
    evas_object_resize(app->browser, geometry.w - 20, geometry.h - 20);

    if (url && (url[0] != '\0'))
        ewk_view_uri_set(app->browser, url);

    evas_object_show(app->browser);
    ecore_evas_show(app->ee);

    evas_object_focus_set(app->browser, EINA_TRUE);

    windows = eina_list_append(windows, app);

    return 1;
}

static void
browserDestroy(Ecore_Evas *ee)
{
    ecore_evas_free(ee);
    if (!eina_list_count(windows))
        ecore_main_loop_quit();
}

static void
closeWindow(Ecore_Evas *ee)
{
    Eina_List *l;
    void *app;
    EINA_LIST_FOREACH(windows, l, app)
    {
        if (((ELauncher*) app)->ee == ee)
            break;
    }
    windows = eina_list_remove(windows, app);
    browserDestroy(ee);
    free(app);
}

static Eina_Bool
main_signal_exit(void *data, int ev_type, void *ev)
{
    ELauncher *app;
    while (windows) {
        app = (ELauncher*) eina_list_data_get(windows);
        ecore_evas_free(app->ee);
        windows = eina_list_remove(windows, app);
    }
    if (!eina_list_count(windows))
        ecore_main_loop_quit();
    return EINA_TRUE;
}

static char *
findThemePath(const char *theme)
{
    const char *defaultTheme = DATA_DIR"/default.edj";
    char *rpath;
    struct stat st;

    if (!theme)
        theme = defaultTheme;

    rpath = realpath(theme, NULL);
    if (!rpath)
        return NULL;

    if (stat(rpath, &st)) {
        free(rpath);
        return NULL;
    }

    return rpath;
}

int
main(int argc, char *argv[])
{
    const char *default_url = "http://www.google.com/";

    Eina_Rectangle geometry = {0, 0, 0, 0};
    char *url = NULL;
    char *userAgent = NULL;
    const char *tmp;
    const char *proxyUri;
    char path[PATH_MAX];

    char *engine = NULL;
    char *theme = NULL;
    char *backingStore = (char *)backingStores[1];

    unsigned char quitOption = 0;
    unsigned char isFlattening = 0;
    unsigned char isFullscreen = 0;
    int args;

    Ecore_Getopt_Value values[] = {
        ECORE_GETOPT_VALUE_STR(engine),
        ECORE_GETOPT_VALUE_BOOL(quitOption),
        ECORE_GETOPT_VALUE_STR(backingStore),
        ECORE_GETOPT_VALUE_BOOL(isFlattening),
        ECORE_GETOPT_VALUE_BOOL(isFullscreen),
        ECORE_GETOPT_VALUE_PTR_CAST(geometry),
        ECORE_GETOPT_VALUE_STR(theme),
        ECORE_GETOPT_VALUE_STR(userAgent),
        ECORE_GETOPT_VALUE_INT(verbose),
        ECORE_GETOPT_VALUE_BOOL(quitOption),
        ECORE_GETOPT_VALUE_BOOL(quitOption),
        ECORE_GETOPT_VALUE_BOOL(quitOption),
        ECORE_GETOPT_VALUE_BOOL(quitOption),
        ECORE_GETOPT_VALUE_NONE
    };

    if (!ecore_evas_init())
        return EXIT_FAILURE;

    if (!edje_init()) {
        ecore_evas_shutdown();
        return EXIT_FAILURE;
    }

    ecore_app_args_set(argc, (const char**) argv);
    args = ecore_getopt_parse(&options, values, argc, argv);

    if (args < 0)
       return quit(EINA_FALSE, "ERROR: could not parse options.\n");

    if (quitOption)
        return quit(EINA_TRUE, NULL);

    if (args < argc)
        url = argv[args];
    else
        url = (char*) default_url;

    themePath = findThemePath(theme);
    if (!themePath)
        return quit(EINA_FALSE, "ERROR: could not find theme.\n");

    ewk_init();
    tmp = getenv("TMPDIR");
    if (!tmp)
        tmp = "/tmp";
    snprintf(path, sizeof(path), "%s/.ewebkit-%u", tmp, getuid());
    ecore_file_mkpath(path);
    ewk_settings_icon_database_path_set(path);
    ewk_settings_web_database_path_set(path);

    proxyUri = getenv("http_proxy");
    if (proxyUri)
        ewk_settings_proxy_uri_set(proxyUri);

    browserCreate(url, themePath, userAgent, geometry, engine, backingStore, isFlattening, isFullscreen, path);
    ecore_event_handler_add(ECORE_EVENT_SIGNAL_EXIT, main_signal_exit, &windows);

    ecore_main_loop_begin();

    ewk_shutdown();

    return quit(EINA_TRUE, NULL);
}
