'use strict';

oml.ui.identifyDialog = function(data) {

    var ui = oml.user.ui,

        $form = Ox.Element(),

        $findSelect = Ox.Select({
                items: [
                    {id: 'title', title: Ox._('Title')},
                    {id: 'isbn', title: Ox._('ISBN')},
                    {id: 'id', title: Ox._('ID')}
                ],
                overlap: 'right',
                max: 1,
                min: 1,
                style: 'squared',
                value: [data.isbn ? 'isbn' : 'title'],
                width: 96
            })
            .bindEvent({
                change: function(data) {
                    $innerElement.replaceElement(1, $findInput[data.value]);
                    (
                        data.value == 'title' ? $titleInput : $findInput[data.value]
                    ).focusInput(true);
                }
            }),

        $titleInput = Ox.Input({
                style: 'squared',
                value: Ox.decodeHTMLEntities(data.title || ''),
                width: 224
            })
            .bindEvent({
                change: findMetadata,
                submit: findMetadata
            }),

        $authorInput = Ox.Input({
                style: 'squared',
                value: Ox.decodeHTMLEntities((data.author || []).join('; ')),
                width: 224
            })
            .bindEvent({
                change: findMetadata,
                submit: findMetadata
            }),

        $findInput = {
            title: Ox.InputGroup({
                    inputs: [$titleInput, $authorInput],
                    separators: [{
                        title: Ox._('Author'),
                        width: 96
                    }],
                    style: 'squared',
                    width: 544
                }),
            isbn: Ox.Input({
                    style: 'squared',
                    value: Ox.formatISBN(data.isbn || '', 13, true),
                    width: 544
                })
                .bindEvent({
                    change: findMetadata,
                    submit: findMetadata
                }),
            id: Ox.Input({
                    style: 'squared',
                    value: data.id,
                    width: 544
                })
                .bindEvent({
                    change: findMetadata,
                    submit: findMetadata
                })
        },

        $findButton = Ox.Button({
                overlap: 'left',
                style: 'squared',
                title: Ox._('Find'),
                width: 96
            })
            .bindEvent({
                click: findMetadata
            }),

        $innerElement = Ox.FormElementGroup({
                elements: [
                    $findSelect,
                    $findInput[$findSelect.value()]
                ],
                float: 'left'
            }),

        $outerElement = Ox.FormElementGroup({
                elements: [
                    $innerElement,
                    $findButton
                ],
                float: 'right'
            })
            .css({margin: '16px'})
            .appendTo($form),

        $list,

        $innerPanel,

        $outerPanel = Ox.SplitPanel({
            elements: [
                {element: $form, size: 48},
                {element: renderResults([])}
            ],
            orientation: 'vertical'
        }),

        $updateSelect = Ox.Select({
                items: [
                    {id: 'replace', title: Ox._('Replace Metadata')},
                    {id: 'merge', title: Ox._('Merge Metadata')}
                ],
                max: 1,
                min: 1,
                style: 'squared',
                value: ui.updateMetadata,
                width: 192
            })
            .css({margin: '4px'})
            .bindEvent({
                change: function(data) {
                    oml.UI.set({updateMetadata: data.value});
                    $list && $innerPanel.replaceElement(1, renderResult());
                }
            }),

        $dontUpdateButton = Ox.Button({
                id: 'dontupdate',
                style: 'squared',
                title: Ox._('No, Don\'t Update')
            })
            .bindEvent({
                click: function() {
                    that.close();
                }
            }),

        $updateButton = Ox.Button({
                disabled: true,
                id: 'update',
                style: 'squared',
                title: Ox._('Yes, Update')
            })
            .bindEvent({
                click: function() {
                    that.options({content: Ox.LoadingScreen().start()});
                    that.disableButtons();
                    oml.api.edit(Ox.extend({
                        id: data.id
                    }, Ox.filter(
                        $list.value($list.options('selected')[0]),
                        function(value, key) {
                            return Ox.contains($list.options('keys'), key)
                                && value != data[key]
                        }
                    )), function(result) {
                        Ox.Request.clearCache('find');
                        oml.$ui.info.updateElement();
                        oml.reloadLists();
                        Ox.Request.clearCache(data.id);
                        oml.$ui.infoView.updateElement(data.id);
                        that.close();
                    });
                }
            }),

        that = Ox.Dialog({
            buttons: [
                $dontUpdateButton,
                $updateButton
            ],
            closeButton: true,
            content: $outerPanel,
            fixedSize: true,
            height: 384,
            removeOnClose: true,
            title: Ox._('Identify Book'),
            width: 768
        });

    $($updateSelect.find('.OxButton')[0]).css({margin: 0});
    $updateSelect.appendTo($(that.find('.OxBar')[1]));

    function disableButtons() {
        $findSelect.options('items').forEach(function(item) {
            $findSelect.disableItem(item.id);
        });
        $findInput[$findSelect.value()].options({disabled: true});
        $findButton.options({disabled: true});
        $updateSelect.options('items').forEach(function(item) {
            $updateSelect.disableItem(item.id);
        });
        $updateButton.options({disabled: true});
    }

    function enableButtons() {
        $findSelect.options('items').forEach(function(item) {
            $findSelect.enableItem(item.id);
        });
        $findInput[$findSelect.value()].options({disabled: false});
        $findButton.options({disabled: false});
        $updateSelect.options('items').forEach(function(item) {
            $updateSelect.enableItem(item.id);
        });
        $updateButton.options({disabled: false});
    }

    function findMetadata() {
        var key = $findSelect.value();
        disableButtons();
        $outerPanel.replaceElement(1, Ox.LoadingScreen().start());
        oml.api.findMetadata(
            key == 'title' ? {
                title: $titleInput.value(),
                author: $authorInput.value()
            } : key == 'isbn' ? {
                isbn: Ox.formatISBN($findInput.isbn.value(), 13)
            } : {
                id: $findInput.id.value()
            },
            function(result) {
                var items = result.data.items.map(function(item, index) {
                    return Ox.extend({index: index.toString()}, item);
                });
                enableButtons();
                $updateButton.options({disabled: !items.length});
                $outerPanel.replaceElement(1, renderResults(items));
            }
        );
    }

    function getValue(key) {
        return key == 'title' ? Ox.decodeHTMLEntities(
                [data.title || ''].concat(data.author || []).join(' ')
            )
            : key == 'isbn' ? (data.isbn || '')
            : data.id;
    }

    function renderResult() {
        var index = $list.options('selected')[0];
        return oml.ui.infoView(
            $updateSelect.value() == 'replace'
            ? $list.value(index)
            : Ox.map($list.value(index), function(value, key) {
                return value || data[key];
            })
        );
    }

    function renderResults(items) {
        if (items.length) {
            $list = Ox.TableList({
                    columns: [{
                        format: function(value, data) {
                            return '<b>' + data.title + '</b> ' + data.author
                        },
                        id: 'index',
                        visible: true,
                        width: 192 - Ox.UI.SCROLLBAR_SIZE
                    }],
                    items: items,
                    keys: [
                        'cover', 'title', 'author',
                        'publisher', 'place', 'date',
                        'series', 'edition', 'language', 'pages',
                        'categories', 'isbn', 'description', 'tableofcontents'
                    ],
                    min: 1,
                    max: 1,
                    scrollbarVisible: true,
                    selected: ['0'],
                    sort: [{key: 'index', operator: '+'}],
                    unique: 'index'
                })
                .bindEvent({
                    select: function(data) {
                        $innerPanel.replaceElement(1, renderResult());
                    }
                });
            $innerPanel = Ox.SplitPanel({
                elements: [
                    {element: $list || Ox.Element(), size: 192},
                    {element: Ox.Element()}
                ],
                orientation: 'horizontal'
            });
            setTimeout(function() {
                $list.triggerEvent('select', {ids: ['0']});
            });
        } else {
            $list = null;
            $innerPanel = Ox.Element();
        }
        return $innerPanel;
    }

    return that;

};