// ********************** world clocks *************************

var tmr;
var clocks = new Array();

//set timezones
var timezones = new Array();
timezones["London"] = 0;
timezones["Paris"] = 2;
timezones["Tokyo"] = 9;
timezones["New York"] = -5;

//calculate if daylight savings is in effect
var dstBegin = new Array();
var dstEnd = new Array();

/***** the below may need updating in future as dst can change from year to year *****/

//europe, begins 1am last sunday in march, ends 2am last sunday in October.
dstBegin["London"] = getLastSundayInMonth(2,1);
dstEnd["London"] = getLastSundayInMonth(9,1);
dstBegin["Paris"] = getLastSundayInMonth(2,1);
dstEnd["Paris"] = getLastSundayInMonth(9,1);

//new york, begins 2am first sunday in april, ends 2am last sunday in october
// From 2007 (until further notice) this is now: begins 2am second sunday in march, ends 2am first sunday in november
dstBegin["New York"] = getSecondSundayInMonth(2,2);
dstEnd["New York"] = getFirstSundayInMonth(10,1);

//tokyo, no dst adjustments required at present

/*************************** end of dst adjustments **********************************/

var months = new Array('Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec');

function getFirstSundayInMonth(month,time) {
  //return the date of the first sunday in the given month
  var d = new Date();
  d.setMonth(month);
  d.setDate(1);
  var day = d.getDay();
  while (day > 0) {
    d.setDate(d.getDate()+1);
    day = d.getDay();
  }
  d.setHours(time);
  d.setMinutes(0);
  d.setSeconds(0);
  return d;
}

function getSecondSundayInMonth(month,time) {
  //return the date of the second sunday in the given month
  var d = new Date();
  d.setMonth(month);
  d.setDate(8);
  var day = d.getDay();
  while (day > 0) {
    d.setDate(d.getDate()+1);
    day = d.getDay();
  }
  d.setHours(time);
  d.setMinutes(0);
  d.setSeconds(0);
  return d;
}

function getLastSundayInMonth(month,time) {
  //return the date of the last sunday in the given month
  var d = new Date();
  d.setMonth(month);
  var match = new Date();
  match.setMonth(month);
  match.setDate(1);
  while (d.getMonth() == month) {
    if (d.getDay() == 0) match.setDate(d.getDate());
    d.setDate(d.getDate()+1);
  }
  match.setHours(time);
  match.setMinutes(0);
  match.setSeconds(0);
  return match;
}

function getHand(clock,hand) {
  var index;
  if (hand == 'hours') index = 1;
  else if (hand == 'minutes') index = 3;
  else if (hand == 'seconds') index = 5;
  return clock.childNodes[0].childNodes[index];
}

function setTime(clock, time) {

  //compensate for daylight savings
  tzOffset = clock.tzOffset;
  if (clock.dstBegin && clock.dstEnd) {
    if (time > clock.dstBegin && time <= clock.dstEnd) tzOffset ++;
  }

  //apply timezone offset
  time.setTime(time.getTime() + 3600*1000*(tzOffset + time.getTimezoneOffset()/60));

  //set analogue time
  getHand(clock,'hours').style.left = Math.floor(time.getHours() % 12)*-15 + 'px'
  getHand(clock,'minutes').style.left = Math.floor(time.getMinutes()/2.5)*-15 + 'px'
  getHand(clock,'seconds').style.left = Math.floor(time.getSeconds()/2.5)*-15 + 'px'

  //set city
  clock.childNodes[1].innerHTML = '<strong>' + clock.city + '</strong>: ' + (time.getHours() % 24) + ':'
                                + padNumber(time.getMinutes(),2) + ', ' + time.getDate() + ' '
                                + months[time.getMonth()];
}

function getClassName(city) {
  return city.replace(' ','-').toLowerCase();
}

function updateClocks() {

  for (var c in clocks) {
    var now = new Date();
    setTime(clocks[c],now);
  }

}

