// This variable is used to store references to nodes, which we may use
// repeatedly across a bunch of different functions.
var Nodes = {};

var isBuggyIE = $.browser.msie && Number($.browser.version.split(".")[0]) <= 7;

$(document).ready(function() {
  // Flag the body as having JS present — this lets us specify custom JS 
  // specific styles.
  Nodes["body"] = $("body");
  Nodes["body"].addClass("javascript");
  // Stash a bunch of stuff in our nodes collection
  Nodes["wrapper"] = $("#wrapper");
  Nodes["inner"] = $("#inner");
  Nodes["content"] = $("#content");
  Nodes["nav"] = $("#navigation");
  //Nodes["nav"].disclosureNavigation();
  disclosureNavigation.setup(Nodes.nav);
  Nodes["siteTitle"] = $("#siteTitle");
  
  CatoAjax.init();
  
  Headings.init();
  
  // If we’re on the frontpage, hide the navigation.
  if ($("#intro").get(0)) {
    Nodes.nav.hide();
    Nodes.siteTitle.css({opacity:"0"});
    $("#skipIntro a").click(introCompleted);
    
    var flashvars = {forwardURL: "/aust/en/home", xml: "/public/introduction.xml"};
    var params = { quality:"high", bgcolor:0x000000, allowScriptAccess:"sameDomain", allowFullScreen:"false", wmode:"opaque" };
    var attributes = {};
    swfobject.embedSWF("/intro-slideshow.swf", "slideshow", "562", "375", "9.0.0", null, flashvars, params, attributes);
  }
});

var Headings = {
  init: function(callback) {
    // If we have a callback, store a reference to it
    this.callback = (callback ? callback : null);
    // Reset the counts
    this.complete = 0;
    this.count = 0;
    var simple = $("h1.simple");
    simple.flashComplexImageReplacement(
      "/images/text-replace.swf",
      {base:{
        font: "Helvetica Neue Black Condensed",
        size: "48",
        color: "0xF5A900",
        lineHeight: "-7",
        xOffset: "-3",
        yOffset: "-12",
        textTransform: "uppercase"
      }}
    );
    var newsItems = $("#newsItems li");
    newsItems.flashComplexImageReplacement(
      "/images/text-replace.swf", 
      {
        base: {
          color: "0x2A272A",
          lineHeight: "-7"
        },
        h2: {
          hoverColor: "0xF5A900",
          xOffset: "-3",
          yOffset: "2",
          font: "Helvetica Neue Black Condensed",
          size: "40",
          textTransform: "uppercase"
        },
        h3: {
          hoverColor: "0xFFFFFF",
          xOffset: "-3",
          yOffset: "-3",
          font: "Helvetica Neue",
          size: "13"
        }
      },
      {
        hoverFunction: "newsSliderHover",
        hoverOutFunction: "newsSliderHoverOut",
        pressFunction: "newsSliderClick"
      }
      
      

    );
    var careers = $("#careersList a");
    careers.flashComplexImageReplacement(
      "/images/text-replace.swf",
      {
        base: {
          color: "0x2A272A",
          lineHeight:"-7"
        },
        h2: {
          hoverColor: "0xF5A900",
          xOffset: "-3",
          yOffset: "3",
          font: "Helvetica Neue Black Condensed",
          size: "40",
          textTransform: "uppercase"
        },
        p: {
          hoverColor: "0xFFFFFF",
          yOffset: "-4",
          xOffset: "-3",
          font: "Helvetica Neue",
          size: "13"
        }
      },
      {
        hoverFunction: "",
        pressFunction: "careersClick"      }
    );
    // Increment all the totals
    this.count += simple.length;
    this.count += newsItems.length;
    this.count += careers.length;
  },
  completed: function(id) {
    this.complete += 1;
    if (this.complete == this.count && this.callback) {
      this.callback();
    }
  },
  isComplete: function() {
    return this.complete >= this.count;
  }
};

// Used on the map page to load the relevant location page.
function careersClick(url, id, key) {
  CatoAjax.load(true, url, Nodes.content);
};

// Used on the map page to load the relevant location page.
function loadLocation(url) {
  CatoAjax.load(true, url, Nodes.content);
};

// Get the height of the content and resize the inner if it's larger than 
// the minimum.
var resizeContent = function() {
  var newHeight = Nodes.content.height() + 56;
  if (newHeight <= 532) newHeight = 532;
  Nodes.inner.animate({height: newHeight + "px"});
};

