if( typeof(window.ReevooMark) === "undefined" ){
  var style_element = document.createElement("link");
  style_element.setAttribute("type", "text/css");
  style_element.setAttribute("rel", "stylesheet");
  style_element.setAttribute("href", "http://mark.reevoo.com/stylesheets/reevoomark.css");
  document.getElementsByTagName("head")[0].appendChild(style_element);

  (function(){
    var ReevooMark = {};
    ReevooMark.Util = {};

ReevooMark.Util.body = function(){return document.getElementsByTagName("body")[0];};
ReevooMark.Util.html = function(){return document.getElementsByTagName("html")[0];};

ReevooMark.Util.add_class_name = function(el, name){
  el.className += " "+name;
};

ReevooMark.Util.remove_class_name = function(el, name){
  el.className = el.className.replace(new RegExp("(^| )"+name+"( |$)"), "");
};


ReevooMark.Util.hide = function(element){
  element.style.display = "none";
};

ReevooMark.Util.show = function(element, block_or_inline){
  element.style.display = (block_or_inline || "block");
};

ReevooMark.Util.query_string = function(object) {
  var query_string = [];
  for(key in object) {
    var value = object[key];
    if(typeof(value) == "function") { continue; }

    if(typeof(value) != "object" || typeof(value.length) != "number") {
      value = [value];
    }

    for(var i = 0; i < value.length; i++) {
      query_string.push(escape(key) + "=" + escape(value[i]));
    }
  }
  return query_string.join("&");
};

ReevooMark.Util.load_script = function(url){
  var script = document.createElement("script");
  script.setAttribute("type", "text/javascript");
  script.setAttribute("src", url);
  this.body().appendChild(script);
};

ReevooMark.Util.extend = function(a,b,c){
  for(i in b){a[i] = b[i];}
  if(c){
    ReevooMark.Util.extend(a, c);
  }
  return a;
};

ReevooMark.Util.browser_dimensions = function() {
  return {
    width: (window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth)),
    height: (window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight))
  };
};

ReevooMark.minimum_window_dimensions_for_lightbox = {"width":798, "height":500};
ReevooMark.Util.browser_big_enough_for_lightbox = function() {
  var dimentions = ReevooMark.Util.browser_dimensions();
  return (dimentions.height >= ReevooMark.minimum_window_dimensions_for_lightbox.height && dimentions.width >= ReevooMark.minimum_window_dimensions_for_lightbox.width);
}

ReevooMark.Util.create_element = function(tag_name, attributes) {
  var el = document.createElement(tag_name);
  for(i in attributes) {
    if(i in Object.prototype) { continue; }
    if(i == "class") {
      el.className = attributes[i];
    }else{
      el.setAttribute(i, attributes[i]);
    }
  }
  return el;
};

ReevooMark.Util.tracking_tag_exists = function(tracking_url){
  var classElements = new Array();
  var els = document.getElementsByTagName('img');
  var elsLen = els.length;
  for (i = 0, j = 0; i < elsLen; i++) {
    if ( els[i].getAttribute('src') == tracking_url ) {
      return true;
    }
  }
  return false;
}

ReevooMark.Util.get_elements_by_class = function(searchClass,node,tag){
  var classElements = new Array();
  if ( node == null )
    node = document;
  if ( tag == null )
    tag = '*';
  var els = node.getElementsByTagName(tag);
  var elsLen = els.length;
  var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)");
  for (i = 0, j = 0; i < elsLen; i++) {
    if ( pattern.test(els[i].className) ) {
      classElements[j] = els[i];
      j++;
    }
  }
  return classElements;
}

ReevooMark.Util.isMobileBrowser = function() {
  return navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPod/i)
};

ReevooMark.Util.when_dom_ready = [];

ReevooMark.Util.ready = function(callback) {
  if(this.domIsReady) {
    callback();
  }else{
    this.when_dom_ready.push(callback);
  }
}

ReevooMark.Util.dom_now_ready = function(){
  if(this.domIsReady){return;}
  this.domIsReady = true;
  for(var i = 0; i < this.when_dom_ready.length; i++){
    this.when_dom_ready[i]();
  }
  this.when_dom_ready = [];
}



ReevooMark.Util.listen_for_dom_ready = function(){
  if ( this.hooked_up_dom_ready ){ return; }
  this.hooked_up_dom_ready = true;

  if ( document.addEventListener ) {
    document.addEventListener( "DOMContentLoaded", function(){
      document.removeEventListener( "DOMContentLoaded", arguments.callee, false );
      ReevooMark.Util.dom_now_ready();
    }, false );
  } else if ( document.attachEvent ) {
    document.attachEvent("onreadystatechange", function(){
      if ( document.readyState === "complete" ) {
        document.detachEvent( "onreadystatechange", arguments.callee );
        ReevooMark.Util.dom_now_ready();
      }
    });

    if ( document.documentElement.doScroll && window == window.top ) (function(){
      if ( this.domIsReady ) return;

      try {
        document.documentElement.doScroll("left");
      } catch( error ) {
        setTimeout( arguments.callee, 0 );
        return;
      }

      ReevooMark.Util.dom_now_ready();
    })();
  }

  var old_onload = window.onload;
  window.onload = function(e){
    ReevooMark.Util.dom_now_ready();
    if(typeof(old_onload) == "function"){old_onload(e);}
  }
}