addLoadEvent('topnav',function() {

  var divs = getElementsByTagName(document,'div');
  for (var d = divs.length-1;d > -1;d--) {
    var clockdiv = divs[d];
    if (clockdiv.className && clockdiv.className.indexOf('world-clock') > -1) {

      //add div to clocks array
      clocks.push(clockdiv);

      //add clock markup to div
      clockdiv.innerHTML = '<div class="clock-container">'
                         + '  <div class="hour-hand"><\/div>'
                         + '  <div class="minute-hand"><\/div>'
                         + '  <div class="second-hand"><\/div>'
                         + '<\/div>'
                         + '<span><\/span>'

      //get city and timezone
      for (var city in timezones) {
        var zoneClass = getClassName(city);
        if (clockdiv.className.indexOf(zoneClass) > -1) {
          clockdiv.city = city;
          clockdiv.tzOffset = timezones[city];
          clockdiv.dstBegin = dstBegin[city];
          clockdiv.dstEnd = dstEnd[city];
        }
      }

      //set intitial time
      setTime(clockdiv,new Date());

    }
  }
  tmr = window.setInterval("updateClocks()",1000);

});

// *********************** remember me *************************

function initRememberMe() {

  var remember = getElementById('remember-me');
  if (remember) {

    remember.style.visibility = 'visible';
    var form = getElementById('login-form');

    var username = getCookie('hemscottLoginDetails');
    if (username && username != '') {

      form.username.value = username;
      form.rememberme.checked = true;

    }

    var password = getCookie('hemscottPasswordDetails');
    if (password && password != '') {

      form.password.value = password;

    }

    addEvent(form,'submit',function () {

      var form = getElementById('login-form');

      if(form.rememberme.checked) {

        var expires = new Date();
        expires.setDate(expires.getDate()+3650); //expires after 10 years
        setCookie('hemscottLoginDetails',form.username.value,expires,'/');
        setCookie('hemscottPasswordDetails',form.password.value,expires,'/');

      } else {

        deleteCookie('hemscottLoginDetails');
        deleteCookie('hemscottPasswordDetails');

      }

    });

  }

}

// ************************* adverts ***************************

var tile = 1;
var pos = new Object();
var adTags = new Array();
var popupExclusions = new Array();
var ord = Math.random() * 100000000000000000;
var queryParams = getQueryParams(document.location.search);

//pages from which to exclude popups
popupExclusions.push('/');
popupExclusions.push('/home.do');
popupExclusions.push('/news/news-alerts-home.do');
popupExclusions.push('/news/news-alerts.do');
popupExclusions.push('/companies.do');
popupExclusions.push('/news/latest-news.do');
popupExclusions.push('/markets.do');
popupExclusions.push('/my-time.do');
popupExclusions.push('/news/rna.do');

//exclude popups from selected pages
for (var i in popupExclusions) {
  if (document.location.pathname == popupExclusions[i]) {
    adTags['!category'] = 'nopopup';
    break;
  }
}

addLoadEvent('disclaimer',function() {

  if (typeof(queryParams.showAdTags) != 'undefined') {
    var tags = '';
    for (var i in adTags) tags += i + '=' + adTags[i] + ';'
    alert(tags);
  }

  setInterval('refreshFeatures()', 120000);
  setInterval('refreshAds()', 120000);
});

function getAdFrame(type,tile,pos,includeIst) {

  //get ad tags parameters
  var misc = '';
  for (var i in adTags) misc += i + '=' + adTags[i] + ';'

  //show test ads for debugging purposes
  if (typeof(queryParams.testAds) != 'undefined') misc += 'test=testfiller;';

  return '<iframe allowtransparency="true" scrolling="no" frameborder="0" align="middle" src="/hsretail/jsp/adframe.jsp?type='
    + type + '&ad=' + queryParams[type] + '&tile=' + tile + '&misc=' + escape(misc) + '&ord=' + ord + '&pos=' + pos + '&ist='
    + includeIst + ((typeof(queryParams.showAdURL) != 'undefined')?'&showAdURL=true':'') + '"></iframe>';

}


function deleteCookie(name) {
  //delete a cookie
  document.cookie = name + '=; expires=-1; path=/';
}


