/*
 * $Id: nzski_2011.js,v 1.9 2011-05-23 10:23:43 han Exp $
 */

var nzski = (function($) {

  var utils = (function() {
    var covers = [];

    function cover_field(id, text, parent, cover) {
      var field = $(id);
      parent = parent || $("body");

      var shouldReposition = !cover;

      if (!cover) {
        cover = $("<div>").css({
          position : "absolute",
          width : field.width(),
          height : field.height(),
          fontSize : "8pt",
          lineHeight : 2.4,
          padding : "0px 10px",
          cursor : "text",
          color : "#999"
        }).addClass("field_cover");
      }

      if (text)
        cover.text(text);

      if (shouldReposition) {
        covers.push(function() {
          if (field.css("position") == "absolute") {
            cover.css({
              top : field.css("top"),
              left : field.css("left"),
              marginLeft : field.css("marginLeft")
            });
          } else {
            cover.css({
              top : field.offset().top,
              left : field.offset().left
            });
          }
        });
      }

      function focus() {
        cover.hide();
        field[0].focus();
      }

      cover.click(focus);
      field.click(focus).focus(focus);
      field.blur(function() {
        if (!field.val())
          cover.show();
      });

      if (field.val())
        cover.hide();

      parent.append(cover);
    }

    function position() {
      $(covers).each(function() {
        var f = this;
        f();
      });
    }

    $(window).resize(position);

    return {
      cover_field : cover_field,
      reposition_covers : position
    };
  })();

  /* make sure the backgrounds are positioned correctly */
  function resize_content() {
    if ($("#content").height() < $(window).height()) {
      $("#container").css("height", $(document).height() + "px");
    }
    $("#backgrounds").css("height", $(document).height() + "px");

    $("#backgrounds .br, #backgrounds .bl")[$(document).height() <= 1230 ? "hide"
        : "show"]();

    $("body")[$(window).height() < 650 ? "addClass" : "removeClass"]("short");
  }

  /* login form animation */
  function open_session() {
    var session = $("#session");
    if (session.hasClass("open") || session.hasClass("opening")
        || session.hasClass("closing"))
      return;

    session.addClass("opening");

    session.find(".controls").first().animate({
      width : 328
    }, {
      duration : 500,
      complete : function() {
        session.removeClass("opening");
        session.addClass("open");
      }
    });
    session.find(".login").fadeOut();
    $("#masthead .options.purchase h2 span").fadeOut();
    $("#session .arrow, #session-extra").fadeIn();
    $("#session input, #session .cover_container").fadeIn("slow");
  }

  function close_session() {
    var session = $("#session");
    if (!session.hasClass("open"))
      return;

    session.removeClass("open");
    session.addClass("closing");

    session.find(".controls").first().animate({
      width : 47
    }, {
      duration : 500,
      complete : function() {
        session.removeClass("closing");
      }
    });
    session.find(".login").fadeIn();
    $("#masthead .options.purchase h2 span").fadeIn();
    $("#session input, #session .cover_container, #session-extra").fadeOut();
    $("#session .arrow").fadeOut("fast");
  }

  function toggle_session() {
    var session = $("#session");
    if (session.hasClass("open")) {
      close_session();
    } else if (!(session.hasClass("opening") || session.hasClass("closing"))) {
      open_session();
    }
  }

  // menu
  var menu = {
    timeout : 0,

    open : function(e) {
      var menu = $("#masthead .purchase .menu");
      if (menu.is(":hidden")) {
        menu.slideDown(150);
      }

      clearTimeout(this.timeout);
      if (e)
        e.stopImmediatePropagation();
      return false;
    },

    close : function(e) {
      this.timeout = setTimeout(function() {
        var menu = $("#masthead .purchase .menu");
        if (!menu.is(":hidden")) {
          menu.slideUp(150);
        }
      }, 200);
      if (e)
        e.stopImmediatePropagation();
      return false;
    }
  };

  // slide show
  /*
   * the following map lists all the available slide shows for various sections.
   * they are organised mountain. if the mountain is missing otherwise is used
   */
  var slidesets = {
    coronetpeak : [ "/images/header/coronetpeak/01.jpg",
        "/images/header/coronetpeak/02.jpg",
        "/images/header/coronetpeak/03.jpg",
        "/images/header/coronetpeak/04.jpg",
        "/images/header/coronetpeak/05.jpg" ],

    theremarkables : [ "/images/header/theremarkables/01.jpg",
        "/images/header/theremarkables/02.jpg",
        "/images/header/theremarkables/03.jpg",
        "/images/header/theremarkables/04.jpg",
        "/images/header/theremarkables/05.jpg" ],

    mthutt : [ "/images/header/mthutt/01.jpg", "/images/header/mthutt/02.jpg",
        "/images/header/mthutt/03.jpg", "/images/header/mthutt/04.jpg",
        "/images/header/mthutt/05.jpg" ],

    otherwise : [ "/images/header/nzski/01.jpg", "/images/header/nzski/02.jpg",
        "/images/header/nzski/03.jpg", "/images/header/nzski/04.jpg",
        "/images/header/nzski/05.jpg", "/images/header/nzski/06.jpg"]
  };

  function getter(key) {
    return function() {
      return this[key];
    };
  }

  /* visiting the tarpit to create a lazy list that cycles */
  function cycle_list(array) {
    var first = {
      head : array[0],
      tail : null
    };
    var previous = first;
    var current = null;

    for ( var i = 1, j = array.length; i < j; i++) {
      current = {
        head : array[i]
      };

      previous.tail = (function(current) {
        return function() {
          return current;
        };
      })(current);
      previous = current;
    }
    previous.tail = function() {
      return first;
    };
    return first;
  }

  function lazy_to_array(lazy, n) {
    var a = [];
    while (n-- > 0 && lazy) {
      a.push(lazy.head);
      lazy = lazy.tail();
    }
    return a;
  }

  function init_slideshow(element_or_id, interval, callbacks) {
    var el = $(element_or_id);
    if (el.length == 0)
      return false;

    var slides = $(
        slidesets[$([ "mthutt", "theremarkables", "coronetpeak" ]).filter(
            function(_, n) {
              return $("body").hasClass(n);
            }).get(0)
            || "otherwise"]).map(function(_, n) {
      var i = new Image();
      var d = new $.Deferred();
      i.src = n;
      $(i).load(function() {
        d.resolve();
      });
      return {
        image : i,
        deferred : d
      };
    });

    var slideshow = {
      triggerSlide : function() {
      },
      readyDeferred : new $.Deferred()
    };

    $.when.apply($, $(slides).map(getter).toArray()).then(
        function() {
          var slide_template = el.find("div.slide").first();

          if (slide_template.length == 0)
            return; // no template, no slideshow

          var slide_els = [];
          $(slides).map(getter("image")).each(function() {
            var s = slide_template.clone();
            s.find("img:nth(1)")[0].src = this.src;
            s.css({
              "display" : "none"
            });
            el.append(s);
            slide_els.push(s);
          });

          var loop = cycle_list(slide_els);
          loop = {
            head : slide_template,
            tail : loop.tail
          }; // quick hack to get the first
          // slide out of the road

          function iterate() {
            loop.head.animate({
              "left" : -950
            }, {
              duration : 600
            });
            loop = loop.tail();
            loop.head.show();
            loop.head.css("left", 950);
            loop.head.animate({
              "left" : 0
            }, {
              duration : 600,
              complete : function() {
                if (callbacks.endSlide)
                  callbacks.endSlide();
              }
            });
            if (callbacks.beginSlide)
              callbacks.beginSlide();
          }

          setInterval(iterate, interval || 3000);

          slideshow.trigger_slide = iterate;
          slideshow.readyDeferred.resolve();
        });

    return slideshow;
  }

  function showUserInfo(username, verticalMeters) {
    $("body").addClass("loggedin");
    var meters = verticalMeters ? verticalMeters : "0";
    $("#user_info").html("Your vertical metres:<br/>" + meters + " m");
    $("#session-extra .profile").prepend("Welcome " + username);
  }

  function getUserInfo() {
    $.getJSON(window.mypassUrl + "/spring/nzski/jsonHeader?callback=?",
        function(data) {
          showUserInfo(data.User, data.Vertical);
        });
  }

  function login(username, password) {
    $.ajax({
      url : window.mypassUrl + "/spring/loginProcess",
      data : {
        j_username : username,
        j_password : password
      },
      dataType : "JSONP",
      success : function(data) {
        if (data.authenticated) {
          window.location.reload();
        } else {
          alert("Your login was unsuccessful, please check your username and password and try again."); 
        } 
      },
      error : function(xhr, status, error) {
        // TODO: failed to authenticated because of ajax error
      }
    });
  }

  function logout() {
    $.ajax({
      url : window.mypassUrl + "/spring/logout",
      dataType : "JSONP",
      complete : function() {
        window.location.reload();
      }
    });
  }

  // onready handlers and event registration

  $(function() {
    resize_content();

    var cover_container = $("<div class=\"cover_container\">").hide();
    $("#session .controls").append(cover_container);
    utils.cover_field("#session input[type=text]", "Username", cover_container,
        $("<div>Username</div>").addClass("cover_username").css({
          position : "absolute",
          zIndex : 1000,
          fontSize : "8pt",
          left : "135px",
          lineHeight : "38px"
        }));
    utils.cover_field("#session input[type=password]", "Password",
        cover_container, $("<div>Password</div>").addClass("cover_password")
            .css({
              position : "absolute",
              zIndex : 1000,
              fontSize : "8pt",
              left : "295px",
              lineHeight : "38px"
            }));

    if ($("#mypass form").length > 0) {
      utils.cover_field("#mypass form input[type=text]", null,
          $("#mypass form"), $("<div>Email Address</div>").addClass(
              "cover_email"));
      utils.cover_field("#mypass form input[type=password]", null,
          $("#mypass form"), $("<div>Password</div>")
              .addClass("cover_password"));
    }

    utils.reposition_covers();

    $("#session .mypass, #session .login").click(toggle_session);

    getUserInfo();

    $("#session").submit(function(event) {
      event.preventDefault();
      login($("#username").val(), $("#password").val());
    });

    $("#logout").click(function(event) {
      event.preventDefault();
      logout();
    });

    $("#masthead .purchase").mouseover(function(e) {
      return menu.open(e);
    }).mouseout(function(e) {
      return menu.close(e);
    });

    var animating = false;
    var pendingTransition = false;
    var slideshow = init_slideshow("#splash .gallery", 5000, {
      beginSlide : function() {
        animating = true;
        pendingTransition = false;
      },

      endSlide : function() {
        animating = false;
        if (pendingTransition) {
          slideshow.trigger_slide();
        }
        ;
        pendingTransition = false;
      }
    });

    if (slideshow && slideshow.readyDeferred) {
      slideshow.readyDeferred.then(function() {
        $("body").addClass("shownextslidebutton");
        $(".nextslide").click(function() {
          if (animating) {
            pendingTransition = true;
          } else {
            slideshow.trigger_slide();
          }
        });
      });
    }
  });

  $(window).resize(resize_content);
  $(window).load(resize_content);

  return {};
})(jQuery.sub());