/* from: http://plugins.jquery.com/files/jquery.md5.js.txt */
ReevooMark.Util.md5 = function(data) {
  var rotateLeft = function(lValue, iShiftBits) {return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));}

  var addUnsigned = function(lX, lY) {
    var lX4, lY4, lX8, lY8, lResult;
    lX8 = (lX & 0x80000000);
    lY8 = (lY & 0x80000000);
    lX4 = (lX & 0x40000000);
    lY4 = (lY & 0x40000000);
    lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
    if (lX4 & lY4) return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
    if (lX4 | lY4) {
      if (lResult & 0x40000000) return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
      else return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
    } else {
      return (lResult ^ lX8 ^ lY8);
    }
  }

  var F = function(x, y, z) {return (x & y) | ((~ x) & z);}
  var G = function(x, y, z) {return (x & z) | (y & (~ z));}
  var H = function(x, y, z) {return (x ^ y ^ z);}
  var I = function(x, y, z) {return (y ^ (x | (~ z)));}

  var FF = function(a, b, c, d, x, s, ac) {
    a = addUnsigned(a, addUnsigned(addUnsigned(F(b, c, d), x), ac));
    return addUnsigned(rotateLeft(a, s), b);
  };

  var GG = function(a, b, c, d, x, s, ac) {
    a = addUnsigned(a, addUnsigned(addUnsigned(G(b, c, d), x), ac));
    return addUnsigned(rotateLeft(a, s), b);
  };

  var HH = function(a, b, c, d, x, s, ac) {
    a = addUnsigned(a, addUnsigned(addUnsigned(H(b, c, d), x), ac));
    return addUnsigned(rotateLeft(a, s), b);
  };

  var II = function(a, b, c, d, x, s, ac) {
    a = addUnsigned(a, addUnsigned(addUnsigned(I(b, c, d), x), ac));
    return addUnsigned(rotateLeft(a, s), b);
  };

  var convertToWordArray = function(string) {
    var lWordCount;
    var lMessageLength = string.length;
    var lNumberOfWordsTempOne = lMessageLength + 8;
    var lNumberOfWordsTempTwo = (lNumberOfWordsTempOne - (lNumberOfWordsTempOne % 64)) / 64;
    var lNumberOfWords = (lNumberOfWordsTempTwo + 1) * 16;
    var lWordArray = Array(lNumberOfWords - 1);
    var lBytePosition = 0;
    var lByteCount = 0;
    while (lByteCount < lMessageLength) {
      lWordCount = (lByteCount - (lByteCount % 4)) / 4;
      lBytePosition = (lByteCount % 4) * 8;
      lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
      lByteCount++;
    }
    lWordCount = (lByteCount - (lByteCount % 4)) / 4;
    lBytePosition = (lByteCount % 4) * 8;
    lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
    lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
    lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
    return lWordArray;
  };

  var wordToHex = function(lValue) {
    var WordToHexValue = "", WordToHexValueTemp = "", lByte, lCount;
    for (lCount = 0; lCount <= 3; lCount++) {
      lByte = (lValue >>> (lCount * 8)) & 255;
      WordToHexValueTemp = "0" + lByte.toString(16);
      WordToHexValue = WordToHexValue + WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2);
    }
    return WordToHexValue;
  };

  var uTF8Encode = function(string) {
    string = string.replace(/\x0d\x0a/g, "\x0a");
    var output = "";
    for (var n = 0; n < string.length; n++) {
      var c = string.charCodeAt(n);
      if (c < 128) {
        output += String.fromCharCode(c);
      } else if ((c > 127) && (c < 2048)) {
        output += String.fromCharCode((c >> 6) | 192);
        output += String.fromCharCode((c & 63) | 128);
      } else {
        output += String.fromCharCode((c >> 12) | 224);
        output += String.fromCharCode(((c >> 6) & 63) | 128);
        output += String.fromCharCode((c & 63) | 128);
      }
    }
    return output;
  };

  var md5 = function(string) {
    var x = Array();
    var k, AA, BB, CC, DD, a, b, c, d;
    var S11=7, S12=12, S13=17, S14=22;
    var S21=5, S22=9 , S23=14, S24=20;
    var S31=4, S32=11, S33=16, S34=23;
    var S41=6, S42=10, S43=15, S44=21;
    string = uTF8Encode(string);
    x = convertToWordArray(string);
    a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
    for (k = 0; k < x.length; k += 16) {
      AA = a; BB = b; CC = c; DD = d;
      a = FF(a, b, c, d, x[k+0],  S11, 0xD76AA478);
      d = FF(d, a, b, c, x[k+1],  S12, 0xE8C7B756);
      c = FF(c, d, a, b, x[k+2],  S13, 0x242070DB);
      b = FF(b, c, d, a, x[k+3],  S14, 0xC1BDCEEE);
      a = FF(a, b, c, d, x[k+4],  S11, 0xF57C0FAF);
      d = FF(d, a, b, c, x[k+5],  S12, 0x4787C62A);
      c = FF(c, d, a, b, x[k+6],  S13, 0xA8304613);
      b = FF(b, c, d, a, x[k+7],  S14, 0xFD469501);
      a = FF(a, b, c, d, x[k+8],  S11, 0x698098D8);
      d = FF(d, a, b, c, x[k+9],  S12, 0x8B44F7AF);
      c = FF(c, d, a, b, x[k+10], S13, 0xFFFF5BB1);
      b = FF(b, c, d, a, x[k+11], S14, 0x895CD7BE);
      a = FF(a, b, c, d, x[k+12], S11, 0x6B901122);
      d = FF(d, a, b, c, x[k+13], S12, 0xFD987193);
      c = FF(c, d, a, b, x[k+14], S13, 0xA679438E);
      b = FF(b, c, d, a, x[k+15], S14, 0x49B40821);
      a = GG(a, b, c, d, x[k+1],  S21, 0xF61E2562);
      d = GG(d, a, b, c, x[k+6],  S22, 0xC040B340);
      c = GG(c, d, a, b, x[k+11], S23, 0x265E5A51);
      b = GG(b, c, d, a, x[k+0],  S24, 0xE9B6C7AA);
      a = GG(a, b, c, d, x[k+5],  S21, 0xD62F105D);
      d = GG(d, a, b, c, x[k+10], S22, 0x2441453);
      c = GG(c, d, a, b, x[k+15], S23, 0xD8A1E681);
      b = GG(b, c, d, a, x[k+4],  S24, 0xE7D3FBC8);
      a = GG(a, b, c, d, x[k+9],  S21, 0x21E1CDE6);
      d = GG(d, a, b, c, x[k+14], S22, 0xC33707D6);
      c = GG(c, d, a, b, x[k+3],  S23, 0xF4D50D87);
      b = GG(b, c, d, a, x[k+8],  S24, 0x455A14ED);
      a = GG(a, b, c, d, x[k+13], S21, 0xA9E3E905);
      d = GG(d, a, b, c, x[k+2],  S22, 0xFCEFA3F8);
      c = GG(c, d, a, b, x[k+7],  S23, 0x676F02D9);
      b = GG(b, c, d, a, x[k+12], S24, 0x8D2A4C8A);
      a = HH(a, b, c, d, x[k+5],  S31, 0xFFFA3942);
      d = HH(d, a, b, c, x[k+8],  S32, 0x8771F681);
      c = HH(c, d, a, b, x[k+11], S33, 0x6D9D6122);
      b = HH(b, c, d, a, x[k+14], S34, 0xFDE5380C);
      a = HH(a, b, c, d, x[k+1],  S31, 0xA4BEEA44);
      d = HH(d, a, b, c, x[k+4],  S32, 0x4BDECFA9);
      c = HH(c, d, a, b, x[k+7],  S33, 0xF6BB4B60);
      b = HH(b, c, d, a, x[k+10], S34, 0xBEBFBC70);
      a = HH(a, b, c, d, x[k+13], S31, 0x289B7EC6);
      d = HH(d, a, b, c, x[k+0],  S32, 0xEAA127FA);
      c = HH(c, d, a, b, x[k+3],  S33, 0xD4EF3085);
      b = HH(b, c, d, a, x[k+6],  S34, 0x4881D05);
      a = HH(a, b, c, d, x[k+9],  S31, 0xD9D4D039);
      d = HH(d, a, b, c, x[k+12], S32, 0xE6DB99E5);
      c = HH(c, d, a, b, x[k+15], S33, 0x1FA27CF8);
      b = HH(b, c, d, a, x[k+2],  S34, 0xC4AC5665);
      a = II(a, b, c, d, x[k+0],  S41, 0xF4292244);
      d = II(d, a, b, c, x[k+7],  S42, 0x432AFF97);
      c = II(c, d, a, b, x[k+14], S43, 0xAB9423A7);
      b = II(b, c, d, a, x[k+5],  S44, 0xFC93A039);
      a = II(a, b, c, d, x[k+12], S41, 0x655B59C3);
      d = II(d, a, b, c, x[k+3],  S42, 0x8F0CCC92);
      c = II(c, d, a, b, x[k+10], S43, 0xFFEFF47D);
      b = II(b, c, d, a, x[k+1],  S44, 0x85845DD1);
      a = II(a, b, c, d, x[k+8],  S41, 0x6FA87E4F);
      d = II(d, a, b, c, x[k+15], S42, 0xFE2CE6E0);
      c = II(c, d, a, b, x[k+6],  S43, 0xA3014314);
      b = II(b, c, d, a, x[k+13], S44, 0x4E0811A1);
      a = II(a, b, c, d, x[k+4],  S41, 0xF7537E82);
      d = II(d, a, b, c, x[k+11], S42, 0xBD3AF235);
      c = II(c, d, a, b, x[k+2],  S43, 0x2AD7D2BB);
      b = II(b, c, d, a, x[k+9],  S44, 0xEB86D391);
      a = addUnsigned(a, AA);
      b = addUnsigned(b, BB);
      c = addUnsigned(c, CC);
      d = addUnsigned(d, DD);
    }
    var tempValue = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
    return tempValue.toLowerCase();
  }
  return md5(data);
}

