// 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) {
  $(window).bind('cloudStack.ready', function() {
    // Region switcher
    var $regionList = $('<ul>');

    // Get region listing
    var refreshRegions = function() {
      $regionList.find('li').remove();
      cloudStack.sections.regions.regionSelector.dataProvider({
        response: {
          success: function(args) {
            var data = args.data;
            var activeRegionID = args.activeRegionID;

            $(data).each(function() {
              var region = this;
              var regionName = region.name;
              var $li = $('<li>').append($('<span>').html(_s(region.name)));

              $li.data('region-data', region);

              if (region.id == activeRegionID) {
                $li.addClass('active');
              }
              
              $regionSwitcherButton.find('.title')
                .html(regionName)
                .attr('title', regionName);
              
              $regionList.append($li);
            });
          }
        }
      });
    };

    $(window).bind('cloudStack.refreshRegions', refreshRegions);

    var $regionSelector = $('<div>').addClass('region-selector')
    .append($('<div>').addClass('top-arrow'))
    .append($('<h2>').html(_l('label.menu.regions')))
    .append($regionList)
    .append(
      $('<div>').addClass('buttons')
      .append(
        $('<div>').addClass('button close').append($('<span>').html(_l('label.close')))
      )
    )
    .hide();
    var $regionSwitcherButton = $('<div>').addClass('region-switcher')
    .attr('title', 'Select region')
    .append(
      $('<span>').addClass('icon').html('&nbsp;'),
      $('<span>').addClass('title').html('')
    );

    var closeRegionSelector = function(args) {
      $regionSwitcherButton.removeClass('active');
      $regionSelector.fadeOut(args ? args.complete : null);
      $('body > .overlay').fadeOut(function() { $('body > .overlay').remove() });
    };

    var switchRegion = function(url) {
      closeRegionSelector({
        complete: function() {
          $('#container').prepend($('<div>').addClass('loading-overlay'));

          document.location.href = url;
        }
      });
    };

    $regionList.click(function(event) {
      var $target = $(event.target);
      var $li = $target.closest('li');
      var region, url;

      if ($li.size() && !$li.hasClass('active')) {
        region = $li.data('region-data');
        url = region.endpoint;
        id = region.id;

        if (id != '-1') {
          switchRegion(url);
        }
      }
    });

    $regionSwitcherButton.click(function() {
      if ($regionSwitcherButton.hasClass('active')) {
        closeRegionSelector();
      } else {
        $regionSwitcherButton.addClass('active');
        $regionSelector.fadeIn('fast').overlay({ closeAction: closeRegionSelector });
      }
    });

    $regionSelector.find('.button.close').click(function() {
      closeRegionSelector();
    });
    
    $('#header .controls .view-switcher.button:last').after($regionSwitcherButton, $regionSelector); 
    refreshRegions();
  });
}(jQuery, cloudStack));      
        
