/* TVAB GLOBAL */

/*! Misc constants
 */
var STATIC = {
  DEBUG: 1,
  EDITAREA: 0
};

/* Is current browser MSIE? Set on document ready */
var MSIE  = false;
/* Is current browser MSIE6? Set on document ready */
var MSIE6 = false;

/*! Misc strings
 */
var Strings =
{
  en: {
    months: [
      'January','Febuary','March','April','May','June','July',
      'August','September','October','November','December'
    ],
    shortMonths: [
      'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'
    ],
    days: [
      'Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'
    ],
    shortDays: [ 'Mon','Tue','Wed','Thu','Fri','Sat','Sun' ],
    nextMonth: 'Next month',
    prevMonth: 'Previous month',
    currMonth: 'Start month'
  },

  sv: {
    months: [
      'januari','februari','mars','april','maj','juni','juli',
      'augusti','september','oktober','november','december'
    ],
    shortMonths: [
      'jan','feb','mar','apr','maj','jun','jul','aug','sep','okt','nov','dec'
    ],
    days: [
      'måndag','tisdag','onsdag','torsdag','fredag','lördag','söndag'
    ],
    shortDays: [ 'mån','tis','ons','tor','fre','lör','sön' ],
    nextMonth: 'Nästa månad',
    prevMonth: 'Föregående månad',
    currMonth: 'Startmånad'
  }
};

/*! Format string, like in C#:
 *! String.format("This is argument {0} and {1}", "One", 2);
 */
String.format = function(format) // {{{
{
  for (var i = 0; i < arguments.length; i++) {
    var re = new RegExp("\\\{" + i + "\\\}", "g");
    format = format.replace(re, arguments[i+1]);
  }

  return format;
}; // }}}

$ID = function(id) { return $('#' + id); };

/*! Function to use for debugging output
 */
var lowtrace = window.console ? console.log : alert;

/*! Trace function. Only outputs when in DEBUG mode
 */
var trace = function()
{
  if (STATIC.DEBUG && arguments.length > 0) {
    var m = arguments[0];
    if (arguments.length > 1) {
      for (var i = 1; i < arguments.length; i++) {
	var re = new RegExp("\\\{" + i-1 + "\\\}", "g");
	m = m.replace(re, arguments[i]);
      }
    }
    try { window.console ? console.log(m) : alert(m); }
    catch (e) { console.log(e); }
  }
};

/*! Set focus on form field @[field] and scroll to it
 */
function focusField(field)
{
  if (typeof field == 'string')
    field = $ID(field);

  document.location.href = "#" + field.attr('id');
  field.focus();
  return false;
}

/*! Open link in new window
 *!
 *! @param HTMLElement caller
 *!  The link that should be opened in a new window
 *! @param string realm
 *!  Window name to use
 */
function TargetBlank(caller, realm)
{
  if (realm) window.open(caller.href, realm);
  else window.open(caller.href);

  return false;
}

/*! Insert a Flash file
 */
function Flash(file, target, width, height, version, vars, params)
{
  if (!width)   width   = '100%';
  if (!height)  height  = '100%';
  if (!version) version = 6;

  var so = new SWFObject(file, target, width, height, version);

  for (var name in params)
    so.addParam(name, params[name]);

  for (var name in vars)
    so.addVariable(name, vars[name]);

  so.write(target);
}

/*! Insert a Flash movie
 */
function MoviePlayer(datafile, target, vars, width, height)
{
  var ff = '/globals__/flash/mp2.swf';
  if (!vars)
    vars = {};

  vars.media = datafile;

  Flash(ff, target, width, height, 6, vars, { scale: 'noScale'});
}

/*! Miscellaneous methods and variables
 */