ReevooMark.Util.listen_for_dom_ready();

    ReevooMark.RemoteData = {
  callback_handlers:{},
  callbacks:{},
  cached_responses:{},

  load: function(url, callback){
    var callback_id = "_" + ReevooMark.Util.md5(url);
    if(this.cached_responses[callback_id]){
      callback(this.cached_responses[callback_id]);
    }else if(this.callback_handlers[callback_id]){
      this.callback_handlers[callback_id].push(callback);
    }else{
      this.callback_handlers[callback_id] = [callback];
      this.callbacks[callback_id] = this.define_handler(callback_id);
      ReevooMark.Util.load_script(this.add_callback_to_url(callback_id, url));
    }
  },

  define_handler: function(callback_id){
    var rd = this;
    return function(data){
      rd.cached_responses[callback_id] = data;
      var callback, relevent_callbacks = rd.callback_handlers[callback_id];

      while(callback = relevent_callbacks.shift()) {
        callback(data);
      }
      delete rd.callbacks[callback_id];
      delete rd.callback_handlers[callback_id];
    }
  },

  add_callback_to_url: function(callback_id, url){
    return url + (url.match(/\?/) ? "&" : "?") + "callback=ReevooMark.RemoteData.callbacks." + callback_id;
  }
};


    ReevooMark.Callbacks = {click_observers: [], load_observers: []};