function loadAd(type) {
  //load initial ad state
  if (typeof(pos[type]) == 'undefined') pos[type] = 1;
  document.write('<div id="' + type + pos[type] + '" class="' + tile + '">' + getAdFrame(type,tile++,type + pos[type]++,true) + '</div>');
}

function refreshFeatures() {
  //random = Math.random() * 100000000000000000;

  //for (var i = 1;refreshAd('feature',i);i++);
}

function refreshAds() {
  //ord = Math.random() * 100000000000000000;

  //for (var i = 1;refreshAd('banner',i);i++);
  //setTimeout(function() { for (var i = 1;refreshAd('skyscraper',i);i++); },2000);
  //setTimeout(function() { for (var i = 1;refreshAd('mpu',i);i++); },4000); 
}

function refreshAd(type,pos) {
  setWide(type + pos)
  var div = getElementById(type + pos)
  if (div) div.innerHTML = getAdFrame(type,div.className,div.id,false);
  return div;
}

function setNarrow(pos) {
  //resize an ad frame to be narrow
  /*var ad = getElementById(pos);
  if (ad) ad = ad.parentNode;
  if (ad && elementHasClass(ad,'banner')) applyClass(ad,'narrow-banner');
  else if (ad && elementHasClass(ad,'skyscraper')) applyClass(ad,'narrow-sky');*/
}

function setWide(pos) {
  //resize an ad frame to be wide
  /*var ad = getElementById(pos);
  if (ad) ad = ad.parentNode;
  if (ad && elementHasClass(ad,'banner')) removeClass(ad,'narrow-banner');
  else if (ad && elementHasClass(ad,'skyscraper')) removeClass(ad,'narrow-sky');*/
}

function flipAd(pos,content) {
  //function to move the ad out of the frame into the page body
  //this function is called from within adverts.js once ad has loaded
  var ad = document.getElementById(pos);
  if (ad) ad.innerHTML = content;
}

// *********************** market tabs *************************

var marketTabLinks;
var marketTabs;

addLoadEvent('disclaimer',function() {
  var marketsDiv = getElementById('market-nav');
  if (marketsDiv) {

    marketTabLinks = getElementsByTagName(marketsDiv,'a');
    for (var i=0;i < marketTabLinks.length;i++) {
      var href= marketTabLinks[i].href;
      marketTabLinks[i].href = 'javascript:setMarketTab(' + i + ');';
    }

    marketTabs = getElementsByClassName(getElementById('world-markets'),'div','market-tab');
  }
});

function setMarketTab(index) {
  for (var i=0;i < marketTabLinks.length;i++) {
    if (i == index) marketTabLinks[i].className = 'selected';
    else marketTabLinks[i].className = '';
  }
  for (var i=0;i < marketTabs.length;i++) {
    if (i == index) marketTabs[i].style.display = 'block';
    else marketTabs[i].style.display = 'none';
  }
}

// ******************** seminars validation ********************

addLoadEvent('disclaimer',function() {
  var seminarsForm = getElementById('seminars-form');
  if (seminarsForm) {

    addEvent(getElementById('invite-friend'),'click',function() {
      getElementById('friend-contact').style.display = (getElementById('invite-friend').checked)? 'block':'none';
    });

  }
});

// ************************* toolbox ***************************

function printPage() {
  window.print();
}

function bookmarkPage() {
  alert('Press Ctrl-D to add this page to favourites');
}

addLoadEvent('tool-box',function() {

  //print button
  var printButton = getElementById('toolbox-print');
  if (printButton) {
    printButton.style.display = 'block';
    printButton.href = 'javascript:printPage();';
  }

  //bookmark page
  var bookmarkButton = getElementById('toolbox-favourites');
  if (bookmarkButton) {
    bookmarkButton.style.display = 'block';
    bookmarkButton.href = 'javascript:bookmarkPage();';
  }

});

// *************** form, login and search fields ****************

function initSidebar() {

  //sidebar login and search
  var passText = 'Password';
  passPromptFunc();
  setElementClear(getElementById('login-box-username'),'Username');
  setElementClear(getElementById('company-search-box'),'Name or EPIC');

}

function setJsHover(element) {
  //dummy stub function for ie script
}