var Misc = // {{{
{
  prevSelectedTOC: null,
  currentTOC: null,
  
  ViewableWidth: function()
  {
    var width = $(document.body).width();
    if (width == 0)
      width = document.body.offsetWidth;
    var body = $ID('main-wrapper').width();
    return { window: width, content: body };
  },

  HighlightSelectedTOC: function(caller, id)
  {
    caller     = $(caller);
    var p      = $ID(id);
    var pc     = null;
    var parent = caller.parents('.toc-component');
    
    if (!parent) return;

    parent          = parent[0];
    parent.id       = 'toc-' + id;
    this.currentTOC = parent.id;

    pc = p.next('.picture-component,.toc-component');
    var h = pc.children('h2');
    if (h.length > 0)
      pc = h[0];
    else {
      h = pc.children('h3');
      pc = h && h.length > 0 && h[0];
    }
    
    if (!pc) return;

    pc = $(pc);

    if (this.prevSelectedTOC) {
      this.prevSelectedTOC.removeClass('highlighted-toc');
      $('#htoctop').remove();
    }

    this.prevSelectedTOC = pc;
    pc.addClass('highlighted-toc');

    var e = $("<p id='htoctop' style='margin:5px 0 10px 0'>" +
              "<a href='#" + this.currentTOC + "' class='to-the-top-dark'>" +
	      "Till förteckningen</a></p>");

    pc.after(e);
    return;
  }
}; // }}}

var ZipQuery =
{
  Init: function(inp, outp)
  {
    new ZipQueryClass(inp, outp);
  }
}

/*! Queries the zip database and returns the city of a zip number
 */
var ZipQueryClass = function(input, output)
{
  if (typeof input == 'string')  input  = $ID(input);
  if (typeof output == 'string') output = $ID(output);
  this.inputField = input;
  this.outputField = output;
  this.file = '/scripts__/postnummer.xml';
  this.init();
};

ZipQueryClass.prototype = // {{{
{
  init: function()
  {
    var f = this.inputField;

    if (f) {
      var _parent = this;
      var cb = function(ev)
      {
	ev = ev || window.event;
	var code;
	if (ev.keyCode)    code = ev.keyCode;
	else if (ev.which) code = ev.which;

	switch (code) {
	  case 8:  case 9:  case 13: case 37:
	  case 38: case 39: case 40: case 47:
	    return;
	}

	var ok = false;
	var v = this.value.replace(' ', '');
	var c = v.substr(v.length-1, v.length).charCodeAt(0);
	this.value = v;
	if (v.length == 5) {
	  if (parseInt(v) > 10000 && this._zip != v) {
	    this._zip = v;
	    _parent.Query(v);
	    return;
	  }
	}
	this.value = v.substr(0,5);
      };
      f.keyup(cb);
      f.blur(cb);
      f.change(cb);
    }
  },

  Query: function(code)
  {
    var _parent = this;
    $.get(this.file, { zip:code }, function(res) {
      _parent.outputField.attr('value', (res == 'false') ? '' : res);
    });
  }
}; // }}}

/*! Handle form errors
 */
var Form = // {{{
{
  Error: // {{{
  {
    errors: [],
    form: null,
    Append: function(id, message)
    {
      if (!Form.Error.form)
      	Form.Error.form = this.findForm(document.getElementById(id));

      var h = "<div class='form-error'>" +
              "<a href='javascript:void(0)'" +
              " onclick='document.location=\"#{0}\";$(\"#{0}\").focus();'>" +
              "{1}</a></div>";

      Form.Error.errors.push($(String.format(h, id, message)));
      $('#' + id).addClass('error');
    },

    Print: function()
    {
      var form = $(this.form);
      var wrap = $("<div class='form-errors'><p>Några fel uppstod!</p></div>");
      var eles = form.find('fieldset,select,input[type!=hidden],textarea');
      $(this.errors).each(function(i, el) { wrap.append(el); });
      wrap.insertBefore($(eles[0]));
    },

    findForm: function(child)
    {
      var p = child;
      while ((p = p.parentNode) != null)
      	if (p.nodeName == 'FORM')
	  return p;
    }
  } // }}}
}; // }}}

var Asset = // {{{
{
  css: function(path) 
  {
    $('head').append($(String.format("<link rel='stylesheet' type='text/css' " +
                                     "href='{0}'/>", path)));
  },

  javascript: function(path)
  {
    $('head').append($(String.format("<script type='text/javascript' " +
                                     "src='{0}'></script>", path)));
  }
}; // }}}