var profileSwapper = function() {
  var current = null;
  // Move the profiles into a wrapper
  var profiles = $("div.profile");
  var wrapper = $('<div id="profileWrapper"></div>');
  $(profiles[0]).before(wrapper);
  profiles.appendTo(wrapper);
  // Position the images and set up the entries
  var entries = [];
  var images = $("div.profile img");
  images.each(function(i, img) {
    var img = $(img);
    img.attr("id", "profileLink" + i);
    img.css({left: 66 * i + "px"});
    entries[img.attr("id")] = $(profiles[i]);
    if (i > 0) {
      entries[img.attr("id")].addClass("disabled");
      img.css({opacity: 0.2});
    } else {
      current = img[0];
    }
  });
  // Attach events for hover effect on the images
  images.hover(
    function() { $(this).stop(); $(this).animate({opacity: 1}); },
    function() { if (this != current) {$(this).stop(); $(this).animate({opacity: 0.2});} }
  );
  // Attach events for showing and hiding profiles
  images.click(function() {
    if (this != current) {
      $(current).css({opacity: 0.2});
      entries[current.id].addClass("disabled");
      current = this;
      entries[current.id].removeClass("disabled");
      resizeContent();
    }
  });
};

function newsSlider(target) {
  var ANIMATE_SPEED = 1200;
  // Set all up nice now
  var previous = null;
  var current = null;
  var ul = $(target);
  var wrapper = $('#newsItemsWidget');
  
  // Add the overlay
  var overlay = $('<div id="overlay">&nbsp;</div>');
  wrapper.append(overlay);
  
  var open = false;
  // Associate the P, IMG with each LI
  var lis = ul.find("li");
  var entries = {};
  lis.each(function(i, li) {
    // Save a reference to each
    entries[i] = {image: $(li).find("img"), blurb: $(li).find("p")};
  });
  // Hide the paragraphs and image, append them in the wrapper
  ul.find("p").css({opacity: 0 });
  // Now pull all of them out, stick em in the wrapper.
  ul.find("p, img").appendTo(wrapper);

  this.newsSliderHover = function(id, key) {
    if(key && id){
      //hide other blurbs
      for(var i in entries){
        entries[i].blurb.stop().css({opacity: 0});
      }
      //show this
      entries[key].blurb.stop().css({opacity: 1});
    }
  };
  this.newsSliderHoverOut = function(id, key) {
    if(key){
      entries[key].blurb.animate({opacity: 0}, ANIMATE_SPEED);
    }
  };
  this.newsSliderClick = function(id, key) {
    if(id){
      var li = document.getElementById(id);
      li = $(li).parent().get();
      if(open != true){
        if (li != current) {
          open = true;
          $(li).removeClass("hover");
          $(li).addClass("current");
          current = li;
          entries[key].image.animate({left: "0px"}, ANIMATE_SPEED);
          ul.addClass("disabled");
          ul.animate({left: "575px"}, ANIMATE_SPEED);
          control.css({display: "block"});
        }
      } else {
        overlay.click();
      }
    };
  };
  
  this.cancel = function() {
    open = false;
    if (this == control) $(this).css({display: "none"});
    for(var i in entries){
      var e = entries[i];
      e.blurb.css({opacity: 0});
      e.image.animate({left: "-575px"}, ANIMATE_SPEED);
    }
    ul.animate({left: "0px"}, ANIMATE_SPEED);
    ul.removeClass("disabled");
    $(current).removeClass("current");
    control.hide();
    current = null;
  };
  
  // Add a control for cancelling the news display
  var control = $('<p id="newsCancel">Back to News</p>');
  wrapper.before(control);
  control.click(cancel);
  overlay.click(cancel);
  //
  //check for an open news item
  lis.each(function(i, e){
    if($(e).hasClass("current")){
      newsSliderClick(e.id, i);
    }
  });
};

// Simple rollover which displays or hides coressponding DD for each DT
$.fn.portfolioFeatures = function() {
  var previous = null;
  var dl = $(this);
  var dds = dl.find("dd");
  var dts = dl.find("dt");
  // Hide em all, and add a class that repositions them
  dds.css({opacity: 0});
  dl.addClass("widget");
  // Returns the index of the anchor/dd
  var getDD = function(anchor, value) {
    var dt = $(anchor).parent()[0];
    var index = dts.index(dt);
    return $(dds[index]);
  };
  // Attach event to DL
  dl.find("a").hover(
    function() {
      if (previous && previous != this) {
        getDD(previous).stop().css({opacity: 0});
      }
      getDD(this).stop().css({opacity: 1});
    },
    function() {
      getDD(this).animate({opacity: 0}, 1000);
      previous = this;
    }
  );
};