function clonePass(oldPass) {
  //clone a subset of the properties of the password input box
  var newPass = document.createElement('input');
  newPass.name = oldPass.name;
  newPass.className = oldPass.className;
  newPass.id = oldPass.id;
  newPass.title = oldPass.title;
  return newPass;
}

function passPromptFunc() {
  var oldPass = getElementById('login-box-password');
  if (!oldPass || oldPass.value != '') return;
  var newPass = clonePass(oldPass);
  newPass.type = 'text';
  newPass.value = passText;
  addEvent(newPass,'focus',passClearFunc);
  setJsHover(newPass);
  replaceElement(oldPass,newPass);
}

function passClearFunc() {
  var oldPass = getElementById('login-box-password');
  if (!oldPass || oldPass.value != passText) return;
  var newPass = clonePass(oldPass);
  newPass.type = 'password';
  addEvent(newPass,'blur',passPromptFunc);
  setJsHover(newPass);
  replaceElement(oldPass,newPass);
  setTimeout(function() {newPass.focus();},100);
}

function setElementClear(element,clearText) {
  //set a text input field to clear when focussed
  if (!element) return;
  addEvent(element,'focus',function() {
    element.focus();
    if (element.value != clearText) return;
    element.value = '';
  });
  addEvent(element,'blur',function() {
    if (element.value != '') return;
    element.value = clearText;
  });
  if (element.value == '') element.value = clearText;
  element.blur();
}

function updateNameEpicClearText() {
  //set the cleartext for the name/epic search field
  var field = getElementById('company-search-field');
  var radio = getElementById('search-type-name');
  if (!field || !radio) return;
  if (field.value != '' && field.value != 'Enter Name' && field.value != 'Enter Epic') return;
  if (radio.checked) field.value = 'Enter Name';
  else field.value = 'Enter Epic';
}

addLoadEvent('disclaimer',function() {

  //search page name/epic search
  //clear name/epic field based on radio button settings
  var field = getElementById('company-search-field');
  if (field) {
    addEvent(field,'focus',function() {
      field.focus();
      if (field.value != 'Enter Name' && field.value != 'Enter Epic') return;
      field.value = '';
    });
    addEvent(field,'blur',updateNameEpicClearText);
    updateNameEpicClearText();
    field.blur();
  }

  //name/epic search radio buttons
  addEvent(getElementById('search-type-name'),'click',updateNameEpicClearText);
  addEvent(getElementById('search-type-epic'),'click',updateNameEpicClearText);

  //sudoku submission form
  var sudokuForm = getElementById('submission-form');
  if (sudokuForm) {
    var fields = getElementsByClassName(sudokuForm,'input','textbox');
    setElementClear(fields[0],'Name');
    setElementClear(fields[1],'Email Address');
    setElementClear(fields[2],'Telephone No.');  
  }

  //seminars form
  var seminarsForm = getElementById('seminars-form');
  if (seminarsForm) {
    setElementClear(getElementById('friend-email'),'same as above');
    setElementClear(getElementById('friend-phone'),'same as above');
  }

});

// ********************* truncated links ***********************

var untruncated;

function setUntruncateHover(element) {
  if (element && element.title && element.title != '' && element.title != element.innerHTML) {

    element.untruncated = element.title;
    element.title = '';

    var offset = (typeof(isMSIE)!='undefined')? 4:3;

    addEvent(element,'mouseover',function() {
      untruncated.innerHTML = '<a href="' + element.href + '">' + element.untruncated + '</a>';
      setElementPosition(untruncated,getOffsetLeft(element) - offset, getOffsetTop(element) - 4);
    });

  }
}

addLoadEvent('disclaimer',function() {

  untruncated = createElement('div');
  insertElementBefore(untruncated,document.getElementById('footer'));
  untruncated.id = 'untruncated';

  addEvent(untruncated,'mouseout',function() {setElementPosition(untruncated,-1000,-1000);});

  var links = getElementsByClassName(document,'a','truncated');
  for (var i=0;i < links.length;i++) setUntruncateHover(links[i]);

});

// *************** external link functionality *****************

