$(function() {
    Ox.theme("modern");
    var $body = $("body"),
        $document = $(document),
        app = new Ox.App({
            // requestURL: "http://blackbook.local:8000/api/"
            requestURL: "http://lion.oil21.org:8000/api/"
        }),
        findCondition = {},
        groups = [
            {
                conditions: [],
                id: "director",
                title: "Director"
            },
            {
                conditions: [],
                id: "country",
                title: "Country"
            },
            {
                conditions: [],
                id: "year",
                title: "Year"
            },
            {
                conditions: [],
                id: "language",
                title: "Language"
            },
            {
                conditions: [],
                id: "genre",
                title: "Genre"
            }
        ],
        $group = [],
        elements = [],
        rightPanelWidth = $document.width() - 256;

    $.each(groups, function(i, v) {
        var size = rightPanelWidth / 5 + (rightPanelWidth % 5 > i);
        $group[i] = new Ox.TextList({
            columns: [
                {
                    align: "left",
                    id: "name",
                    operator: v.id == "year" ? "-" : "+",
                    title: v.title,
                    unique: true,
                    visible: true,
                    width: size - 40 - ($.browser.mozilla ? 16 : 12)
                },
                {
                    align: "right",
                    id: "items",
                    operator: "-",
                    title: "#",
                    visible: true,
                    width: 40
                }
            ],
            id: "group_" + v.id,
            request: function(options) {
                delete options.keys;
                app.request("find", $.extend(options, {
                    group: v.id,
                    query: constructQuery()
                }), options.callback);
            },
            sort: [
                {
                    key: v.id == "year" ? "name" : "items",
                    operator: "-"
                }
            ]
        });
        elements.push({
            element: $group[i],
            resizable: true,
            size: size
        });
    });

    var $groupsInnerPanel = new Ox.SplitPanel({
            elements: [
                elements[1],
                elements[2],
                elements[3]
            ],
            orientation: "horizontal"
        }),

        $groupsOuterPanel = new Ox.SplitPanel({
            elements: [
                elements[0],
                {
                    element: $groupsInnerPanel
                },
                elements[4]
            ],
            orientation: "horizontal"
        })

        $list = constructList("text");

        $toolBar = Ox.Bar({
            size: 24
        }),

        $button = Ox.Button({
            id: "groupsButton",
            value: ["Show Groups", "Hide Groups"]
        }).css({
            float: "left",
            margin: "4px"
        }).width(80).appendTo($toolBar),

        $select = Ox.Select({
            id: "viewSelect",
            items: [
                {
                    checked: true,
                    id: "list",
                    title: "View as List"
                },
                {
                    id: "icons",
                    title: "View as Icons"
                },
                {
                    id: "clips",
                    title: "View with Clips"
                },
                {
                    id: "timelines",
                    title: "View with Timelines"
                },
                {
                    id: "maps",
                    title: "View with Maps"
                },
                {
                    id: "calendars",
                    title: "View with Calendars"
                },
                {
                    id: "clip",
                    title: "View as Clips"
                },
                {
                    id: "map",
                    title: "View on Map"
                },
                {
                    id: "calendar",
                    title: "View on Calendar"
                },
            ]
        }).css({
            float: "left",
            margin: "4px"
        }).width(120).appendTo($toolBar);

        $input = new Ox.Input({
            autocomplete: function(key, value, callback) {
                Ox.print("autocomplete", key, value);
                value === "" && Ox.print("Warning: autocomplete function should never be called with empty value");
                if (key == "all") {
                    callback();
                } else {
                    app.request("find", {
                        keys: [key],
                        query: {
                            conditions: [
                                {
                                    key: key,
                                    value: value,
                                    operator: ""
                                }
                            ],
                            operator: ""
                        },
                        sort: [
                            {
                                key: key,
                                operator: "+"
                            }
                        ],
                        range: [0, 10]
                    }, function(result) {
                        Ox.print("calling callback", result.data.items)
                        callback($.map(result.data.items, function(v) {
                            return v.title;
                        }))
                    });
                }
            },
            clear: true,
            highlight: true,
            id: "find",
            label: [
                { id: "all", title: "Find: All" },
                { id: "title", title: "Find: Title" },
                { id: "director", title: "Find: Director" },
                { id: "country", title: "Find: Country" },
                { id: "year", title: "Find: Year" },
                { id: "language", title: "Find: Language" },
                { id: "writer", title: "Find: Writer" },
                { id: "producer", title: "Find: Producer" },
                { id: "cinematographer", title: "Find: Cinematographer" },
                { id: "editor", title: "Find: Editor" },
                { id: "actor", title: "Find: Actor" },
                { id: "character", title: "Find: Character" },
                { id: "name", title: "Find: Name" },
                { id: "genre", title: "Find: Genre" },
                { id: "keyword", title: "Find: Keyword" },
                { id: "summary", title: "Find: Summary" },
                { id: "dialog", title: "Find: Dialog" }
            ],
            labelWidth: 85
        }).css({
            float: "right",
            margin: "4px"
        }).width(300).appendTo($toolBar);

        $contentPanel = new Ox.SplitPanel({
            elements: [
                {
                    element: $groupsOuterPanel,
                    size: 128
                },
                {
                    element: $list
                }
            ],
            orientation: "vertical"
        }),

        $statusBar = new Ox.Bar({
            size: 16
        }).attr({
            id: "statusBar"
        }),

        $totals = new Ox.Element()
            .attr({
                id: "totals"
            })
            .appendTo($statusBar),

        $leftPanel = new Ox.Container(),

        $rightPanel = new Ox.SplitPanel({
            elements: [
                {
                    element: $toolBar,
                    size: 24
                },
                {
                    element: $contentPanel
                },
                {
                    element: $statusBar,
                    size: 16
                }
            ],
            orientation: "vertical"
        }),

        $loadingIcon = new Ox.LoadingIcon({
            size: "medium"
        });

        $mainMenu = new Ox.MainMenu({
            extras: [
                $loadingIcon
            ],
            menus: [
                {
                    id: "oxdb",
                    title: "OxDB",
                    items: [
                        { id: "about", title: "About" }
                    ]
                },
                {
                    id: "sort",
                    title: "Sort",
                    items: [
                        { id: "sort_movies", title: "Sort Movies by", items: [
                            { checked: false, group: "sort_movies", id: "title", title: "Title"},
                            { checked: false, group: "sort_movies", id: "director", title: "Director" },
                            { checked: false, group: "sort_movies", id: "country", title: "Country" },
                            { checked: true, group: "sort_movies", id: "year", title: "Year" },
                            { checked: false, group: "sort_movies", id: "language", title: "Language" },
                            { checked: false, group: "sort_movies", id: "runtime", title: "Runtime" },
                            { checked: false, group: "sort_movies", id: "genre", title: "Genre" },
                        ] },
                        { id: "order_movies", title: "Order Movies", items: [
                            { checked: false, group: "order_movies", id: "ascending", title: "Ascending"},
                            { checked: true, group: "order_movies", id: "descending", title: "Descending" },
                        ] }
                    ]
                },
                {
                    id: "debug",
                    title: "Debug",
                    items: [
                        { id: "show_query", title: "Show Query" }
                    ]
                }
            ],
            size: "medium"
        }),

        $mainPanel = new Ox.SplitPanel({
            elements: [
                {
                    element: $leftPanel,
                    size: 256
                },
                {
                    element: $rightPanel
                }
            ]
        }),

        $appPanel = Ox.SplitPanel({
            elements: [
                {
                    element: $mainMenu,
                    size: 20
                },
                {
                    element: $mainPanel
                }
            ],
            orientation: "vertical"
        }).appendTo($body);

    Ox.Request.requests() && $loadingIcon.start();
    Ox.Event.bind(null, "requestStart", function() {
        Ox.print("start")
        $loadingIcon.start();
    });
    Ox.Event.bind(null, "requestStop", function() {
        Ox.print("stop")
        $loadingIcon.stop();
    });

    Ox.Event.bind(null, "change_viewSelect", function(event, data) {
        $list.replaceWith(constructList(data.id));
    });

    Ox.Event.bind(null, "submit_find", function(event, data) {
        findCondition = {
            key: data.key == "all" ? "" : data.key,
            value: data.value,
            operator: ""
        };
        $.each(groups, function(i, group) {
            groups[i].conditions = [];
            $group[i].options({
                request: function(options) {
                    delete options.keys;
                    return app.request("find", $.extend(options, {
                        group: group.id,
                        query: constructQuery(group.id)
                    }), options.callback);
                }
            });
        });
        $list.options({
            request: function(options) {
                return app.request("find", $.extend(options, {
                    query: constructQuery()
                }), options.callback);
            }
        })
    });

    $.each(groups, function(i, group) {
        Ox.Event.bind(null, "select_group_" + group.id, function(event, data) {
            $list.options({
                request: function(options) {
                    groups[i].conditions = $.map(data.ids, function(v) {
                        return {
                            key: group.id,
                            value: v,
                            operator: "="
                        };
                    });
                    return app.request("find", $.extend(options, {
                        query: constructQuery()
                    }), options.callback);
                }
            });
            $.each(groups, function(i_, group_) {
                if (i_ != i) {
                    $group[i_].options({
                        request: function(options) {
                            delete options.keys;
                            return app.request("find", $.extend(options, {
                                group: group_.id,
                                query: constructQuery(group_.id)
                            }), options.callback);
                        }
                    });
                }
            });
        });
    });
    Ox.Event.bind(null, "change_sort_movies", function(event, data) {

    });
    Ox.Event.bind(null, "load_list", function(event, data) {
        $totals.html(constructStatus({
            "total": data,
            "selected": {}
        }));
        var html = [
            Ox.formatNumber(data.items) + " movie" + (data.items != 1 ? "s" : ""),
            Ox.formatDuration(data.runtime, "medium"),
            data.files + " file" + (data.files != 1 ? "s" : ""),
            Ox.formatDuration(data.duration, "short"),
            Ox.formatValue(data.size, "B"),
            Ox.formatValue(data.pixels, "px")
        ];
        $totals.html("Total: " + constructStatus(data) + " &mdash; Selected: " + constructStatus({
            duration: 0,
            files: 0,
            items: 0,
            pixels: 0,
            runtime: 0,
            size: 0
        }));
    });
    Ox.Event.bind(null, "sort_list", function(event, data) {
        
    });
    Ox.Event.bind(null, "select_list", function(event, data) {
        
    });
    Ox.Event.bind(null, "click_show_query", function(event, data) {
        var query = constructQuery(),
            html = "Conditions<br/><br/>" + $.map(query.conditions, function(v) {
                return v.key + " " + v.operator + " " + v.value;
            }).join("<br/>") + "<br/><br/>Operator: " + query.operator,
            $dialog = new Ox.Dialog({
                title: "Show Query",
                buttons: [
                    {
                        value: "Close",
                        click: function() {
                            $dialog.close();
                        }
                    }
                ]
            })
            .append(html)
            .open();
    });

    function constructList(view) {
        var $list;
        if (view == "text") {
            $list = new Ox.TextList({
                columns: [
                    {
                        align: "left",
                        id: "id",
                        operator: "+",
                        title: "ID",
                        unique: true,
                        visible: true,
                        width: 80
                    },
                    {
                        align: "left",
                        id: "title",
                        operator: "+",
                        title: "Title",
                        visible: true,
                        width: 160
                    },
                    {
                        align: "left",
                        id: "director",
                        operator: "+",
                        title: "Director",
                        visible: true,
                        width: 160
                    },
                    {
                        align: "left",
                        id: "country",
                        operator: "+",
                        title: "Country",
                        visible: true,
                        width: 120
                    },
                    {
                        align: "right",
                        id: "year",
                        operator: "-",
                        title: "Year",
                        visible: true,
                        width: 60
                    },
                    {
                        align: "left",
                        id: "language",
                        operator: "+",
                        title: "Language",
                        visible: true,
                        width: 120
                    },
                    {
                        align: "right",
                        id: "runtime",
                        operator: "-",
                        title: "Runtime",
                        visible: true,
                        width: 80
                    },
                    {
                        align: "left",
                        id: "genre",
                        operator: "+",
                        title: "Genre",
                        visible: true,
                        width: 120
                    },
                    {
                        align: "right",
                        id: "rating",
                        operator: "-",
                        title: "Rating",
                        width: 80
                    },
                    {
                        align: "right",
                        id: "votes",
                        operator: "-",
                        title: "Votes",
                        width: 80
                    }
                ],
                id: "list",
                request: function(options) {
                    app.request("find", $.extend(options, {
                        query: constructQuery()
                    }), options.callback);
                },
                sort: [
                    {
                        key: "director",
                        operator: "+"
                    }
                ]
            });
        } else if (view == "icons") {
            $list = new Ox.IconList({
                id: "list",
                item: function(data, sort, size) {
                    return {
                        height: data.posterHeight,
                        id: data["id"],
                        info: data[$.inArray(sort[0].key, ["title", "director"]) > -1 ? "year" : sort[0].key],
                        title: data.title + (data.director ? " (" + data.director + ")" : ""),
                        url: "http://0xdb.org/" + data.id + "/poster." + size + "." + "jpg",
                        width: data.posterWidth
                    };
                },
                keys: ["director", "id", "posterHeight", "posterWidth", "posterURL", "title"],
                request: function(options) {
                    app.request("find", $.extend(options, {
                        query: constructQuery()
                    }), options.callback);
                },
                size: 128,
                sort: [
                    {
                        key: "director",
                        operator: "+"
                    }
                ],
                unique: "id"
            });
        }
        return $list;
    }

    function constructQuery(groupId) {
        var conditions = $.merge(!Ox.isUndefined(findCondition.key) ? [findCondition] : [], $.map(groups, function(v, i) {
            if (v.id != groupId) {
                return v.conditions;
            }
        }));
        /*
        Ox.print("conditions", conditions, "groups conditions", $.map(groups, function(v) {
            return v.conditions;
        }));
        */
        return {
            conditions: conditions,
            operator: conditions.length ? "," : ""
        };
    }

    function constructStatus(data) {
        var html = [];
        $.each(data, function(k, v) {
            html.push(Ox.toTitleCase(k) + ": " + [
                Ox.formatNumber(data.items) + " movie" + (data.items != 1 ? "s" : ""),
                Ox.formatDuration(data.runtime, "medium"),
                data.files + " file" + (data.files != 1 ? "s" : ""),
                Ox.formatDuration(data.duration, "short"),
                Ox.formatValue(data.size, "B"),
                Ox.formatValue(data.pixels, "px")
            ].join(", "));
        })
        return html.join(" &mdash; ");
        
    }

    function getGroupById(id) { // unused
        $.each(groups, function(i, v) {
            if (v.id == id) {
                return i;
            }
        });
        return -1;
    }

});