/*! Creates a listener for when the mouse is clicked outside of an object
 *!
 *! <code>
 *! function myCallback(htmlObj)
 *! {
 *!   htmlObj.style.display = 'none';
 *! }
 *!
 *! Click.Outside(document.getElementById('my-div', myCallback);
 *! </code>
 */
var Click =
{
  container: [],
  isInit: false,

  Outside: function(obj, callback, extraArgs)
  {
    if (!this.isInit) {
      document.body.onmouseup = Click.__click;
      this.isInit = true;
    }

    this._push({ object: obj, callback: callback, args: extraArgs });
  },

  _push: function(w)
  {
    var e = false;
    for (var i = 0; i < this.container.length; i++) {
      if (this.container[i].object == w.object) {
	e = true;
	break;
      }
    }

    if (!e)
      this.container.push(w);
  },

  _unshift: function(w)
  {
    var a = [];
    for (var i = 0; i < this.container.length; i++)
      if (this.container[i].object != w)
	a.push(this.container[i]);

    this.container = a;
  },

  __click: function(evt)
  {
    var e = evt ? evt : window.event;
    var mx = e.clientX;
    var my = e.clientY;
    var c  = Click.container;
/*
    if (Browser.browser == 'Explorer') {
      my += document.getElementsByTagName('body')[0].scrollTop;
      mx += document.getElementsByTagName('body')[0].scrollLeft;
    }
    else {
*/
      if (typeof window.pageYOffset == 'number') {
	my += window.pageYOffset;
	mx += window.pageXOffset;
      }
      else {
	my += document.body.scrollTop;
	mx += document.body.scrollLeft;
      }
/*    } */

    for (var i = 0; i < c.length; i++) {
      var b = Click.getBounds(c[i].object);
      if (mx < b.x || mx > b.w || my < b.y || my > b.h) {
	Click._unshift(c[i].object);
	c[i].callback(c[i].object, c[i].args);
      }
    }
  },

  getBounds: function(obj)
  {
    var pos = $(obj).position();
    var w = pos.left + obj.offsetWidth;
    var h = pos.top  + obj.offsetHeight;

    return { x: pos.left, y: pos.top, w: w, h: h };
  }
}; // }}}

var ExpandableMenu = function(caller, target) // {{{
{
  this.caller = $ID(caller);
  this.target = $ID(target);
  var my = this;

  this.caller.click(function() {
    if (jQuery.browser.msie) $(my.target.toggle());
    else $(my.target).slideToggle('fast');
    return false;
  });
}; // }}}

function DelayForm(form, msg, addBreak) // {{{
{
  var fields = 0;
  form = $(form);
  form.find('select').each(function(i, sel) {
    $(sel).attr('disabled', 'disabled');
    form.append($(String.format(
      "<input type='hidden' name='{0}' value='{1}' />",
      $(sel).attr('name'), sel.options[sel.selectedIndex].value
    )));
    $(sel).attr('name', '__' + $(sel).attr('name') + '__');
    fields++;
  });
  
  form.find('input[type!=hidden]').each(function(i, inp) {
    $(inp).attr('disabled','disabled');
    form.append($(String.format(
      "<input type='hidden' name='{0}' value='{1}' />",
      inp.name, inp.value
    )));
    $(inp).attr('name', '__' + inp.name + '__');
    fields++;
  });

  if (fields > 0) {
    form.css('opacity','0.4');
    var e = $("<div class='form-overlay'><p><strong>" +
              (msg||'Var god vänta') + "</strong></p></div>");

    $(document.body).append(e);
    var pos    = form.offset();
    var width  = parseInt(form.width());
    var height = parseInt(form.height());

    e.css('top',  (pos.top + height/2) - (e.height()/2) - 7);
    e.css('left', (pos.left + width/2) - (e.width()/2));
    return true;
  }

  return false;
} // }}}


