var pageTracker = new Object;
var hueDrag = false;
var linkActive = false;
var linkCurrent = null;
var linkInfo = null;
var galleryDisplay = null;
var linkIcons = new Array();
function init() {
  $('.hue').click(hueSet);
  $('.hue').mousedown(function(e) {
    $('body').css('cursor', 'move');
    $('body').mousemove(hueSet);
    $('body').select(function(e) { return false; });
    e.preventDefault();
    $('body').bind('mouseup mouseleave',function(e) {
      $('body').unbind('mousemove mouseup mouseleave');
      $('body').css('cursor', '');
    });
  });
  linkCurrent = '#' + $('body > section > article:first').attr('id').replace(/\:/g, '\\:');
  $(window).resize(minHeight);
  minHeight();
  $.each($('a'), function (key, value) { linkBehaviour(value); });
  $(window).hashchange(function() { linkSwitch(location.hash); });
  loadTwitter();
}
function minHeight() {
  var contentsize = $('body').height() - ($('body > footer').offset().top + $('body > footer').innerHeight());
  $('body > section').animate({ 'min-height': ($('body > section').height() + contentsize) }, 200);
  if (galleryDisplay != null) {
    $('> figure img', galleryDisplay).css({
      'max-width': $('body').width() - 100 + 'px',
      'max-height': $('body').height() - ($('> figure > figcaption', galleryDisplay).outerHeight(true) * 2) - 20 + 'px'
    });
    $('> figure', galleryDisplay).css('line-height', $('> figure img', galleryDisplay).css('max-height'));
  }
}

