﻿(function() {
  if (jQuery.browser.msie && jQuery.browser.version < 6) return;
  var $ = jQuery;

  // Fix arrays in IE
  if (!Array.indexOf) {
    Array.prototype.indexOf = function(obj, start) {
      for (var i = (start || 0); i < this.length; i++) {
        if (this[i] == obj) {
          return i;
        }
      }
    }
  }

  $(document).ready(function() {
    af.allMunicipalitiesLabel = $('#municipalityList option.all').text() || af.allMunicipalitiesLabel;
    af.allCategoriesLabel = $('#categoryList option.all').text() || af.allCategoriesLabel;
    af.allSitesLabel = $('#siteList option.all').text() || af.allSitesLabel;

    $('#municipalityList').change(af.updateCategories).change();
    $('#categoryList').change(af.updateMunicipalities);

    $('#findButton input').click(function() {
      af.getActivities(af.displayActivities);
      return false;
    });
  });

  var af = {
    slow: 400,
    fast: 200,

    loadingPage: false,

    allMunicipalitiesLabel: 'Alla Kommuner',
    allCategoriesLabel: 'Alla Kategorier',
    allSitesLabel: 'Alla Platser',

    /*************************************************
    * Reload the municipalities for the current categories.
    *************************************************/
    updateCategories: function() {
      $('#categoryLabel').addClass('ajaxLoading');
      $.ajax({
        url: af.cleanUrl(window.location),
        data: {
          method: 'getCategories',
          municipalities: $('#municipalityList').val()
        },
        dataType: 'json',
        error: af.dataLoadFailed,
        success: function(data) {
          af.listLoaded(data, 'category', af.allCategoriesLabel, af.updateSites);
        }
      });
      return false;
    },

    /*************************************************
    * Reload the categories for the current municipalities.
    *************************************************/
    updateMunicipalities: function() {
      $('#municipalityLabel').addClass('ajaxLoading');
      $.ajax({
        url: af.cleanUrl(window.location),
        data: {
          method: 'getMunicipalities',
          categories: $('#categoryList').val()
        },
        dataType: 'json',
        error: af.dataLoadFailed,
        success: function(data) {
          af.listLoaded(data, 'municipality', af.allMunicipalitiesLabel, af.updateSites);
        }
      });
      return false;
    },

    /*************************************************
    * Reload the sites for the current municipalities
    * and categories.
    *************************************************/
    updateSites: function() {
      $('#siteLabel').addClass('ajaxLoading');
      $.ajax({
        url: af.cleanUrl(window.location),
        data: {
          method: 'getSites',
          municipalities: $('#municipalityList').val(),
          categories: $('#categoryList').val()
        },
        dataType: 'json',
        error: af.dataLoadFailed,
        success: function(data) {
          af.listLoaded(data, 'site', af.allSitesLabel, function() {
            if (this.children().length) $('#findButton button').removeAttr('disabled');
            else $('#findButton button').attr('disabled', 'disabled');
          });
        }
      });
      return false;
    },

    /*************************************************
    * Called when the find button has been pressed
    * and the data has been loaded.
    *************************************************/
    displayActivities: function(data) {
      $('#confirmation').empty();

      af.loadingPage = false;

      var activityList = $('#activityList');
      var displayActivities = function() {
        var windowPos = $('html,body').scrollTop()
        activityList.removeAttr('style').html(data);
        $('html,body').scrollTop(windowPos);

        var h = activityList.height();
        activityList.css({ height: 0 });
        activityList
          .animate({ height: h }, af.slow, 'swing', function() {
            $(this).removeAttr('style');
            $.scrollWindow('#activityList');
          })
          .find('.paging a')
            .click(function() {
              if (af.loadingPage) return;
              af.loadingPage = true;
              $('.paging-result').addClass('ajaxLoading');
              var uri = $.parseUri(this.href);
              af.getActivities(function(data) { af.pageActivity(data, uri.queryKey['page']); }, uri.queryKey['municipalities'], uri.queryKey['categories'], uri.queryKey['sites'], uri.queryKey['page']);
              return false;
            })
          .end()
          .find('thead th')
            .each(function() {
              this.style.width = $(this).width() + 'px';
            })
          .end()
          .find('tbody a')
            .click(af.displayApplicationForm)
          .end()
          .find('a.topLink')
            .click(function() {
              $.scrollWindow('#head');
              return false;
            });
      };

      if (activityList.children().length > 0)
        activityList.animate({ height: 0 }, af.slow, 'swing', displayActivities);
      else
        displayActivities();

      return false;
    },

    /*************************************************
    * Called when a paging link has been clicked
    * and the data has been loaded.
    *************************************************/
    pageActivity: function(data, pageNum) {
      af.loadingPage = false;
      var slow = 500, fast = 200;

      var currentTable = $('#activityList table');
      var tableWidth = currentTable.width() + 1;
      $('#activityList').width(tableWidth);

      var forw = (parseInt(currentTable.data('pagenum')) || 1) < pageNum;
      var newTable = $(data).filter('table')
                .css('margin-left', (forw ? 1 : -1) * tableWidth)
                .insertAfter(currentTable.css({ 'position': 'absolute' }))
                .data('pagenum', pageNum)
                .find('tbody a').click(af.displayApplicationForm).end();

      var delta = newTable.height() - currentTable.height();
      var pagingMargin = parseInt($(".paging").css('margin-top'));
      var oldHeight = $('#activityList').height();

      if (delta > 0) {         // new > old
        $(".paging").css('margin-top', pagingMargin - delta).animate({ 'marginTop': pagingMargin }, { duration: fast, queue: false });
      } else if (delta < 0) {  // new < old
        $('#activityList').css('height', oldHeight - delta);
        $(".paging").css('margin-top', pagingMargin - delta);
      }

      currentTable.animate({ 'left': (forw ? -1 : 1) * tableWidth }, slow, function() { currentTable.remove(); });
      newTable.animate({ 'marginLeft': 0 }, slow, function() {
        if (delta < 0) {   // new < old
          $('#activityList').animate({ 'height': $('#activityList').height() + delta }, fast, function() { $(this).removeAttr('style'); });
          $(".paging").animate({ 'marginTop': pagingMargin }, fast, function() { $(this).removeAttr('style'); });
        } else {
          $(".paging").removeAttr('style');
          $(".activityList").removeAttr('style');
        }
      });

      $(".paging").animate({ 'opacity': 0 }, fast, function() {
        $(this)
          .html($(data).filter('.paging').html())
          .animate({ 'opacity': 1 }, fast)
          .find('a').click(function() {
            $('.paging-result').addClass('ajaxLoading');
            var uri = $.parseUri(this.href);
            af.getActivities(function(data) { af.pageActivity(data, uri.queryKey['page']); }, uri.queryKey['municipalities'], uri.queryKey['categories'], uri.queryKey['sites'], uri.queryKey['page']);
            return false;
          });
      });

      return false;
    },

    /*************************************************
    *
    *************************************************/
    getActivities: function(callback, municipalities, categories, sites, page) {
      $.ajax({
        url: af.cleanUrl(window.location),
        data: {
          method: 'getActivities',
          municipalities: municipalities || $('#municipalityList').val(),
          categories: categories || $('#categoryList').val(),
          sites: sites || $('#siteList').val(),
          page: page
        },
        dataType: 'html',
        error: af.dataLoadFailed,
        success: callback
      });

      return false;
    },

    /*************************************************
    * Load the application form of the specified activity.
    *************************************************/
    displayApplicationForm: function() {
      var uri = $.parseUri(this.href);
      var linkRow = $(this).parent().parent();
      $.ajax({
        url: af.cleanUrl(window.location),
        data: {
          method: "getApplicationForm",
          municipalities: uri.queryKey['municipalities'],
          categories: uri.queryKey['categories'],
          sites: uri.queryKey['sites'],
          page: uri.queryKey['page'],
          activity: uri.queryKey['activity']
        },
        dataType: "html",
        error: af.dataLoadFailed,
        success: function(data) {
          $('tr.activityDescription div:first').slideUp(af.slow, function() {
            $(this).parent().parent().remove();
          });
          $('a', linkRow).unbind('click').click(function() {
            linkRow.find('a').unbind('click').click(af.displayApplicationForm)
                        .end().next().find('div:first').slideUp(af.slow, function() {
                          $(this).parent().parent().remove();
                        });
            return false;
          });

          $('<div>' + data + '</div>').hide()
                        .appendTo($('<td colspan="5"/>').appendTo($('<tr class="activityDescription"/>').insertAfter(linkRow)))
                        .slideDown(af.slow)
                        .find('#applyButton button').click(af.applyToActivity);
        }
      });

      return false;
    },

    /*************************************************
    * Send the application data.
    *************************************************/
    applyToActivity: function() {
      if (!af.validateApplication()) {
        $.scrollWindow('#applicationForm');
        return false;
      }
      var uri = $.parseUri(this.href);
      $.ajax({
        url: af.cleanUrl(window.location),
        data: $.param({ method: "applyToActivity", activity: $('#currentActivity').val() }) + '&' + $('form').serialize(),
        dataType: "html",
        type: "POST",
        success: af.confirmApplication,
        error: af.dataLoadFailed
      });

      return false;
    },

    /*************************************************
    * Validate the data entered in the application form.
    *************************************************/
    validateApplication: function() {
      var valid = true;
      var validateField = function(field) {
        if (!$(field).val()) {
          $(field + "Label").addClass("error");
          return false;
        }
        else {
          $(field + "Label").removeClass("error");
        }
        return true;
      };

      var validateEmailField = function(field) {
      //var regExEmail = /^([a-zA-Z0-9_.-])+@(([a-zA-Z0-9-])+.)+([a-zA-Z0-9]{2,4})+$/;
      var regExEmail = new RegExp(/^([a-zA-Z0-9]{3,})(((\.|\-|\_)[a-zA-Z0-9]{2,})+)?@([a-z]{3,})(\-[a-z0-9]{3,})?(\.[a-z]{2,})+$/);

        if (!regExEmail.test($(field).val())) {
          $(field + "Label").addClass("error");
          return false;
        }
        else {
          $(field + "Label").removeClass("error");
        }
        return true;
      };

      if ($("#childPanel").length > 0) {
        var childPanelFields = ["#dateOfBirth", "#childFirstName", "#childLastName"];
        for (var i = 0; i < childPanelFields.length; i++) {
          valid &= validateField(childPanelFields[i]);
        }
      }

      if ($("#adultPanel").length > 0) {
        var adultPanels = ["#firstName", "#lastName", "#streetAddress", "#zipCode", "#city", "#mobilePhone"];
        var adultPanelEmail = "#emailAddress";
        for (var i = 0; i < adultPanels.length; i++) {
          valid &= validateField(adultPanels[i]);
        }

        if (validateField(adultPanelEmail) & validateEmailField(adultPanelEmail)) {
          valid &= true;
        }
        else {
          valid &= false;
        }
      }

      return valid;
    },

    /*************************************************
    *
    *************************************************/
    confirmApplication: function(data) {
      $.scrollWindow('#activityFinder');
      $('#activityList').slideUp(af.slow, function() { $(this).empty() });
      $('#applicationForm').slideUp(af.slow, function() { $(this).empty() });

      $.ajax({
        url: af.cleanUrl(window.location),
        data: { method: "setConfirmation" },
        dataType: "html",
        type: "POST",
        success: function(data) {
          $("#confirmation").html(data);
          return false;
        }
      });

      return false;
    },

    /*************************************************
    * Called when list load Ajax call is complete.
    * Update the list and keep the current selection.
    *************************************************/
    listLoaded: function(data, listName, allItemsLabel, callback) {
      var label = $('#' + listName + 'Label');
      var list = $('#' + listName + 'List');

      label.removeClass('ajaxLoading');

      var selectedItems = list.val() || '';
      list.empty();
      if (!data.length) {
        list.attr('disabled', true);
        return;
      }

      list.removeAttr('disabled');
      list.append('<option class="all" value="-1">' + allItemsLabel + '</option>');
      af.loadListData.apply(list, [data, selectedItems]);

      // If nothing is selected in the list, select the first option item.
      if (!list.find('option[selected]').length) list.find('option:first').attr('selected', 'selected');

      if (callback) callback.apply(list);
    },

    /*************************************************
    * Load groups and options into a select list.
    *************************************************/
    loadListData: function(data, selectedItems) {
      for (var i = 0; i < data.length; i++) {
        var item = data[i];
        if (item.data) {
          var group = $('<optgroup label="' + item.name + '">').appendTo(this);
          af.loadListData.apply(group, [item.data, selectedItems]);
          continue;
        }

        if (selectedItems && selectedItems.indexOf(String(item.id)) > -1) {
          this.append('<option value="' + item.id + '" selected="selected">' + item.name + '</option>');
        } else {
          this.append('<option value="' + item.id + '">' + item.name + '</option>');
        }
      }
    },

    /*************************************************
    * Called when an error occurred during list load.
    *************************************************/
    dataLoadFailed: function(request, textStatus) {
      $('.ajaxLoading').removeClass('ajaxLoading');
      alert('dataLoadFailed: ' + textStatus);
    },

    /*************************************************
    * Remove all the parameters from the specified url.
    *************************************************/
    cleanUrl: function(url) {
      url = String(url);
      var startPos = url.indexOf('?');
      return (startPos == -1) ? url : url.substr(0, startPos);
    }
  };
})();