// Fades an alternate version of a news entry
$.fn.featuresFadeIn = function() {
  var features = $(this);
  var fade = features.clone();
  fade.attr("id", "featuresFade");
  features.after(fade);
  var fadeEntries = fade.find("a img");
  fadeEntries.css({opacity: 0});
  
  fadeEntries.hover(
    function() {$(this).stop().animate({opacity: 1}, 800);},
    function() {$(this).stop().animate({opacity: 0}, 200);}
  );
  
  fade.portfolioFeatures();
};


// Turns a set of nested ULs into a navigation element where the sub-nav 
// entries are disclosed using a toggle.
var disclosureNavigation = {
  currentParent: null,
  current: null,
  currentToggle: null,
  nodes: {},
  numberOfLis: 0,
  URLs: {},
  setup: function(list) {
    this.initialise(list);
  },
  // Recursive function which loops through all the nested ULs and adds 
  // toggle widgets where needed.
  initialise: function(ul) {
    // Mark the current parent first, so check all the anchors and see if any
    // of them match the current url. If they do, mark it as current.
    // window.location.pathname
    var LIs = $(ul).find("> li");
    for (var i=0; i < LIs.length; i++) {
      var li = $(LIs[i]);
      var a = li.find("> a");
      
      this.numberOfLis ++;
      var id = this.numberOfLis;
      
      // Store the ID against the anchor’s URL for quick lookup later
      this.URLs[this.stripDomain(a.attr("href"))] = id;
      
      a.addClass("disclosureNav_" + id);
      li.addClass("disclosureNav_" + id);
      
      var currentMeta = this.nodes[id] = {anchor: a, li: li, toggles: false, child: null};
      
      var ul = li.find("> ul");
      if (ul.length > 0) {
        // Store the height of the UL so we can resize it later
        currentMeta.height = ul.height();
        
        if (a.hasClass("currentParent")) {
          this.currentParent = id;
          this.currentToggle = id;
        }
        else {
          var options = {height: 0};
          if (!isBuggyIE) options.opacity = 0;
          ul.css(options);
        }
        
        a.addClass("toggles");
        
        currentMeta.toggles = true;
        currentMeta.child = ul;
        
        // attach toggle event
        // a.click(this.toggleClick);
        
        this.initialise(ul);
      }
      else if (a.hasClass("current")) {
        this.current = id;
      }
    };
    
  },
  // Event handler used for toggling a list open or closed.
  toggleClick: function(e) {
    var anchor = $(this);
    disclosureNavigation.toggle(anchor);
    e.preventDefault();
  },
  // This function allows other code to ask for a particular element to be 
  // highlighted based on the URL that gets passed in. Checks to see if it's 
   // a click on a toggle, we have to either open or close the sibling UL.
  select: function(url) {
    url = this.stripDomain(url);
    var id = this.URLs[url];
    if (id) {
      var meta = this.nodes[id];
      var target = meta.anchor;
      var li = meta.li;
      
      // Highlight the current selection
      this.highlight(target, li, id);
      
      // Check to see if we’re inside a sublist and need to toggle
      // Otherwise, close the existing toggle
      var listParent = li.parent().parent();
      if (listParent.is("li")) {
        this.toggle(listParent, true);
      }
      else if (this.currentToggle) {
        this.toggle(this.nodes[this.currentToggle].li);
      };
    }
  },
  // Toggles the sublist open or closed.
  toggle: function(li, stickOpen) {
    var id = this.getId(li);
    var meta = this.nodes[id];
    
    if (this.currentToggle == id) {
      if (!stickOpen) {
        this.currentToggle = null;
        options = {height: 0};
        if (!isBuggyIE) options.opacity = 0;
        meta.child.animate(options, 1000);
      }
    }
    else {
      var callback = function() {
        options = {height: meta.height};
        if (!isBuggyIE) options.opacity = 1;
        meta.child.animate(options, 1000);
      };
      if (this.nodes[this.currentToggle]) {
        options = {height: 0};
        if (!isBuggyIE) options.opacity = 0;
        this.nodes[this.currentToggle].child.animate(options, 500, callback);
      }
      else {
        callback();
      }
      this.currentToggle = id;
    }
  },
  // Adds a highlight to the selected element. This includes highlighting the
  // ancestor nodes and removing the highlight from the previous selection.
  highlight: function(target, li, id) {
    // Clear then update the current anchors
    if (this.currentParent) this.clear(this.currentParent, "currentParent");
    if (this.current) this.clear(this.current, "current");
    // Flag this page
    var className = (li.find("ul")[0] ? "currentParent" : "current");
    target.addClass(className);
    li.addClass(className);
    this.current = id;
    
    // Flag the parent
    this.currentParent = null;
    if (className == "current") {
      var parent = li.parent().parent();
      if (parent.is("li")) {
        parent.addClass("currentParent");
        var parentA = parent.find("> a");
        parentA.addClass("currentParent");
        this.currentParent = this.getId(parent);
      }
    }
  },
  // Utility function which returns the id of the selected element
  getId: function(element){
    var result = element.attr('class').match(/disclosureNav_(\d+)/);
    if (result) return result[1];
  },
  // Utility function which removes the specified class from the entry
  clear: function(entry, className) {
    this.nodes[entry].anchor.removeClass(className);
    this.nodes[entry].li.removeClass(className);
  },
  // A utility function which removes the domain off the front of a URL.
  stripDomain: function(url) {
    if (url.indexOf("?") >= 0) url = url.slice(0, url.indexOf("?"));
    if (url.match(/^(ftp|http|https)/)) {
      url = url.replace("http://", "");
      url = url.slice(url.indexOf("/"), url.length);
    }
    return url;
  }
};

