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

/*! 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(fmt)
{
  for (var i = 1; i < arguments.length; i++)
    fmt = fmt.replace('{' + (i-1) + '}', arguments[i]);

  return fmt;
};

$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++)
	m = m.replace('{' + (i-1) + '}', arguments[i]);
    }
    lowtrace(m);
  }
};

/*! 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 FormError = // {{{ 
{
  errors: 0,
  errDiv: null,
  errDivInner: null,
  /**
   * Anropas från XSL-mallen form-missing-field (cms-templates/functions.xsl)
   * och lägger till felmeddelandet i <div id="form-errors" /> om det finns.
  */
  Add: function(field, text)
  {
    if (typeof field == 'string')
      field = $ID(field);

    if (!field || !field.length)
      return;

    try {
      this.errors++;
      if (!this.errDiv) {
	this.errDiv = $('#form-errors');
	if (!this.errDiv || !this.errDiv.length) {
	  var form = this.findForm(field);
	  if (!form) {
	    this.errDiv = null;
	    return;
	  }
	  this.errDiv = $("<div id='form-errors'></div>");
	  form.prepend(this.errDiv);
	}

	this.errDivInner = $("<div class='container'></div>'");
	this.errDiv.append(this.errDivInner);
	$(document).ready(this.onDone);
      }

      this.errDivInner.append(FormError.makeTag(field, text));
    }
    catch (ex) {
      trace(ex);
    }
  },

  makeTag: function(field, text)
  {
    var p   = $('<p>');

    if (field) {
      var a = $(String.format("<a href='#{0}'>{1}</a>", field, text));
      a[0].field = field;
      p.append(a.click(function(e) {
	return focusField($(this)[0].field);
      }));
    }
    else {
      p.text(text);
    }
    
    var div = $("<div class='form-error'></div>");
    var img = $(
      String.format(
	"<img width='{0}' height='{1}' src='{2}' alt='{3}' title='' />",
	22, 22, '/t-net/img/icons/notify.png', text
      )
    );
    div.append(img);
    div.append(p);
   
    return div;
  },

  onDone: function()
  {
    if (FormError.errors > 0) {
      var f = FormError;
      f.errDiv.addClass('got-errors');
      var text = f.errors + ' stycken felifyllda formulärfält hittades. ' +
		 'Var god rätta till uppgifterna enligt anvisningarna nedan';

      f.errDiv.prepend(
	$(String.format("<p class='header'><strong>{0}</strong></p>", text))
      );
    }
  },
  
  findForm: function(field)
  {
    if (typeof field == 'string')
      field = $ID(field);

    var form = field.parents('form');
    return form && form.length && $(form[0]) || false;
  }
}; // }}}

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);
  this.caller.get(0).owner = this;
  this.target.hide();
  
  this.caller.click(function() {
    $(this.owner.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);
      });
    });
  }
};

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

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

  //Tweet.Load();
  new DOMTabs();

  MetaFrame.Move();
});

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