addLoadEvent('disclaimer',function() {
  var links = getElementsByTagName(document,'a');
  for(var i=0;i < links.length;i++) {
    var link = links[i];

    if (link.innerHTML.substring(0, 4) != 'www.'){
      if (link.href != '' && link.href.indexOf('mailto:') == -1) link.href = link.href.replace(/miranda/,'www');
    }

    if ((link.href.indexOf('http://') > -1 && link.href.indexOf('http://' + document.location.host) == -1)
     || (link.href.indexOf('https://') > -1 && link.href.indexOf('https://' + document.location.host) == -1)
     || elementHasClass(link,'external')) {
      link.target = "_blank";
      if (link.title == '') link.title = 'opens in a new window';
      else link.title += ' (opens in a new window)';
      if (!elementHasClass(link,'no-icon')
       && !elementHasClass(link,'feature')
       && !elementHasClass(link,'button')
       && !elementHasClass(link,'button-submit')
       && !elementHasClass(link,'anchor-submit')
       && !elementHasClass(link,'anchor-submit-arrow')
       && link.href.indexOf('google.com/intl/en_ALL/help/terms_maps') == -1
       && link.innerHTML.indexOf('<img') == -1
       && link.innerHTML.indexOf('<IMG') == -1) link.className += ' external-icon';
    }
  }
});

// ******************** news alerts popup message ************************

if (document.location.pathname == '/' || document.location.pathname == '/home.do') {
  //if (!getCookie('newsAlertsPopupDontShow')) addLoadEvent('container',openPopup);
  //if (!getCookie('newsAlertsPopunderDontShow')) openPopunder();
}

function openPopunder() {
  var popup = openPopup('newsAlertsPopunder');
  popup.blur();
  window.focus();
}

function openPopup(name) {
  if (typeof(name) == 'undefined') cookie = 'newsAlertsPopup';
  var popup = window.open('/hsretail/adverts/popups/news-alerts.html?' + name + 'DontShow',name,'width=1,height=1');
  if (popup.opener == null) popup.opener = window;
  return popup;
}

function setURL(url) {
  document.location.href = url;
}

// ******************** welcome message ************************

//if (!getCookie('newsAlertsPopupDontShow')) importScript('/hsretail/js/popup.js');

// ***************** general utility functions ******************

function padNumber(number,width) {
  //pad a number with zeros, up to the specified width;
  var s = '' + number;
  while (s.length < width) s = '0' + s;
  return s;
}

function trim(text) {
  //trim whitespace from a string
  text = text.replace(/^\s+/g,''); //leading space
  return text.replace(/\s+$/g,''); //trailing space
}

function elementHasClass(element, className) {
  //return true if the element has the given class name
  className = className.replace(/\-/g, '\\-');
  var re = new RegExp('(^|\\s)' + className + '(\\s|$)');
  return re.test(element.className);
}

function applyClass(element, className) {
  //add a class to an element
  if (!elementHasClass(element, className)) element.className += ' ' + className;
}

function removeClass(element, className) {
  //remove a class from an element
  className = className.replace(/\-/g, '\\-');
  var re = new RegExp('(^|\\s)' + className + '(\\s|$)');
  element.className = element.className.replace(re,'');
}

function getElementById(id) {
  //get element with a given id
  return (document.all)? document.all[id] : document.getElementById(id);
}

function getElementsByTagName(container, tagName) {
  //get all html nodes of a given type within a given container
  if (container) return container.getElementsByTagName(tagName);
  else return new Array();
}

function getElementsByClassName(container, tagName, className) {
  //get all html nodes of a given type and class within a given container
  var elements = getElementsByTagName(container, tagName);
  var result = new Array();
  for(var i=0;i < elements.length;i++) {
    var e = elements[i];
    if (elementHasClass(e,className)) result.push(e);
  }
  return result;   
}

function addEvent(element, event, func) {
  //add an event to the specified element, preserving any existing events that are attached
  if (!element) return;
  if (element.addEventListener) {
    element.addEventListener(event, func, false);
    return true;  
  } else {
    var oldFn = element['on' + event];
    var fn;
    if (oldFn) {
      fn = function() {
        return oldFn();
        return func();
      }
    } else {
      fn = func;
    }
    if (element.attachEvent) return element.attachEvent('on' + event, fn);
    else element['on' + event] = fn;
  }
}