// Callback for when the flash has finished
function introCompleted() {
  Nodes.nav.css({opacity: 0}).show();
  Nodes.nav.animate({opacity: 1}, 2000);
  Nodes.siteTitle.show().animate({opacity: 1}, 2000);
  //load the first link in the nav
  CatoAjax.load(true, Nodes.nav.find("a:first").attr('href'), Nodes.content);
  return false;
}


// Flash image replacement
jQuery.fn.flashComplexImageReplacement = function(path, vars, extras) {
  
  this.each(function(i, e){
    //
    var item = $(e);
    item.addClass("textReplaced");
    
    var flashvars = {};
    //pass txt to flash
    flashvars.txt = encodeURIComponent(item.html());
    
    //assign any extra parameters
    for(var v in extras){
      flashvars[v] = extras[v];
    }
    
    //break up all the variables for all the selectors into textReplace flashvars
    for(var v in vars){
      for(var k in vars[v]){
        flashvars["textReplace_"+v+"_"+k] = vars[v][k];
      }
    }
    
    //create a holder for the flash file
    var rand = String(Math.random() + Math.random() + Math.random());
    rand = rand.replace(".", "");
    var id = "flash_text_replace_" + i + rand;
    item.html('<div id="'+id+'" class="textReplacedWrap">' + flashvars.txt + '</div>');
    //setup any params
    params = {};
    //if(jQuery.browser.msie == false){
      params.wmode = "transparent";
    //}
    
    //pass variables to the flash so it knows what its called and what number it is
    flashvars.embeddedID = id;
    flashvars.embeddedKey = i;
    
    flashvars.width = item.width();
    flashvars.height = item.height();
    
    //check for a url and pass it to the flash
    if(item.attr("href")){
      flashvars.embeddedURL = item.attr("href");
    }
    
    //assign id and name (good practise for ExternalInterface)
    var attributes = {id:id, name:id};
    
    //embed the swf
    swfobject.embedSWF(path, id, Math.min(1000, item.width()), Math.min(1000, item.height()), "8.0.0", null, flashvars, params, attributes);
    
  });
  
  return this;
  
};

function textReplacedHeight(id, height, width) {
  var flash = $("#" + id);
  var parent = flash.parent();
  // Set the heights
  if (parent.is("h1.simple")) {
    var parentHeight = height;
    parentHeight = parentHeight < 48 ? 48 : parentHeight;
  } else if (parent.is("#newsItems li")) {
    var parentHeight = 48;
  } else if (parent.is("#careersList li a")) {
    height = height + 25;
    var parentHeight = height;
  }
  flash.height(height);
  parent.height(parentHeight);
  // Tell the headings obj we've finished loading this one
  Headings.completed(id);
}