function linkBehaviour(link) {
  if (linkInfo == null) {
    linkInfo = document.createElement('figure');
    linkInfo.className = 'link';
    var linkTitle = document.createElement('p');
    linkIcons['default'] = document.createElement('img');
    linkIcons['default'].src = '/img/favicon-default.png';
    linkIcons['default'].alt = '';
    var linkHref = document.createElement('figcaption');
    linkInfo.appendChild(linkTitle);
    linkInfo.appendChild(linkIcons['default']);
    linkInfo.appendChild(linkHref);
    $('body').append(linkInfo);
  }
  if (galleryDisplay == null) {
    galleryDisplay = document.createElement('div');
    galleryDisplay.className = 'gallery';
    var galleryFigure = document.createElement('figure');
    var galleryTitle = document.createElement('figcaption');
    var galleryImage = document.createElement('img');
    var galleryNav = document.createElement('nav');
    var galleryMatte = document.createElement('div');
    galleryFigure.appendChild(galleryTitle);
    galleryFigure.appendChild(galleryImage);
    galleryFigure.appendChild(galleryNav);
    galleryDisplay.appendChild(galleryMatte);
    galleryDisplay.appendChild(galleryFigure);
    $('body').append(galleryDisplay);
    $(galleryDisplay).click(function() { $(galleryDisplay).fadeTo(500, 0, function() { $(this).css('display', 'none'); }); });
  }
  var href = $(link).attr('href');
  if (href.match(/.(jpe?g|png|gif)$/i) || href.match(/^http:\/\/twitpic.com\//i)) {
    $(link).click(linkGallery);
  } else if (href.charAt(0) == '/') {
    $(link).click(linkSwitch);
  } else if (href.match(/^(https?|ftp|file):\/\//i)) {
    var domainSplit = href.split('/');
    var domain = domainSplit[2];
    if (!linkIcons[domain]) {
      linkIcons[domain] = document.createElement('img');
      linkIcons[domain].src = 'http://' + domain + '/' + 'favicon.ico';
      linkIcons[domain].alt = '';
      $(linkIcons[domain]).error(function() { this.src = linkIcons['default'].src; });
      debugOutput(domain + ': ' + linkIcons[domain].src);
    }
    $(link).click(function() {
      var newWindow = window.open($(this).attr('href'), '_blank');
      newWindow.focus();
      return false;
    });
    $(link).hover(linkDetails, function() {
      $(linkInfo).css('display', 'none');
      var oldTitle = $('p', linkInfo).text();
      if (oldTitle) this.title = oldTitle;
    });
  }
}

function linkSwitch(hash) {
  if (linkActive) return false;
  linkActive = true;
  var href, hrefIdEsc, content = null;
  if (typeof hash == 'string') {
    href = hash.replace(/#/g, '');
  } else {
    href = $(this).attr('href').replace(/#/g, '');
  }
  if (href) {
    var hrefId = 'page' + href.replace(/\//g, ':');
    hrefIdEsc = hrefId.replace(/\:/g, '\\:');
    debugOutput('href: ' + href + ' | ' + hrefId + ' | ' + hrefIdEsc + ' | ' + linkCurrent);
    content = $('#' + hrefIdEsc);
  } else {
    content = $('body > section > article:first');
    hrefIdEsc = $(content).attr('id').replace(/\:/g, '\\:');
  }
  if (!content.length) {
    content = document.createElement('article');
    content.id = hrefId;
    $(content).load('/cache' + href, function() {
      $('body > section').append(content);
      linkSlide('#' + hrefIdEsc);
      $.each($('a', content), function (key, value) { linkBehaviour(value); });
      $('code', content).chili();
    });
  } else {
    if ($(content).attr('id') != $(linkCurrent).attr('id')) {
      linkSlide('#' + hrefIdEsc);
    } else {
      linkActive = false;
      return false;
    }
  }
  if (href) window.location = '#' + href;
  if (typeof pageTracker._trackPageview != 'function') pageTracker = _gat._getTracker('UA-15988759-3');
  if (typeof pageTracker._trackPageview != 'function') pageTracker._trackPageview(href);
  return false;
}

function linkGallery() {
  var src = $(this).attr('href');
  if (src.match(/^http:\/\/twitpic.com\//i)) {
    src = src.replace(/^http:\/\/twitpic.com\/([a-z0-9]+)$/i, "http://twitpic.com/show/full/$1.jpg");
  }
  var alt = '';
  if ($('> img' ,this).length) {
    alt = $('> img' ,this).attr('alt');
  } else if (!$(this).text().match(/^(https?|ftp|file):\/\//i)) {
    alt = $(this).text();
  } else {
    alt = $(this).parent().text().replace($(this).attr('href'), '');
  }
  var image = $('> figure img', galleryDisplay);
  $(image).load(function() {
    $(this).fadeTo(500, 1);
    $(this).unbind();
    $('> figure', galleryDisplay).removeClass('loading');
  });
  $(image).css('display', 'none');
  $('> figure', galleryDisplay).addClass('loading');
  $(galleryDisplay).fadeTo(500, 1);
  $(image).attr('src', src);
  minHeight();
  $(image).attr('alt', alt);
  $('> figure figcaption', galleryDisplay).text(alt);
  return false;
}

function linkSlide(current) {
  var header = $('> header > h1', current);
  if (header.length) {
    document.title = $(header).text() + ' ᚑ Gwellin.ca';
  } else {
    document.title = 'Gwellin.ca';
  }
  var prior = linkCurrent;
  $(current).css({ 'position': 'absolute', 'margin-left': '1000px', 'opacity': '0' });
  $(prior).css({ 'position': 'absolute', 'margin-left': '0px' });
  $('body > section').css('height', $(prior).height() + 'px');
  $(current).animate({ 'margin-left': '0px', 'opacity': '1' }, 500, function() {
    if ($('body > section').height() < $(this).height()) {
      $('body > section').animate({ 'height': $(this).height() + 'px' }, 500);
    }
  });
  $(prior).animate({ 'margin-left': '-1000px', 'opacity': '0' }, 500);
  $('body > section').animate({ 'height': $(current).height() + 'px' }, 500);
  linkCurrent = current;
  linkActive = false;
}

function linkDetails(e) {
  var domainSplit = this.href.split('/');
  var domain = domainSplit[2];
  if (this.title) {
    $('p', linkInfo).text(this.title);
    this.title = '';
    $('p', linkInfo).css('display', 'block');
  } else {
    $('p', linkInfo).text('');
    $('p', linkInfo).css('display', 'none');
  }
  if (linkIcons[domain]) {
    $('img', linkInfo).attr('src', linkIcons[domain].src);
  } else {
    $('img', linkInfo).attr('src', linkIcons['default'].src);
  }
  $('figcaption', linkInfo).text(this.href);
  var linkPos = $(this).offset();
  var posTop = linkPos.top + $(this).outerHeight();
  var posLeft = linkPos.left - ($(linkInfo).outerWidth() - $(this).outerWidth()) / 2;
  $(linkInfo).css('top', posTop);
  $(linkInfo).css('left', posLeft);
  $(linkInfo).fadeTo(200, 0.97);
}

function hueSet(e) {
  var hue, hueDiff;
  if (e.pageX) {
    hueDiff = (e.pageX - $('.hue').offset().left) / $('.hue').width();
    if (hueDiff < 0) hueDiff = 0;
    else if (hueDiff > 1) hueDiff = 1;
    hue = Math.round(hueDiff * 359);
    setCookie('humble-hue', hue, 60, '/');
  } else {
    hue = Math.round(e);
    if (hue < 0) hue = 0;
    else if (hue > 359) hue = 359;
    hueDiff = hue / 359;
  }
  debugOutput('Hue: ' + hue + '°');
  $('.hue figure').css('left', hueDiff * 100 + '%');
  $('.hue figure figcaption').attr("title", 'Hue value: ' + hue + '°');
  var fighsl = hexToHsl($('.hue figure figcaption').css('background-color'));
  $('.hue figure figcaption').css('background-color', hslToHex(hueDiff, fighsl.s, fighsl.l));
  hueChange('body', hueDiff, 'background-color');
  hueChange('body > header', hueDiff, Array('color', 'border-color'));
  hueChange('body > header hgroup', hueDiff, Array('background-color', 'background-image'));
  hueChange('body > header nav', hueDiff, Array('color', 'background-color', 'border-color'));
  hueChange('body > header nav ul li', hueDiff, 'border-color');
  hueChange('body > section', hueDiff, 'border-color');
  hueChange('body > section article > header', hueDiff, 'color');
  hueChange('body > footer', hueDiff, Array('background-color', 'background-image'));
  hueChange('body > footer aside.middle', hueDiff, 'border-color');
  hueChange('body > footer div.twitter', hueDiff, 'border-color');
  hueChange('button', hueDiff, Array('color', 'background-color', 'background-image', 'border-color'));
}
function hueChange(element, hueDiff, properties) {
  var elm = $(element);
  if (elm.length && hueDiff && properties) {
    var getProperty = '';
    var hsl = new Array(0, 0, 0);
    var newValue = '#000000';
    var gradColour = new Array();
    if (properties.constructor.toString().indexOf('Array') == -1) properties = Array(properties);
    for (var i in properties) {
      getProperty = properties[i];
      if (getProperty == 'border-color') {
        getProperty = 'border-left-color';
      }
      if (getProperty == 'background-image') {
        newValue = $(elm).css(getProperty);
        while ((gradColour = /rgb[^\)]+/.exec(newValue)) != null) {
          hsl = hexToHsl(gradColour[0] + ')');
          newValue = newValue.replace(gradColour[0] + ')', hslToHex(hueDiff, hsl.s, hsl.l));
        }
      } else {
        hsl = hexToHsl($(elm).css(getProperty));
        newValue = hslToHex(hueDiff, hsl.s, hsl.l);
      }
      $(elm).css(properties[i], newValue);
      debugOutput(element + ' { ' + properties[i] + ': ' + newValue + '; }');
    }
  }
}

function loadTwitter() {
  if ($('div.twitter').length) {
    $.ajax({
      url: 'http://api.twitter.com/1/statuses/user_timeline.json?screen_name=gwellin&count=40&trim_user=true&include_rts=true',
      dataType: 'jsonp',
      jsonpCallback: 'parseTwitter'
    });
  }
}
function parseTwitter(data) {
  var tweet = null;
  debugOutput('tweet: ' + data[0].text);
  $('div.twitter').html('');
  var tweetList = document.createElement('ul');
  $('div.twitter').append(tweetList);
  for (var i in data) {
    if (data[i]['text'].substr(0,1) != '@') {
      data[i]['text'] = data[i]['text'].replace(/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig, "<a href=\"$1\">$1</a>");
      data[i]['text'] = data[i]['text'].replace(/@([\d\w]+)/g, "<a href=\"http://twitter.com/$1\">@$1</a>");
      data[i]['text'] = data[i]['text'].replace(/#([\d\w]+)/g, "<a href=\"http://twitter.com/search?q=#$1\">#$1</a>");
      data[i]['text'] = data[i]['text'].replace(/\n/g, '<br>');
      tweet = document.createElement('li');
      tweet.innerHTML = data[i]['text'];
      tweetTime = document.createElement('a');
      tweetTime.href = 'https://twitter.com/gwellin/status/' + data[i]['id'];
      tweetTime.innerHTML = prettyDate(data[i]['created_at']);
      tweet.appendChild(document.createElement('br'));
      tweet.appendChild(tweetTime);
      $(tweetList).append(tweet);
      $.each($('a', tweet), function (key, value) { linkBehaviour(value); });
    }
  }
}
// Pretty Time (modified) source: http://ejohn.org/blog/javascript-pretty-date/
function prettyDate(time){
  var date = new Date(Date.parse(time)),
      diff = (((new Date()).getTime() - date.getTime()) / 1000),
      day_diff = Math.floor(diff / 86400);
  if (isNaN(day_diff) || day_diff < 0 || day_diff >= 31) return time.substr(0, time.indexOf(' ', 8));
  return day_diff == 0 && (
    diff < 60 && "just now" ||
    diff < 120 && "1 minute ago" ||
    diff < 3600 && Math.floor( diff / 60 ) + " minutes ago" ||
    diff < 7200 && "1 hour ago" ||
    diff < 86400 && Math.floor( diff / 3600 ) + " hours ago") ||
    day_diff == 1 && "Yesterday" ||
    day_diff < 7 && day_diff + " days ago" ||
    day_diff < 31 && Math.ceil( day_diff / 7 ) + " weeks ago";
}

function hexToHsl(hex) {
  var hsl = new Array(0, 0, 0);
  if (hex) {
    if (hex.substring(0, 1) == '#') {
      hex = hex.substring(1, 7);
      hsl = rgbToHsl(parseInt(hex.substring(0, 2),16), parseInt(hex.substring(2, 4),16), parseInt(hex.substring(4, 6),16));
    } else if (hex.substring(0, 4) == 'rgb(') {
      hsl = eval(hex.replace('rgb', 'rgbToHsl'));
    }
  } else {
    debugOutput('Error: No hex value.');
  }
  return { h:hsl[0], s:hsl[1], l:hsl[2] };
}
function hslToHex(h, s, l) {
  var rgb = hslToRgb(h, s, l);
  var hex = new Array();
  hex[0] = Math.round(rgb[0]).toString(16);
  hex[1] = Math.round(rgb[1]).toString(16);
  hex[2] = Math.round(rgb[2]).toString(16);
  if (hex[0].length == 1) hex[0] = '0' + hex[0];
  if (hex[1].length == 1) hex[1] = '0' + hex[1];
  if (hex[2].length == 1) hex[2] = '0' + hex[2];
  return '#' + hex[0] + hex[1] + hex[2];
}

function debugOutput(newLine) {
  var code = $('code.log');
  if (code.length) {
    $(code).append(newLine + "\n");
    $(code).scrollTop(50000);
  }
  if('console' in window) console.log(newLine);
}
function getCookie( name ) {
  var start = document.cookie.indexOf( name + "=" );
  var len = start + name.length + 1;
  if ( ( !start ) && ( name != document.cookie.substring( 0, name.length ) ) ) {
    return null;
  }
  if ( start == -1 ) return null;
  var end = document.cookie.indexOf( ';', len );
  if ( end == -1 ) end = document.cookie.length;
  return unescape( document.cookie.substring( len, end ) );
}
function setCookie( name, value, expires, path, domain, secure ) {
  var today = new Date();
  today.setTime( today.getTime() );
  if ( expires ) {
    expires = expires * 1000 * 60 * 60 * 24;
  }
  var expires_date = new Date( today.getTime() + (expires) );
  document.cookie = name+'='+escape( value ) +
    ( ( expires ) ? ';expires='+expires_date.toGMTString() : '' ) + //expires.toGMTString()
    ( ( path ) ? ';path=' + path : '' ) +
    ( ( domain ) ? ';domain=' + domain : '' ) +
    ( ( secure ) ? ';secure' : '' );
}
function deleteCookie( name, path, domain ) {
  if ( getCookie( name ) ) document.cookie = name + '=' +
    ( ( path ) ? ';path=' + path : '') +
    ( ( domain ) ? ';domain=' + domain : '' ) +
    ';expires=Thu, 01-Jan-1970 00:00:01 GMT';
}

/*
  Functions rgbToHsl() and hslToRgb()
  Source: http://mjijackson.com/2008/02/rgb-to-hsl-and-rgb-to-hsv-color-model-conversion-algorithms-in-javascript
*/

/**
 * Converts an RGB color value to HSL. Conversion formula
 * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
 * Assumes r, g, and b are contained in the set [0, 255] and
 * returns h, s, and l in the set [0, 1].
 *
 * @param   Number  r       The red color value
 * @param   Number  g       The green color value
 * @param   Number  b       The blue color value
 * @return  Array           The HSL representation
 */
function rgbToHsl(r, g, b) {
  r /= 255, g /= 255, b /= 255;
  var max = Math.max(r, g, b), min = Math.min(r, g, b);
  var h, s, l = (max + min) / 2;
  if (max == min) {
    h = s = 0; // achromatic
  } else {
    var d = max - min;
    s = l > 0.5 ? d / (2 - max - min) : d / (max + min);
    switch(max){
      case r: h = (g - b) / d + (g < b ? 6 : 0); break;
      case g: h = (b - r) / d + 2; break;
      case b: h = (r - g) / d + 4; break;
    }
    h /= 6;
  }
  return [h, s, l];
}

/**
 * Converts an HSL color value to RGB. Conversion formula
 * adapted from http://en.wikipedia.org/wiki/HSL_color_space.
 * Assumes h, s, and l are contained in the set [0, 1] and
 * returns r, g, and b in the set [0, 255].
 *
 * @param   Number  h       The hue
 * @param   Number  s       The saturation
 * @param   Number  l       The lightness
 * @return  Array           The RGB representation
 */
function hslToRgb(h, s, l) {
  var r, g, b;
  if (s == 0) {
    r = g = b = l; // achromatic
  } else {
    function hue2rgb(p, q, t) {
      if (t < 0) t += 1;
      if (t > 1) t -= 1;
      if (t < 1/6) return p + (q - p) * 6 * t;
      if (t < 1/2) return q;
      if (t < 2/3) return p + (q - p) * (2/3 - t) * 6;
      return p;
    }
    var q = l < 0.5 ? l * (1 + s) : l + s - l * s;
    var p = 2 * l - q;
    r = hue2rgb(p, q, h + 1/3);
    g = hue2rgb(p, q, h);
    b = hue2rgb(p, q, h - 1/3);
  }
  return [r * 255, g * 255, b * 255];
}

init();