function addLoadEvent(id,func) {
  //add an onload event which will fire once the given id is located within the document
  //this is more reliable than window.onload and will happen exactly when needed

  function loadEvent() {
    var element = getElementById(id);
    if (element) func(); else window.setTimeout(loadEvent,2000);
  }

  loadEvent();

}

function createElement(tagName) {
  //create an html node of the specified type
  return document.createElement(tagName);
}

function createTextNode(text) {
  //create an html text node
  return document.createTextNode(text);
}

function replaceElement(element,replacement) {
  //replace an html node with the specified alternative
  if (element) element.parentNode.replaceChild(replacement,element);
}

function insertElement(parent,child) {
  //insert an html node within the specified parent, after the last child
  if (parent) parent.appendChild(child);
}

function removeElement(element) {
  //remove the specified node from the dom tree
  if (element && element.parentNode) element.parentNode.removeChild(element);
}

function insertElementBefore(element,before) {
  //insert an html node before the specified element
  if (before && before.parentNode) before.parentNode.insertBefore(element,before);
}

function insertElementAfter(element,after) {
  //insert an html node after the specified element
  if (after && after.parentNode) {
    if (after.nextSibling) insertElementBefore(element,after.nextSibling);
    else insertElement(after.parentNode,element);
  }
}

function showChildren(element, show) {
  //show or hide all the children of the specified element
  var display = (show)? 'inline':'none';
  if (element) for (e in element.childNodes) {
    var e = element.childNodes[e];
    if (e.style) e.style.display = display;
  }
}

function setElementPosition(element,x,y) {
  //set the absolute (document relative) position of an element in pixels
  if (element.offsetParent) { // using ie's relative positioning model
    x -= getOffsetLeft(element.parentNode);
    y -= getOffsetTop(element.parentNode);
  }
  element.style.left = x + 'px';
  element.style.top = y + 'px';
}

function getOffsetTop(element) {
  //get the absolute (document relative) position of an element in pixels
  var o = element.offsetTop;
  while (element.offsetParent) {
    element = element.offsetParent
    o += element.offsetTop;
  }
  return o;
}

function getOffsetLeft(element) {
  //get the absolute (document relative) position of an element in pixels
  var o = element.offsetLeft;
  while (element.offsetParent) {
    element = element.offsetParent
    o += element.offsetLeft;
  }
  return o;
}

function importScript(url) {
  //import an external javascript file
  document.writeln('<script type="text/javascript" src="' + url + '"></scr' + 'ipt>');
}

function getQueryParams(query) {
  //decode query parameters into an associative array
  var params = new Object();
  if (!query) return params;
  var start = query.indexOf('?');
  if (start > -1) query = query.substr(start + 1);
  var paramArray = query.split("&");
  for (var i in paramArray) {
    var param = paramArray[i];
    var splitPos = param.indexOf("=");
    var name = unescape(param.substring(0,splitPos));
    var value = unescape(param.substring(splitPos+1));
    params[name] = value;
  }
  return params;
}

function setCookie(name, value, expires, path, domain, secure) {
  //set a cookie
  document.cookie = name + '=' + escape(value) +
    ((typeof(expires) != 'undefined' && expires) ? '; expires=' + expires.toGMTString() : '') +
    ((typeof(path) != 'undefined' && path) ? '; path=' + path : '; path=/') +
    ((typeof(domain) != 'undefined' && domain) ? '; domain=' + domain : '') +
    ((typeof(secure) != 'undefined' && secure) ? '; secure' : '');
}

function deleteCookie(name) {
  //delete a cookie
  document.cookie = name + '=; expires=0; path=/';
}

function getCookie(name) {
  //get a cookie
  var dc = document.cookie;
  var prefix = name + '=';
  var begin = dc.indexOf('; ' + prefix);
  if (begin == -1) {
    begin = dc.indexOf(prefix);
    if (begin != 0) return null;
  } else begin += 2;
  var end = document.cookie.indexOf(';', begin);
  if (end == -1) end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}