var MetaFrame = 
{
  banners:      null,
  metadata:     null,
  search:       null,
  frame:        null,
  contentWidth: 760,
  initWidth:    0,
  collapsed:    false,

  Move: function()
  {
    var w = Misc.ViewableWidth();
    var banners = $ID('menu-banners');
//    var metadata = $ID('metadata');
//    if (!metadata || metadata.length == 0) return;
//    metadata = $ID('metadata').clone();

    if (!this.search)
      this.search = $ID('global-search-form');
    if (!this.frame) {
      this.frame = $ID('right-extra-frame');
      this.initWidth = this.contentWidth + 220;
    }

    if ((w.window - this.contentWidth) < 220) {
      if (this.collapsed)
	return;

      banners     && $ID('menu-banners').remove();
//      metadata    && $ID('metadata').remove();
      this.search && $ID('global-search-form').remove();
      this.frame  && this.frame.css('display', 'none');
      $ID('main-wrapper').css('width', this.contentWidth);
      $ID('menu-banners-wrapper').append(banners);
//      $ID('metadata-content').append(metadata);

      this.collapsed = true;
      return;
    }

    if (!this.collapsed)
      return;

    this.frame.append(this.search);
    this.frame.append(banners);
//    this.frame.append(metadata);

    $ID('menu-banners-wrapper').empty();
//    $ID('metadata-content').empty();
    
    $ID('main-wrapper').css('width', this.contentWidth + 210);
    this.frame.css('display', 'block');
    this.collapsed = false;
  }
};

var TopMenu = 
{
  menus: {},

  ShowSubmenu: function(caller)
  {
    caller = $(caller);

    var m;
    if (!(m = TopMenu.menus[caller.attr('title')])) {
      m = new SubMenu();
      TopMenu.menus[caller.attr('title')] = m;
    }

    m.Show(caller);
  }
};

var SubMenu = function()
{
  this.current = null;
  this.timeout = null;
  this.doClose = false;
};

SubMenu.prototype =
{
  Show: function(caller)
  {
    if (this.timeout) {
      clearInterval(this.timeout);
      this.timeout = null;
    }
    
    caller = $(caller);
    var callerh = caller.get(0);
    var ul = caller.parent().find('ul');
    
    if (!ul) return;
    
    var ulh = ul.get(0);
    
    if (!ulh.hasmouseover) {
      ulh.owner = this;
      ulh.hasmouseover = 1;
      ul.mouseover(function(ev) {
	this.owner.doClose = false;
      });
    }

    if (!ulh.hasmouseout) {
      ulh.hasmouseout = 1;
      ul.mouseout(function(ev) {
	this.owner.doClose = true;
	this.owner.setTimeout('Submenu');
      });
    }

    this.current = ul;
    ul.css('display','block');
    var h = ul.find('a').height();

    var diff = 0;
    if (window.ie) diff = 1;
    if (window.opera) diff = -1;
    ul.css('margin-top', -(54-diff));
    this.doClose = false;
    
    if (!callerh.hasmouseout) {
      caller.get(0).owner = this;
      callerh.hasmouseout = 1;
      caller.mouseout(function(ev) {
	this.owner.doClose = true;
	this.owner.setTimeout('Caller');
      });
    }
    //else trace("mouseout already set");
  },
  
  setTimeout: function(by)
  {
    if (this.timeout)
      clearInterval(this.timeout);

    var owner = this;
    this.timeout = setTimeout(function() {
      if (owner.doClose) {
	owner.current.css('display','none');
	owner.doClose = false;
      }
      owner.timeout = null;
    }, 500);
  }
};

/*
var Tweet = 
{
  endpoint: "http://twitter.com/statuses/user_timeline/tekniskaverken.json?callback=?&" + 
            "count=5",
  Load: function(url)
  {
    var ul = $('#twitter-list');
    $.getJSON(this.endpoint, function(data) {
      ul.empty();
      $(data).each(function(i, row) {
	var ut = Date.parse(row.created_at);
	var date = new Date();
	date.setTime(ut);

	var s = date.getYear()+1900 + ', ';
	var v = date.getDay()-1;
	if (v < 0) v = 6;

	s += Strings.sv.shortDays[v] + ' ';
	s += Strings.sv.shortMonths[date.getMonth()] + ' ';

	v = parseInt(date.getDate(), 10);

	if (v < 10) v = '0' + v;

	s += v + ' ';
	s += date.getHours()-2 + ":" + date.getMinutes();

	var st = row.text.substring(0, 28)+'...';
	
	var li = $('<li><p class="text">' + st + '</p>' + 
	           '<p class="when">' + s + '</p></li>');
	li.mouseover(function() {
	  $(this).css({ 'cursor':'default', 'background':'#1a65b1'});
	  $(this).find('p.text').text(row.text);
	});
	li.mouseout(function() {
	  $(this).find('p.text').text(st);
	  $(this).css('background', 'transparent');
	});
	ul.append(li);
      });
    });
  }
};
*/

