// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The ASF licenses this file
// to you 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.
(function(cloudStack, $) {
    var pageElems = cloudStack.uiCustom.projectsTabs = {
        /**
         * User management multi-edit
         */
        userManagement: function(args) {
            var multiEdit = !args.useInvites ?
                cloudStack.projects.addUserForm :
                cloudStack.projects.inviteForm;

            var $multi = $('<div>').multiEdit($.extend(true, {}, multiEdit, {
                context: args.context
            }));

            if (args.useInvites) {
                var $fields = $multi.find('form table').find('th, td');
                var $accountFields = $fields.filter(function() {
                    return $(this).hasClass('account');
                });
                var $emailFields = $fields.filter(function() {
                    return $(this).hasClass('email');
                });

                $multi.prepend(
                    $('<div>').addClass('add-by')
                    .append($('<span>').html(_l('label.add.by') + ':'))
                    .append(
                        $('<div>').addClass('selection')
                        .append(
                            $('<input>').attr({
                                type: 'radio',
                                name: 'add-by',
                                checked: 'checked'
                            }).click(function() {
                                $accountFields.show();
                                $emailFields.hide();
                                $emailFields.find('input').val('');

                                return true;
                            }).click()
                        )
                        .append($('<label>').html(_l('label.account')))
                        .append(
                            $('<input>').attr({
                                type: 'radio',
                                name: 'add-by'
                            }).click(function() {
                                $accountFields.hide();
                                $accountFields.find('input').val('');
                                $emailFields.show();

                                return true;
                            })
                        )
                        .append($('<label>').html(_l('label.email')))
                    )
                );
            }

            return $multi;
        },

        dashboardTabs: {
            overview: function() {
                var $dashboard = $('#template').find('.project-dashboard-view').clone();
                $dashboard.data('tab-title', _l('label.menu.dashboard'));

                var getData = function() {
                    // Populate data
                    $dashboard.find('[data-item]').hide();
                    var $loading = $('<div>').addClass('loading-overlay').prependTo($dashboard);
                    cloudStack.projects.dashboard({
                        response: {
                            success: function(args) {
                                $loading.remove();
                                var data = args.data;

                                // Iterate over data; populate corresponding DOM elements
                                $.each(data, function(key, value) {
                                    var $elem = $dashboard.find('[data-item=' + key + ']');

                                    // This assumes an array of data
                                    if ($elem.is('ul')) {
                                        $elem.show();
                                        var $liTmpl = $elem.find('li').remove();
                                        $(value).each(function() {
                                            var item = this;
                                            var $li = $liTmpl.clone().appendTo($elem).hide();

                                            $.each(item, function(arrayKey, arrayValue) {
                                                var $arrayElem = $li.find('[data-list-item=' + arrayKey + ']');

                                                $arrayElem.text(_s(arrayValue));
                                                $arrayElem.attr('title', _s(arrayValue));
                                            });

                                            $li.attr({
                                                title: item.description
                                            });

                                            $li.fadeIn();
                                        });
                                    } else {
                                        $elem.each(function() {
                                            var $item = $(this);
                                            if ($item.hasClass('chart-line')) {
                                                $item.show().animate({
                                                    width: value + '%'
                                                });
                                            } else {
                                                $item.hide().html(_s(value)).fadeIn();
                                            }
                                        });
                                    }
                                });
                            }
                        }
                    });
                };

                getData();

                $dashboard.find('.button.manage-resources').click(function() {
                    $('.navigation-item.network').click();
                });

                $dashboard.find('.info-box.events .button').click(function() {
                    $('.navigation-item.events').click();
                });

                return $dashboard;
            },

            users: function() {
                return $('<div>').addClass('management').data('tab-title', _l('label.menu.accounts'));
            },

            invitations: function() {
                return $('<div>').addClass('management-invite').data('tab-title', _l('label.invitations'));
            },

            resources: function(options) {
                if (!options) options = {};

                var $resources = $('<div>').addClass('resources').data('tab-title', _l('label.resources'));
                var $form = $('<form>');
                var $submit = $('<input>').attr({
                    type: 'submit'
                }).val(_l('label.apply'));

                cloudStack.projects.resourceManagement.dataProvider({
                    response: {
                        success: function(args) {
                            $(args.data).each(function() {
                                var resource = this;
                                var $field = $('<div>').addClass('field');
                                var $label = $('<label>').attr({
                                    'for': resource.type
                                }).html(_s(resource.label));
                                var $input = $('<input>').attr({
                                    type: 'text',
                                    name: resource.type,
                                    value: resource.value,
                                    id: resource.type
                                }).addClass('required');

                                $field.append($label, $input);
                                $field.appendTo($form);
                            });

                            $form.validate();
                            $form.submit(function() {
                                if (!$form.valid) {
                                    return false;
                                }

                                var $loading = $('<div>').addClass('loading-overlay').appendTo($form);

                                cloudStack.projects.resourceManagement.update({
                                    data: cloudStack.serializeForm($form),
                                    response: {
                                        success: function(args) {
                                            $loading.remove();
                                            $('.notifications').notifications('add', {
                                                section: 'dashboard',
                                                desc: 'label.update.project.resources',
                                                interval: 1000,
                                                poll: function(args) {
                                                    args.complete();
                                                }
                                            });
                                        }
                                    }
                                }, options.projectID);

                                return false;
                            });

                            $submit.appendTo($form);
                            $form.appendTo($resources);
                        }
                    }
                }, options.projectID);

                return $resources;
            }
        },

        /**
         * Projects dashboard
         */
        dashboard: function() {
            var tabs = {
                dashboard: pageElems.dashboardTabs.overview
            };

            // Only show management tabs to owner of project
            if (isAdmin() || isDomainAdmin() || (
                cloudStack.context.projects &&
                (cloudStack.context.projects[0].account == cloudStack.context.users[0].account)
            )) {
                tabs.users = pageElems.dashboardTabs.users;

                if (g_capabilities.projectinviterequired) {
                    tabs.invitations = pageElems.dashboardTabs.invitations;
                }

                if (isAdmin() || isDomainAdmin()) {
                    tabs.resources = pageElems.dashboardTabs.resources;
                }
            }

            var $tabs = $('<div>').addClass('tab-content').append($('<ul>'));
            var $toolbar = $('<div>').addClass('toolbar');

            // Make UI tabs
            $.each(tabs, function(tabName, tab) {
                var $tab = $('<li>').appendTo($tabs.find('ul:first'));
                var $tabContent = tab();
                var $tabLink = $('<a>')
                    .attr({
                        href: '#project-view-dashboard-' + tabName
                    })
                    .html($tabContent.data('tab-title'))
                    .appendTo($tab);
                var $content = $('<div>')
                    .appendTo($tabs)
                    .attr({
                        id: 'project-view-dashboard-' + tabName
                    })
                    .append($tabContent);
            });

            $tabs.find('ul li:first').addClass('first');
            $tabs.find('ul li:last').addClass('last');

            $tabs.bind('tabsactivate', function(event, ui) {
                var $panel = $(ui.newPanel);
                var $management = $panel.find('.management');
                var $managementInvite = $panel.find('.management-invite');

                if ($management.length) {
                    $management.children().remove();
                    $management.append(pageElems.userManagement({
                        context: cloudStack.context
                    }));

                    return true;
                }

                if ($managementInvite.length) {
                    $managementInvite.children().remove();
                    $managementInvite.append(pageElems.userManagement({
                        context: cloudStack.context,
                        useInvites: true
                    }));
                }

                return true;
            });

            return $('<div>').addClass('project-dashboard')
                .append($.merge(
                    $toolbar,
                    $tabs.tabs()
                ));
        },

        /**
         * Add new project flow
         */
        newProjectForm: function() {
            var $newProject = $('<div>').addClass('new-project');
            $newProject.append($('<div>').addClass('title').html(_l('label.create.project')));

            var $form = $('<form>');
            var $formDesc = $('<div>').addClass('form-desc');
            var $projectName = $('<div>').addClass('field name')
                .append($('<label>').attr('for', 'project-name').html(_l('label.project.name')))
                .append($('<input>').addClass('required disallowSpecialCharacters').attr({
                    type: 'text',
                    name: 'project-name',
                    id: 'project-name'
                }));
            var $projectDesc = $('<div>').addClass('field desc')
                .append($('<label>').attr('for', 'project-desc').html(_l('label.display.text')))
                .append($('<input>').addClass('disallowSpecialCharacters').attr({
                    type: 'text',
                    name: 'project-display-text',
                    id: 'project-desc'
                }));
            var $submit = $('<input>').attr({
                type: 'submit'
            }).val(_l('label.create.project'));
            var $cancel = $('<div>').addClass('button cancel').html(_l('label.cancel'));
            var $loading = $('<div>').addClass('loading-overlay');

            // Form events/validation
            $form.validate();
            $form.submit(function() {
                if (!$form.valid()) return false;

                $form.prepend($loading);

                cloudStack.projects.add({
                    context: cloudStack.context,
                    data: cloudStack.serializeForm($form),
                    response: {
                        success: function(args) {
                            var project = args.data;
                            var $projectSwitcher = $('div.project-switcher');

                            $(window).trigger('cloudStack.fullRefresh');

                            // dynamically add newly created project into project switcher
                            $projectSwitcher.find('select').append(
                                $('<option>').val(project.id).html(project.name)
                            );

                            $loading.remove();

                            // Confirmation
                            $form.replaceWith(function() {
                                var $confirm = $('<div>').addClass('confirm');

                                // Update title with project name
                                $newProject.find('.title').html(_s(args.data.name));

                                // Show field data
                                $confirm.append($projectName).find('input').replaceWith( // Name
                                    $('<span>').addClass('value').html(_s(
                                        args.data.name
                                    ))
                                );
                                $confirm.append($projectDesc).find('input').replaceWith( // Display text
                                    $('<span>').addClass('value').html(_s(
                                        args.data.displayText
                                    ))
                                );

                                var $buttons = $('<div>').addClass('buttons');
                                var $addAccountButton = $('<div>').addClass('button confirm').html(_l('label.add.accounts'));

                                $addAccountButton.click(function() {
                                    // Show add user form
                                    $confirm.replaceWith(function() {
                                        var $userManagement = pageElems.userManagement({
                                            context: $.extend(true, {}, cloudStack.context, {
                                                projects: [project]
                                            }),
                                            useInvites: cloudStack.projects.requireInvitation()
                                        });
                                        var $nextButton = $('<div>').addClass('button confirm next').html(_l('label.next'));

                                        $newProject.find('.title').html(
                                            cloudStack.projects.requireInvitation() ?
                                            _l('label.invite.to') + ' ' + _s(args.data.name) :
                                            _l('label.add.accounts.to') + ' ' + _s(args.data.name)
                                        );
                                        $nextButton.appendTo($userManagement).click(function() {
                                            $newProject.find('.title').html(_l('label.review'));
                                            $userManagement.replaceWith(function() {
                                                var $review = $('<div>').addClass('review');
                                                var $projectData = $('<div>').addClass('project-data');

                                                // Basic project data
                                                $review.append($projectData);
                                                $projectData.append($projectName).find('input').replaceWith( // Name
                                                    $('<span>').addClass('value').html(_s(
                                                        args.data.name
                                                    ))
                                                );
                                                $projectData.append($projectDesc).find('input').replaceWith( // Display text
                                                    $('<span>').addClass('value').html(_s(
                                                        args.data.displayText
                                                    ))
                                                );

                                                // User/resouce tabs
                                                var $tabs = $('<div>').addClass('tabs resources').appendTo($review);
                                                var $ul = $('<ul>').appendTo($tabs)
                                                    .append(
                                                        // Users tab
                                                        $('<li>').addClass('first').append(
                                                            $('<a>').attr({
                                                                href: '#new-project-review-tabs-users'
                                                            }).html(
                                                                cloudStack.projects.requireInvitation() ?
                                                                _l('label.invitations') : _l('label.accounts')
                                                            )
                                                        )
                                                );

                                                if (isAdmin() || isDomainAdmin()) {
                                                    $ul.append(
                                                        // Resources tab
                                                        $('<li>').addClass('last').append(
                                                            $('<a>').attr({
                                                                href: '#new-project-review-tabs-resouces'
                                                            }).html(_l('label.resources'))
                                                        )
                                                    );
                                                }

                                                var $users = $('<div>').attr({
                                                    id: 'new-project-review-tabs-users'
                                                }).appendTo($tabs);
                                                cloudStack.context.projects = [project];

                                                var $resources;
                                                if (isAdmin() || isDomainAdmin()) {
                                                    $resouces = $('<div>')
                                                        .attr({
                                                            id: 'new-project-review-tabs-resouces'
                                                        })
                                                        .appendTo($tabs)
                                                        .append(pageElems.dashboardTabs.resources);
                                                }

                                                $tabs.tabs();

                                                $users.listView({
                                                    listView: {
                                                        id: 'project-accounts',
                                                        disableInfiniteScrolling: true,
                                                        fields: !cloudStack.projects.requireInvitation() ? {
                                                            username: {
                                                                label: _l('label.account')
                                                            }
                                                        } : {
                                                            account: {
                                                                label: _l('label.invited.accounts')
                                                            }
                                                        },
                                                        dataProvider: function(args) {
                                                            setTimeout(function() {
                                                                args.response.success({
                                                                    data: $.map($userManagement.find('.data-item tr'), function(elem) {
                                                                        // Store previous user data in list table
                                                                        return !cloudStack.projects.requireInvitation() ? {
                                                                            username: $(elem).find('td.username span').html()
                                                                        } : {
                                                                            account: $(elem).find('td.account span').html()
                                                                        };
                                                                    })
                                                                });
                                                            }, 0);
                                                        }
                                                    }
                                                });

                                                // Save button
                                                var $saveButton = $nextButton.clone().appendTo($review);
                                                $saveButton.html(_l('label.save'));
                                                $saveButton.click(function() {
                                                    $('#new-project-review-tabs-resouces').find('form').submit();
                                                    $('.ui-dialog, .overlay').remove();
                                                });

                                                $laterButton.click(function() {
                                                    $(':ui-dialog, .overlay').remove();

                                                    return false;
                                                });

                                                return $review;
                                            });

                                            $(':ui-dialog').dialog('option', 'position', 'center');
                                        });
                                        $laterButton.html(_l('label.close')).appendTo($userManagement);

                                        return $userManagement;
                                    });

                                    $(':ui-dialog').dialog('option', 'position', 'center');

                                    return false;
                                });

                                var $laterButton = $('<div>').addClass('button later').html(_l('label.remind.later'));
                                $laterButton.click(function() {
                                    $(':ui-dialog, .overlay').remove();

                                    return false;
                                });

                                $buttons.appendTo($confirm).append($.merge(
                                    $addAccountButton, $laterButton
                                ));

                                return $confirm;
                            });
                        },
                        error: cloudStack.dialog.error(function() {
                            $loading.remove();
                        })
                    }
                });

                return false;
            });

            $cancel.click(function() {
                $(':ui-dialog, .overlay').remove();
            });

            return $newProject
                .append(
                    $form
                    .append($formDesc)
                    .append($projectName)
                    .append($projectDesc)
                    .append($cancel)
                    .append($submit)
            );
        },

        /**
         * Project selection list
         */
        selector: function(args) {
            var $selector = $('<div>').addClass('project-selector');
            var $toolbar = $('<div>').addClass('toolbar');
            var $list = $('<div>').addClass('listing')
                .append($('<div>').addClass('header').html(_l('label.name')))
                .append($('<div>').addClass('data').append($('<ul>')));
            var $searchForm = $('<form>');
            var $search = $('<div>').appendTo($toolbar).addClass('search')
                .append(
                    $searchForm
                    .append($('<input>').attr({
                        type: 'text'
                    }))
                    .append($('<input>').attr({
                        type: 'submit'
                    }).val(''))
            );
            var $projectSelect = args.$projectSelect;
            var $cancel = $('<div>').addClass('button cancel').html(_l('label.cancel'));

            // Get project data
            var loadData = function(complete, options) {
                cloudStack.projects.dataProvider({
                    projectName: options ? options.projectName : null,
                    context: cloudStack.context,
                    response: {
                        success: function(args) {
                            var data = args.data;

                            $projectSelect.find('option').remove();
                            $(data).each(function() {
                                var displayText = this.displayText ? this.displayText : this.name;

                                $('<li>')
                                    .data('json-obj', this)
                                    .html(_s(displayText))
                                    .appendTo($list.find('ul'));

                                // Populate project select
                                $('<option>')
                                    .appendTo($projectSelect)
                                    .data('json-obj', this)
                                    .html(_s(displayText));
                            });

                            cloudStack.evenOdd($list, 'li', {
                                even: function($elem) {
                                    $elem.addClass('even');
                                },

                                odd: function($elem) {
                                    $elem.addClass('odd');
                                }
                            });

                            if (complete) complete();
                        }
                    }
                });
            };

            // Search form
            $searchForm.submit(function() {
                $list.find('li').remove();
                loadData(null, {
                    projectName: $(this).find('input[type=text]').val()
                });

                return false;
            });

            //Cancel button
            $cancel.click(function() {
                $(':ui-dialog, .overlay').remove();
                $('.select.default-view').click();
            });


            // Initial load
            loadData(function() {
                if (!$list.find('li').length) {
                    cloudStack.dialog.notice({
                        message: isAdmin() || isDomainAdmin() || g_userProjectsEnabled ? _l('message.no.projects') : _l('message.no.projects.adminOnly')
                    }).closest('.ui-dialog');
                    $.merge($selector, $('.overlay')).remove();
                    $('.select.default-view').click();
                } else {
                    $selector.dialog({
                        title: _l('label.select.project'),
                        dialogClass: 'project-selector-dialog',
                        closeOnEscape: false,
                        width: 420
                    }).closest('.ui-dialog').overlay();
                }
            });

            // Project item click event
            $selector.click(function(event) {
                var $target = $(event.target);

                if ($target.is('li')) {
                    cloudStack.context.projects = [$target.data('json-obj')];
                    showDashboard();

                    var $switcher = $('.select.project-view');
                    var projectName = _s(cloudStack.context.projects[0].name);

                    $switcher.attr('title', projectName);
                    if (projectName.length > 10) {
                        projectName = projectName.substr(0, 10).concat('...');
                    }

                    // Put project name in header
                    $switcher.html('<span class="icon">&nbsp;</span>' + projectName);


                    $.merge($selector, $('.overlay')).remove();

                    // Select active project
                    $projectSelect
                        .find('option').attr('selected', '')
                        .filter(function() {
                            return $(this).data('json-obj').name == _s(cloudStack.context.projects[0].name);
                        }).attr('selected', 'selected');

                    ////
                    // Hidden for now
                    //$projectSelect.parent().show();
                }
            });

            return $selector
                .append($toolbar)
                .append($list)
                .append($cancel);
        }
    };

    /**
     * Show project-mode appearance on CloudStack UI
     */
    var applyProjectStyle = function() {
        var $container = $('#cloudStack3-container');
        $container.addClass('project-view');
    };

    /**
     * Initiate new project flow
     */
    var addProject = function() {
        var $dialog = pageElems.newProjectForm().dialog({
            title: _l('label.new.project'),
            closeOnEscape: false,
            width: 760
        });
        cloudStack.applyDefaultZindexAndOverlayOnJqueryDialogAndRemoveCloseButton($dialog);
    };

    var deleteProject = function(args) {
        var projectId = args.id;
        var $projectSwitcher = $('div.project-switcher');
        var contextProjectId = cloudStack.context.projects ? cloudStack.context.projects[0].id : -1;

        $projectSwitcher.find('option[value="' + projectId + '"]').remove();

        //return to default view if current project is deleted
        if (contextProjectId == projectId) {
            $projectSwitcher.find('select').trigger('change');
        }
        return false;
    };

    /**
     * Show the dashboard, in panel
     */
    var showDashboard = function() {
        var $browser = $('#browser .container');
        applyProjectStyle($('html body'));

        // Cleanup project context
        if (cloudStack.context.projects)
            cloudStack.context.projects[0].isNew = false;

        $browser.cloudBrowser('removeAllPanels');
        $browser.cloudBrowser('addPanel', {
            title: _l('label.project.dashboard'),
            complete: function($newPanel) {
                $('#navigation li.dashboard').addClass('active').siblings().removeClass('active');
                $newPanel.append(pageElems.dashboard);
            }
        });
    };

    /**
     * Projects entry point
     */
    cloudStack.uiCustom.projects = function(args) {
        var $dashboardNavItem = $('#navigation li.navigation-item.dashboard');

        // Use project dashboard
        var event = function() {
            if (!$('#cloudStack3-container').hasClass('project-view')) {
                // No longer in project view, go back to normal dashboard
                $dashboardNavItem.unbind('click', event);

                return true;
            }

            $(this).addClass('active');
            $(this).siblings().removeClass('active');

            if (cloudStack.context.projects && cloudStack.context.projects[0]) {
                showDashboard();
            }

            return false;
        };
        $dashboardNavItem.bind('click', event);

        if (args.alreadySelected) {
            showDashboard();
        } else {
            pageElems.selector(args);
        }
    };

    /**
     * New project event
     */
    $(window).bind('cloudStack.newProject', function() {
        addProject();
    });


    $(window).bind('cloudStack.deleteProject', function(event, args) {
        deleteProject({
            id: args.data.id
        });
    });
})(cloudStack, jQuery);