ReevooMark.Callbacks.observe_click = function(callback){
  this.click_observers.push(callback);
}

ReevooMark.Callbacks.observe_load = function(callback){
  this.load_observers.push(callback);
}

ReevooMark.Callbacks.on_click = function(reevoomark){
  for(var i = 0; i < this.click_observers.length; i++) {
    try{
      this.click_observers[i](reevoomark);
    }catch(e){ };
  }
}

ReevooMark.Callbacks.on_load = function(reevoomark){
  for(var i = 0; i < this.load_observers.length; i++) {
    try{
      this.load_observers[i](reevoomark);
    }catch(e){ };
  }
}

    ReevooMark.Cookies = {target_domain: ""};

ReevooMark.Cookies.set = function(name,value) {
  var cookie = this._generate_cookie(name, value);
  if( this.target_domain === ""){
    var parts = window.location.host.replace(/:.*$/, "").split(".");
    while(parts.length > 0){
      this.target_domain = "." + parts.pop() + this.target_domain;
      try{ document.cookie = cookie + "; domain=" + this.target_domain; }catch(e){}
      if(value == ReevooMark.Cookies.get(name)){ return; }
    }
    this.target_domain = null;
    document.cookie = this._generate_cookie(name, value);
  }else if(this.target_domain === null){
    document.cookie = this._generate_cookie(name, value);
  }else{
    document.cookie = cookie + "; domain=" + this.target_domain;
  }
}

ReevooMark.Cookies._generate_cookie = function(name, value){
  var date = new Date();
  date.setTime(date.getTime()+(30*24*60*60*1000));
  var expires = "; expires="+date.toGMTString();
  return escape("reevoomark_" + name)+"="+escape(value)+expires+"; path=/";
}

ReevooMark.Cookies.get = function(name) {
  var nameEQ = escape("reevoomark_" + name) + "=";
  var ca = document.cookie.split(';');
  for(var i=0;i < ca.length;i++) {
    var c = ca[i];
    while (c.charAt(0)==' ') c = c.substring(1,c.length);
    if (c.indexOf(nameEQ) == 0) return unescape(c.substring(nameEQ.length,c.length));
  }
  return null;
}

    /* All methods defned here are considered public (retailers know about them) and should not be removed or have their functionality changed */