jQuery.fn.extend({ // {{{
  lessAndMore: function(settings)
  {
    _owner = this;

    var lm = $("<div class='" + (settings.moreClass||"") + "'>" +
               "<a href='javascript:void(0)'><span>" +
               (settings.moreText||"More info") + "</span></a></div>");
    lm.find('a').click(function() {
      if ((_owner).css('display') == 'none') {
        this.parentNode.className = settings.lessClass||"";
        $(this).find('span').text(settings.lessText);
      }
      else {
        this.parentNode.className = settings.moreClass||"";
        $(this).find('span').text(settings.moreText);
      }

      _owner.slideToggle('fast');
      return false;
    });

    $(this).css('display','none');
    lm.insertBefore($(this));
    var padder = $("<div style='height:10px;'></div>");
    padder.insertAfter($(this));

    my = {
      owner: _owner,
      conf: settings
    };
  },

  helpLabel: function(settings)
  {
    var label = function(elem)
    {
      //trace(this);
      var my = this;
      this.img = $('<img src="' + settings.img + '" />');
      this.img.css({
	'margin-left'  : 2,
	'margin-bottom': -5,
	'padding'      : 2,
	'display'      : 'inline-block',
	'position'     : 'relative',
	'float'        : 'none'
      });
      this.img.mouseover(function() {
	var pos = my.img.position();
	my.ele.css({
	  'display'   : 'none',
	  'position'  : 'absolute',
	  'z-index'   : 10000,
	  'left'      : pos.left + my.img.width() + 10,
	  'top'       : pos.top - 8
	});
	my.ele.toggle('fast');
      });

      this.img.mouseout(function() {
	my.ele.toggle('fast');
      });

      this.ele = $(elem);
      this.ele.removeClass('help');
      this.ele.addClass(settings['class']).css('display','none');
      this.img.insertBefore(this.ele);
    };

    for (var i = 0; i < this.length; i++)
      new label(this[i]);
  }
}); // }}}

/* URI class
 * This class is for parsing, creating and manupulating a URI
 *
 * Copyright © 2009, Pontus Östlund <spam@poppa.se>
 *
 * License GNU GPL version 3
 *
 * URI.js is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * URI.js is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with URI.js. If not, see <@url{http://www.gnu.org/licenses/@}>.
 *
 * ----------------------------------------------------------------------------
 *
 * Example of usage
 *
 * var uri = new URI("http://mydomain.com/some/path/");
 *
 * console.log(uri.scheme);     //> http
 * console.log(uri.port);       //> 80
 * console.log(uri.host);       //> mydomain.com
 * console.log(uri.path);       //> /some/path/
 * console.log(uri.toString()); //> http://mydomain.com/some/path/
 *
 * // Alter the domain
 * uri.domain = "my.otherdomain.com";
 * console.log(uri.toString()); //> http://my.otherdomain.com/some/path/
 *
 * uri.variables.articleID = 135;
 * uri.variables.action = 'read';
 * console.log(uri.toString());
 * //> http://my.otherdomain.com/some/path/?articleID=135&action=read
 */

/* URI constructor
 *
 * @param uri
 */
var URI = function(uri) // {{{
{
  var scheme = null;
  var host = null;
  var username = null;
  var password = null;
  var port = null;
  var path = null;
  var query = null;
  var fragment = null;
  var variables = {};
  var ports = {
    ftp: 21,
    ssh: 22,
    telnet: 23,
    smtp: 25,
    http: 80,
    https: 443
  };

  var enc = encodeURIComponent;
  var dec = decodeURIComponent;

  var re = new RegExp("(?:([-+a-z0-9]+)://" + // Scheme
		      "((.[^:]*):?(.*)?@)?" + // Userinfo
		      "(.[^:/]*)"           + // Host
		      ":?([0-9]{1,6})?)?"   + // Port
		      "([/.].[^?#]*)?"      + // Path
		      "([?](.[^#]*))?"      + // Query
		      "#?(.*)?", "i");        // Fragment

  var parse = function(theUri)
  {
    uri = theUri;
    var m;
    if (uri && (m = re.exec(uri))) {
      scheme   = m[1] && m[1].toLowerCase();
      username = m[3];
      password = m[4];
      host     = m[5] && m[5].toLowerCase();
      port     = m[6] && parseInt(m[6],10);
      path     = m[7];
      query    = m[9];
      fragment = m[10];

      if (!port && scheme)
	port = ports[scheme];

      if (query && query.length) {
	var q = query.split('&');
	for (var i = 0; i < q.length; i++) {
	  var p = q[i].split('=');
	  variables[dec(p[0])] = p.length > 1 ? dec(p[1]) : null;
	}
      }
    }
  };

  var isDefaultPort = function()
  {
    if (!pub.port) return true;
    for (var schema in ports) {
      if (schema == pub.scheme && pub.port != ports[pub.scheme])
	return false;
    }

    return true;
  };

  parse(uri);

  var pub;

  /*****************************************************************************
   * Return public members and methods */ return pub = {
  /****************************************************************************/

  /* The uri scheme
   * @var string
   */
  scheme: scheme,

  /* The host
   * @var string
   */
  host: host,

  /* The username
   * @var string
   */
  username: username,

  /* The password
   * @var string
   */
  password: password,

  /* The port
   * @var int
   */
  port: port,

  /* The local path
   * @var path
   */
  path: path,

  /* The fragment
   * @var string
   */
  fragment: fragment,

  /* The query string variables
   * @var object
   */
  variables: variables,

  /* Reparse with uri
   *
   * @param uri
   */
  parse: function(uri)
  {
    parse(uri);
    this.scheme = scheme;
    this.host = host;
    this.username = username;
    this.password = password;
    this.port = port;
    this.path = path;
    this.fragment = fragment;
    this.variables = variables;
  },

  /* Returns the variables as a query string
   */
  queryString: function()
  {
    //trace(this.variables);
    var tmp = [];
    for (var name in this.variables) {
      var t;
      if (this.variables[name] != null)
	t = enc(name) + '=' + enc(this.variables[name]);
      else
      	t = enc(name);

      tmp.push(t);
    }

    return tmp.length && tmp.join('&') || null;
  },

  /* Turns this object into a full URI
   */
  toString: function()
  {
    var s = "", q = null;
    if (this.scheme)                    s  = this.scheme + "://";
    if (this.username)                  s += this.username;
    if (this.username && this.password) s += ":";
    if (this.password)                  s += this.password;
    if (this.username)                  s += "@";
    if (this.host)                      s += this.host;
    if (!isDefaultPort())               s += ":" + this.port;
    if (this.path)                      s += this.path;
    if (q = this.queryString())         s += "?" + q;
    if (this.fragment)                  s += "#" + this.fragment;

    return s;
  }
  /***/}/***/
}; // }}}

$(document).ready(function() 
{
  MSIE  = jQuery.browser.msie;
  MSIE6 = jQuery.browser.msie && jQuery.browser.version == '6.0';

  $('.hide-from-js,.tabcontent').each(function(i, elem) {
    $(elem).css('display', 'none');
  });

  $('.js-show-on-ready').each(function(i, elem) {
    $(elem).css('display', 'block');
  });

  $('div.less-more').lessAndMore({
    moreText:  'Mer information',
    lessText:  'Mindre information',
    moreClass: 'more-info',
    lessClass: 'less-info'
  });

  $('.help').helpLabel({
    'img'   : '/t-net/my-pages/templates/default/img/icons/help.png',
    'class' : 'the-help'
  });
  
  //Tweet.Load();
  new DOMTabs();

  if (Form.Error.form)
    Form.Error.Print();
  
  MetaFrame.Move();
});

$(window).resize(function(e) {
  MetaFrame.Move();
});