ReevooMark.init_badge = function(target_id, product_sku, options) {
  if(options == undefined){ options = {}; }

  if(options.immediate) {
    this.init_badge_from_identifiers(target_id, {sku: product_sku}, options);
    if (window.location.hash.match(/^#reevoo-open/)) {
      options.badge_style = "social_link";
      ReevooMark.Callbacks.observe_load(function() {ReevooMark.show_popup(product_sku, options)});
    }
  }
  else {
    ReevooMark.Util.ready(function() {
      ReevooMark.init_badge(target_id, product_sku, ReevooMark.Util.extend({}, options, {immediate: true}));
    });
  }
}

ReevooMark.init_badges = function(options) {
  if(options == undefined){ options = {}; }

  if(options.immediate) {
    var elements = ReevooMark.Util.get_elements_by_class("reevoomark", ReevooMark.Util.body(), "a");
    var matcher = /\/partner\/TSB\/(.*?)(#.*)?$/i;
    for(var i = 0; i < elements.length; i++){
      var target_id = "reevoomark_badge_"+i;
      var el = elements[i];
      var undecorated = /\bundecorated\b/.test(el.className);
      var tracking_tag = 'product'
      if (/\btrack-\w+\b/.test(el.className)) {
        tracking_tag = el.className.match(/\btrack-(\w+)\b/)[1];
      }
      if(parts = matcher.exec(el.href)) {
        var product_sku = unescape(parts[1]);
        if(undecorated) {
          ReevooMark.init_badge(el, product_sku, ReevooMark.Util.extend({}, options, {url_fragment: parts[2], view: "undecorated", tracking_tag:tracking_tag}) );
        }
        else {
          var place_holder = ReevooMark.Util.create_element("div", {id: target_id});
          el.parentNode.insertBefore(place_holder, el);
          el.parentNode.removeChild(el);
          ReevooMark.init_badge(target_id, product_sku, ReevooMark.Util.extend({}, options, {url_fragment: parts[2], tracking_tag:tracking_tag}) );
        }
      }
    }
  }
  else {
    ReevooMark.Util.ready(function() {
      ReevooMark.init_badges(ReevooMark.Util.extend({}, options, {immediate: true}));
    });
  }
}

ReevooMark.show_popup = function(product_identifiers, options) {
  if(typeof(product_identifiers) !== "object") {
    product_identifiers = {sku:product_identifiers};
  }

  if(!options || typeof options.badge_style === "undefined") {
    options = options || {};
    options.badge_style = "custom_link";
  }

  var controller = new ReevooMark.BadgeController(null, product_identifiers, options);
  controller.display_popup();
}

ReevooMark.init_price_links = function(options) {
  if(options == undefined){ options = {}; }

  if(options.immediate) {
    var elements = ReevooMark.Util.get_elements_by_class("reevoomark_prices", ReevooMark.Util.body(), "a");
    var matcher = /\/partner\/TSB\/(.*)\/offers$/i;
    for(var i = 0; i < elements.length; i++){
      var el = elements[i];
      if(parts = matcher.exec(el.href)) {
        var product_sku = parts[1];
        var controller = new ReevooMark.PriceLinkController(el, product_sku, options);
      }
    }
  }
  else {
    ReevooMark.Util.ready(function() {
      ReevooMark.init_price_links(ReevooMark.Util.extend({}, options, {immediate: true}));
    });
  }
}

ReevooMark.observe = function(action, callback){
  ReevooMark.Callbacks["observe_"+action](callback)
}

ReevooMark.track_purchase = function(purchased_skus, basket_value) {
   ReevooMark.Util.ready(function() {
    var viewed_skus = ReevooMark.Tracking.viewed_product_skus();
    var viewed_any = false;

    for(var i = 0; i < purchased_skus.length; i++) {
      var purchased_sku = purchased_skus[i], viewed = false;
      for(var j = 0; j < viewed_skus.length; j++) {
        if(purchased_sku === viewed_skus[j]) {
          viewed_any = true;
          viewed = true;
          break;
        }
      }
      var action = viewed ? "purchase_after_reviews" : "purchase_without_reviews";
      ReevooMark.Tracking.ga_track_event("ReevooMark", action, "sku:" + purchased_sku);
    }

    var label = viewed_any ? "basket_value_with_reviews" : "basket_value_without_reviews";
    ReevooMark.Tracking.ga_track_event("ReevooMark", 'checkout', label, basket_value);

    ReevooMark.Tracking.track_with_cookies("http://mark.reevoo.com/reevoomark/track/purchase?locale=en-GB&amp;retailer_id=338" + "&" + ReevooMark.Util.query_string({"session": ReevooMark.Tracking.get_session_id(), "skus[]": purchased_skus}));
  });
}

ReevooMark.track_exit = function() {
  ReevooMark.Util.ready(function() {
    ReevooMark.Tracking.ga_track_page_view("/exit_page");
  });
}


    ReevooMark.Tracking = {};

ReevooMark.Tracking.get_session_id = function() {
  marker = ReevooMark.Cookies.get('marker');
  if(marker == null) {
    d = new Date();
    r = Math.random();
    marker = ReevooMark.Util.md5(d.toString()+d.getMilliseconds()+r.toString());
    ReevooMark.Cookies.set('marker', marker)
    return marker
  } else {
    return marker;
  }
}

ReevooMark.Tracking.update_viewed_products = function(value) {
  ReevooMark.Cookies.set('viewed_products', value);
}

ReevooMark.Tracking.track_with_cookies = function(url) {
  ReevooMark.Util.load_script(url + "&viewed_products=" + escape(ReevooMark.Cookies.get('viewed_products')));
}

ReevooMark.observe("click", function(rvm){
  ReevooMark.Tracking.track_with_cookies(rvm.product.click_through_tracking_url + '&session=' + ReevooMark.Tracking.get_session_id() + '&tag='+rvm.tracking_tag);
  ReevooMark.Tracking.ga_track_event("ReevooMark", "click_through", "sku:"+rvm.product.sku+" badge:"+rvm.retailer.badge_style);
});

ReevooMark.observe("load", function(rvm) {
  if(!rvm.skip_impression_tracking){
    tracking_url = rvm.product.tracking_url + '&session=' + ReevooMark.Tracking.get_session_id() + '&tag='+rvm.tracking_tag;
    if(!ReevooMark.Util.tracking_tag_exists(tracking_url)){
      ReevooMark.View.insert_tracking_image(tracking_url);
      ReevooMark.Tracking.ga_track_event("ReevooMark", rvm.product.hit_type, "sku:"+rvm.product.sku+" badge:"+rvm.retailer.badge_style);
    }
  }
});

ReevooMark.Tracking.ga_track_page_view = function(opt_page_url) {
  return this.ga_track("page_view", [opt_page_url]);
}

ReevooMark.Tracking.ga_track_event = function(category, action, opt_label, opt_value) {
  var value = typeof opt_value !== "undefined" ? parseInt(opt_value, 10) : undefined;
  return this.ga_track("event", [category, action, opt_label, value]);
}

ReevooMark.Tracking.ga_track = function(type, args) {
  var ga_account = "";
  if(!ga_account) { return; }

  if(this.ga_tracker || typeof(_gat) == "object") {
    if(!this.ga_tracker) {
      this.ga_tracker = _gat._getTracker(ga_account);
      this.ga_tracker._trackPageview();
    }

    var func = null;
    if(type == "event") {
      func = this.ga_tracker._trackEvent;
    } else {
      func = this.ga_tracker._trackPageview;
    }

    if(typeof(func) == "function") {
      return func.apply(this.ga_tracker, args);
    }
  }

  this.ga_queue = this.ga_queue || []
  this.ga_queue.push([type, args]);

  this.ga_load();
}

ReevooMark.Tracking.ga_load = function() {
  if(this.ga_load_interval) {
    return;
  }

  var url = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.") + "google-analytics.com/ga.js";
  ReevooMark.Util.load_script(url);

  this.ga_load_interval = setInterval(function() {
    if(typeof(_gat) != "undefined") {
      clearInterval(ReevooMark.Tracking.ga_load_interval);
      ReevooMark.Tracking.ga_loaded();
    }
  }, 10);
}

ReevooMark.Tracking.ga_loaded = function() {
  while(this.ga_queue.length > 0) {
    var params = this.ga_queue.shift();
    ReevooMark.Tracking.ga_track.apply(this, params);
  }
}

ReevooMark.Tracking.viewed_product_skus = function() {
  var viewed_products_cookie = ReevooMark.Cookies.get("viewed_products");
  if(!viewed_products_cookie) {
    return [];
  }

  var viewed_products = viewed_products_cookie.split("&");
  var skus = [];
  for(var i = 0; i < viewed_products.length; i++) {
    var parts = viewed_products[i].split("=");
    if(parts.length >= 4) {
      skus.push(unescape(parts[3]));
    }
  }
  return skus;
}

    ReevooMark.Retailer = function(options) {
  this.trkref = "TSB";
  this.badge_style = options.badge_style || "v3_rvm_145x77";
  this.force_popup = options.force_popup || false;
};


ReevooMark.Product = {};
ReevooMark.Product.load = function(product_identifiers, retailer, callback) {
  var parameters = ReevooMark.Util.extend({}, {retailer: retailer.trkref, badge_style: retailer.badge_style}, product_identifiers);
  ReevooMark.RemoteData.load("http://mark.reevoo.com/reevoomark/product_summaries.js?locale=en-GB&"+ReevooMark.Util.query_string(parameters), callback);
};

    ReevooMark.View = {};

ReevooMark.View.render_undecorated = function(controller, values){
  if(controller.should_show_badge()){
    controller.target.onclick = function() {
      controller.display_popup();
      return false;
    };
  }else{
    var parent = controller.target;
    ReevooMark.Util.hide(controller.target);
    while(parent = parent.parentNode){
      if(parent.className.match(/requires-reevoomark/)){
        ReevooMark.Util.hide(parent);
        break;
      }
    }
  }
}

ReevooMark.View.render_badge = function(controller, values) {
  if(!controller.should_show_badge()){ return; }

  var link = ReevooMark.View.create_image_link(
    controller,
    "http://mark.reevoo.com/reevoomark/badges/en-GB/" + values.retailer.badge_style + "/" + values.product.average_score + ".png",
    values.product.badge_title,
    controller.popup_url()
  );

  if(controller.show_review_count.enabled) {
    var review_count = ReevooMark.Util.create_element("span");
    review_count.style.top = controller.show_review_count.y + "px";
    review_count.style.left = controller.show_review_count.x + "px";
    review_count.style.fontWeight = (controller.show_review_count.weight || "normal");
    review_count.style.textAlign = (controller.show_review_count.alignment || "left");
    review_count.style.color = (controller.show_review_count.color || "#0000ff");
    review_count.style.textDecoration = (controller.show_review_count.decoration || "none");
    review_count.style.fontSize = (controller.show_review_count.size || "12") + "px";
    review_count.style.fontFamily = "Helvetica, Arial, sans-serif";
    review_count.style.position = "absolute";
    review_count.style.width = "100%";
    var num_reviews = controller.review_count();
    review_count.appendChild(document.createTextNode(controller.show_review_count.text));

    link.style.textDecoration = (controller.show_review_count.decoration || "underline");
    link.appendChild(review_count);
  }

  controller.target.appendChild(link);
};

ReevooMark.View.render_ask_an_owner_badge = function(controller, values){
  if(!controller.should_show_badge()){ return; }

  var container = ReevooMark.Util.create_element("div");
  ReevooMark.Util.add_class_name(container, "reevoomark_badge_container");

  var header = ReevooMark.Util.create_element("h3");
  header.appendChild(document.createTextNode("impartial reviews"));

  container.appendChild(header);
  var ask_a_question_button_placeholder = ReevooMark.Util.create_element("span");
  var read_reviews_button_placeholder = ReevooMark.Util.create_element("span");
  container.appendChild(ask_a_question_button_placeholder);
  container.appendChild(read_reviews_button_placeholder);
  controller.target.appendChild(container);

  var render_ask_a_question_button = function(controller, values){
    var ask_an_owner_reevoo_mark_link = ReevooMark.View.create_image_link(
      controller,
      "http://mark.reevoo.com/images/askanowner-button.png",
      "Ask an owner about this product",
      controller.popup_url("#open-ask-an-owner-tab")
    );
    ReevooMark.Util.add_class_name(ask_an_owner_reevoo_mark_link, "first");
    controller.target.appendChild(ask_an_owner_reevoo_mark_link);
  }

  var render_read_reviews_button = function(controller, values){
    var normal_reevoo_mark_link = ReevooMark.View.create_image_link(
      controller,
      "http://mark.reevoo.com/reevoomark/badges/en-GB/sony-askowner-reviews/" + values.product.average_score + ".png",
      values.product.badge_title,
      controller.popup_url()
    );
    controller.target.appendChild(normal_reevoo_mark_link);
  }

  ReevooMark.init_badge_from_identifiers(ask_a_question_button_placeholder, controller.product_identifiers, ReevooMark.Util.extend({}, controller.options, {view: render_ask_a_question_button, tracking_tag: controller.tracking_tag+"-askowner", skip_impression_tracking: true }));
  ReevooMark.init_badge_from_identifiers(read_reviews_button_placeholder, controller.product_identifiers, ReevooMark.Util.extend({}, controller.options, {view: render_read_reviews_button}));
}

ReevooMark.View.create_image_link = function(controller, image_url, title, popup_url){
  var img = ReevooMark.Util.create_element("img", {
    src: image_url,
    alt: title
  });
  img.style.border = "0";
  img.style.verticalAlign = "bottom";
  img.style.float = "none";
  img.style.margin = "0";
  img.style.padding = "0";

  var link = ReevooMark.Util.create_element("a", {
    "class": "reevoomark_badge",
    href: popup_url,
    title: title
  });
  link.style.position = "relative";
  link.style.display = "inline-block";
  link.style.zoom = "1";
  link.appendChild(img);

  link.onclick = function() {
    controller.display_popup(link);
    return false;
  };

  return link;
}

ReevooMark.View.render_popup = function(controller) {
  if(this.popup_iframe) {
    return this.popup_iframe;
  }

  var close_button = ReevooMark.Util.create_element('a', {"class": "reevoomark_close_button", title: "Close this review window"});
  close_button.appendChild(document.createTextNode("Close this review window"));
  close_button.onclick = function(){ ReevooMark.View.hide_popup_frame(); return false; };

  var container = ReevooMark.Util.create_element('div', {"class": "reevoomark_container"});

  this.popup_iframe = ReevooMark.Util.create_element('iframe', {src: 'about:blank', frameborder: '0'})
  container.appendChild(this.popup_iframe);

  this.popup_frame = ReevooMark.Util.create_element("div", {id:"reevoomark_popup_frame", "class":"en-GB"});
  this.popup_frame.appendChild(close_button);
  this.popup_frame.appendChild(container);
  ReevooMark.Util.hide(this.popup_frame);

  this.popup_backdrop = ReevooMark.Util.create_element('div', {id:"reevoomark_popup_backdrop"});
  ReevooMark.Util.hide(this.popup_backdrop);
  this.popup_backdrop.onclick = function(){ ReevooMark.View.hide_popup_frame(); return false; };

  var body = ReevooMark.Util.body();

  body.appendChild(this.popup_backdrop);
  body.appendChild(this.popup_frame);

  return this.popup_iframe;
};

ReevooMark.View.show_popup_frame = function() {
  var IE = navigator.userAgent.match(/MSIE 6/i) ? true : false;
  if(IE){
    ReevooMark.Util.add_class_name(ReevooMark.Util.html(), "reevoomark_ie");
    this.popup_backdrop.style.opacity = 0.8;
    window.scrollTo(0, 0);
  }
  ReevooMark.Util.show(this.popup_frame);
  ReevooMark.Util.show(this.popup_backdrop);
};

ReevooMark.View.hide_popup_frame = function() {
  ReevooMark.Util.remove_class_name(ReevooMark.Util.html(), "reevoomark_ie");
  ReevooMark.Util.hide(this.popup_frame);
  ReevooMark.Util.hide(this.popup_backdrop);
  this.popup_iframe.setAttribute("src", "about:blank");
};

ReevooMark.View.insert_tracking_image = function(url) {
    var img = ReevooMark.Util.create_element("img", {src: url});
    img.style.position = "absolute";
    img.style.left = "-100px";
    ReevooMark.Util.body().appendChild(img);
};

    ReevooMark.BadgeController = function(target_id, product_identifiers, options) {
  if(options == undefined){ options = {}; }

  this.target = typeof target_id === "string" ? document.getElementById(target_id) : target_id;
  this.retailer = new ReevooMark.Retailer(options);
  this.product_identifiers = product_identifiers;
  this.url_fragment = options.url_fragment;
  this.view = options.view || "badge";
  this.tracking_tag = options.tracking_tag;
  this.skip_impression_tracking = options.skip_impression_tracking;
  this.options = options;
};

ReevooMark.BadgeController.prototype.display_badge = function() {
  if(!this.product) {
    var me = this;
    ReevooMark.Product.load(this.product_identifiers, this.retailer, function(loaded_product) {
      me.show_review_count = loaded_product.show_review_count;
      me.product = loaded_product;
      me.display_badge();
    });
    return;
  }

  ReevooMark.Callbacks.on_load(this);

  if(this.product.can_ask_an_owner && this.view === "badge"){
    this.view = "ask_an_owner_badge";
  }

  var renderer;
  if(typeof(this.view) === "function"){
    renderer = this.view;
  }else{
    renderer = ReevooMark.View["render_" + this.view];
  }
  renderer(this, {product:this.product, retailer:this.retailer});
};

ReevooMark.BadgeController.prototype.popup_url = function(url_fragment){
  var url = "http://mark.reevoo.com/reevoomark/en-GB/product?";
  url += ReevooMark.Util.query_string(ReevooMark.Util.extend({}, this.product_identifiers, {retailer: this.retailer.trkref, badge_style: this.retailer.badge_style}));
  url_fragment = url_fragment || this.url_fragment;
  if(url_fragment != undefined){
    url += url_fragment;
  }
  return url;
}

ReevooMark.BadgeController.prototype.display_popup = function(link) {
  if(!this.product) {
    var me = this;
    ReevooMark.Product.load(this.product_identifiers, this.retailer, function(loaded_product) {
      me.product = loaded_product;
      me.display_popup(link);
    });
    return;
  }

  ReevooMark.Callbacks.on_click(this);

  var url = link && link.href || this.popup_url();

  if(ReevooMark.Util.isMobileBrowser()){
    window.location = url;
  }else if(this.retailer.force_popup || !ReevooMark.Util.browser_big_enough_for_lightbox()){
    window.open(url, "_reevoomark", "scrollbars=1,width="+ReevooMark.minimum_window_dimensions_for_lightbox.width+",height="+ReevooMark.minimum_window_dimensions_for_lightbox.height);
  } else {
    var popup_iframe = ReevooMark.View.render_popup(this);
    popup_iframe.setAttribute("src", url);
    ReevooMark.View.show_popup_frame();
  }
};

// API Method (gets passed into callbacks)
ReevooMark.BadgeController.prototype.review_count = function(){
  return this.product.review_count;
}

// API Method (gets passed into callbacks)
ReevooMark.BadgeController.prototype.scores_count = function(){
  return this.product.scores_count;
}

// API Method (gets passed into callbacks)
ReevooMark.BadgeController.prototype.should_show_badge = function(){
  return this.scores_count() > 2 || this.product.review_with_content_count > 0 || (this.product.show_badge_if_only_foreign_reviews && this.product.foreign_review_count > 0);
}

// API Method (gets passed into callbacks) DEPRECATED
ReevooMark.BadgeController.prototype.has_reviews = ReevooMark.BadgeController.prototype.should_show_badge;

// API Method (gets passed into callbacks)
ReevooMark.BadgeController.prototype.sku = function(){
  return this.product.sku;
}


ReevooMark.PriceLinkController = function(target_element, product_sku, retailer_options) {
  var me = this;
  this.retailer = new ReevooMark.Retailer(retailer_options || {});
  this.product_sku = product_sku;
  this.retailer_options = retailer_options;
  target_element.onclick = function() {
    me.display_popup();
    return false;
  }
}

ReevooMark.PriceLinkController.prototype.popup_url = function(){
  return "http://mark.reevoo.com/reevoomark/en-GB/prices?" + ReevooMark.Util.query_string({sku: this.product_sku, retailer: this.retailer.trkref});
}

ReevooMark.PriceLinkController.prototype.display_popup = function() {
  var url = this.popup_url();

  if(ReevooMark.Util.isMobileBrowser()){
    window.location = url;
  }else if(this.retailer.force_popup || !ReevooMark.Util.browser_big_enough_for_lightbox()){
    window.open(url, "_reevoomark", "scrollbars=1,width="+ReevooMark.minimum_window_dimensions_for_lightbox.width+",height="+ReevooMark.minimum_window_dimensions_for_lightbox.height);
  } else {
    var popup_iframe = ReevooMark.View.render_popup(this);
    popup_iframe.setAttribute("src", url);
    ReevooMark.View.show_popup_frame();
  }
}


    ReevooMark.init_badge_from_identifiers = function(target_id, product_identifiers, options) {
      var controller = new ReevooMark.BadgeController(target_id, product_identifiers, options);
      controller.display_badge();
    };

    window.ReevooMark = ReevooMark;
  })();
}
