
// Copyright (c) 2003-2008 Sonic Foundry, Inc. and Sonic Foundry Media Systems, Inc. Neither this code nor any portion 
// thereof may be reproduced, altered, or otherwise changed, distributed or copied, without the express written
// permission of Sonic Foundry.  All rights reserved.

function GlobalOptions(){}
GlobalOptions.AppRoot="/WebMeeting2009/Viewer";
GlobalOptions.AllowEmailForm = false;GlobalOptions.EnableContextMenuForPlayer = true;GlobalOptions.AlwaysUseSilverlight = false;GlobalOptions.UseLiveEventPolling = false;GlobalOptions.SlideGroupThreshold = 2000;GlobalOptions.SlideGroupMinToTrigger = 25;GlobalOptions.SlideGroupMaxInGroup = 10;GlobalOptions.ErrorPage = "Errors/ErrorPage.aspx";

Type.registerNamespace('Localization');Localization.Common=function(){}
Localization.Buttons=function(){}
Localization.FullSize=function(){}
Localization.CurrentSlideResource=function(){}
Localization.LinksResource=function(){}
Localization.ThumbnailsResource=function(){}
Localization.LiveIndicatorResource=function(){}
Localization.PlayerLayoutResource=function(){}
Localization.PresentationCardResource=function(){}

Localization.Common.registerClass('Localization.Common');
Localization.Buttons.registerClass('Localization.Buttons');
Localization.FullSize.registerClass('Localization.FullSize');
Localization.CurrentSlideResource.registerClass('Localization.CurrentSlideResource');
Localization.LinksResource.registerClass('Localization.LinksResource');
Localization.ThumbnailsResource.registerClass('Localization.ThumbnailsResource');
Localization.PlayerLayoutResource.registerClass('Localization.PlayerLayoutResource');
Localization.PresentationCardResource.registerClass('Localization.PresentationCardResource');
Localization.LiveIndicatorResource.registerClass('Localization.LiveIndicatorResource');

Localization.Common.Slide='Slide';
Localization.Common.Of='de';
Localization.Common.PreviousSlide='Slide Anterior';
Localization.Common.NextSlide='Próximo Slide';
Localization.Common.Language='Idioma';
Localization.Common.AudioTrack='Canal de Áudio';
Localization.Common.Expand='Maximizar';
Localization.Common.Collapse='Minimizar';
Localization.Common.SlideShow='Slide Show';
Localization.Common.SlideList='Lista de Slides';
Localization.Buttons.ShowPolls='Enquetes';
Localization.Buttons.Ask='Perguntar';
Localization.Buttons.Email='Enviar para um amigo';
Localization.Buttons.Links='Links e Outros Materiais';
Localization.Buttons.PreviousSlide='Slide Anterior';
Localization.Buttons.NextSlide='Próximo Slide';
Localization.Buttons.Close='Fechar Janela';
Localization.Buttons.FullScreen='Tela Cheia';
Localization.Buttons.Help='Ajuda';
Localization.Buttons.MaxSlide='Slides em Tamanho Original';
Localization.Buttons.Polls='Enquetes';
Localization.Buttons.Skipback='Retornar';
Localization.Buttons.Stop='Parar';
Localization.Buttons.Mute='Mudo';
Localization.Buttons.UnMute='Volume';
Localization.Buttons.Play='Play';
Localization.Buttons.Pause='Pausar';
Localization.Buttons.CurrentSlide='Slide';
Localization.Buttons.Navigate='Navegar';
Localization.Buttons.ChangeVideoPosition='Mudar Posição do Vídeo';
Localization.Buttons.PlayFaster = 'Mais Rápido';
Localization.Buttons.PlaySlower = 'Mais Lento';
Localization.FullSize.AutoRefresh='Atualização Automática';
Localization.FullSize.PlayFromSlide='Ver a partir deste Slide';
Localization.FullSize.RefreshNow='Atualizar agora';
Localization.CurrentSlideResource.SlideImage='Slide';
Localization.CurrentSlideResource.ShowFullSize='Slides em Tamanho Original';
Localization.CurrentSlideResource.ShowSlideMagnifier='Ligar Zoom';
Localization.CurrentSlideResource.HideSlideMagnifier='Desligar Zoom';
Localization.CurrentSlideResource.PresentationHasEnded='WebMeeting Encerrado';
Localization.LinksResource.PresentationLinks='Links e Outros Materiais';
Localization.LinksResource.Close='Fechar';
Localization.ThumbnailsResource.Thumbnails='Miniaturas';
Localization.ThumbnailsResource.SlideList='Lista de Slides';
Localization.ThumbnailsResource.SmallThumbnails='Miniaturas Menores';
Localization.ThumbnailsResource.LargeThumbnails='Miniaturas Maiores';
Localization.ThumbnailsResource.Chapters='Capítulos';
Localization.ThumbnailsResource.Options='Opção de Miniatura';
Localization.ThumbnailsResource.PreviewSlide='Preview deste slide';
Localization.ThumbnailsResource.PlayFromSlide='Assistir a partir deste slide';
Localization.ThumbnailsResource.ExpandSlides='Maximizar Slides';
Localization.ThumbnailsResource.CollapseSlides='Minimizar Slides';
Localization.ThumbnailsResource.Page='Página';
Localization.ThumbnailsResource.Of='de';
Localization.ThumbnailsResource.Previous='Anterior';
Localization.ThumbnailsResource.Next='Próximo';
Localization.PlayerLayoutResource.AudioOnly ='WebMeeting apenas com Áudio';
Localization.PlayerLayoutResource.NotStarted = 'O WebMeeting ainda não comecou';
Localization.PlayerLayoutResource.ShowCaptioning = 'Mostrar Legendas';
Localization.PlayerLayoutResource.HideCaptioning = 'Ocultar Legendas';
Localization.LiveIndicatorResource.LiveTooltip='AO VIVO';
Localization.LiveIndicatorResource.ReplayTooltip='Gravado';
Localization.LiveIndicatorResource.PausedTooltip='EM PAUSA';
Localization.MediaPlayer=function(){}
Localization.MediaPlayer.registerClass('Localization.MediaPlayer');
Localization.MediaPlayer.GeneralError = 'Ocorreu um erro no seu computador para reprodução do vídeo e aúdio deste WebMeeting. Entre em contato com suporte@atitude.com.br ou ligue para 0800 771-5643.';
Localization.MediaPlayer.FileNotFoundError='O arquivo de vídeo não foi localizado. Entre em contato com suporte@atitude.com.br ou ligue para 0800 771-5643';
Localization.MediaPlayer.ServerConnectionError='Seu computador não conseguiu conexão com servidor de vídeo. Pressione F5 para recarregar a página ou clique em AJUDA. Suporte: 0800 771-5643';
Localization.MediaPlayer.ServerNotAvailable = 'Não foi possível conectar-se ao servidor de vídeo. Pressione F5 para recarregar a página. Caso o problema persista, Verifique sua conexão de internet ou configurações de firewall/NAT/VPN ou entre em contato com suporte@atitude.com.br ou ligue para 0800 771-5643.';
Localization.MediaPlayer.SilverlightNetworkError='Não é possível executar este WebMeeting. O servidor pode não estar disponivel ou o formato não é suportado. Clique em AJUDA ou ligue 0800 771-5643.';
Localization.MediaPlayer.SilverlightSetValueError='Não foi possível designar o seguinte valor para este WebMeeting: ';
Localization.MediaPlayer.SilverlightFullScreenPrompt = 'Clique para colocar em Tela Cheia';
Localization.MediaPlayer.ClipEnded='WebMeeting Encerrado';
Localization.MediaPlayer.State=function(){}
Localization.MediaPlayer.State.registerClass('Localization.MediaPlayer.State');
Localization.MediaPlayer.State.Undefined='ERRO. Clique em AJUDA';
Localization.MediaPlayer.State.Stopped='Parado';
Localization.MediaPlayer.State.Paused='Em pausa';
Localization.MediaPlayer.State.Playing='Em exibição';
Localization.MediaPlayer.State.ScanForward='Fast Forward';
Localization.MediaPlayer.State.ScanReverse='Rewind';
Localization.MediaPlayer.State.Buffering='Carregando...';
Localization.MediaPlayer.State.Waiting='Aguardando';
Localization.MediaPlayer.State.MediaEnded='Vídeo Encerrado';
Localization.MediaPlayer.State.Transitioning='Conectando';
Localization.MediaPlayer.State.Ready='ERRO. Clique em Ajuda ou ligue 0800 771 5643';
Localization.MediaPlayer.State.Reconnecting='Reconectando. Aguarde...';
Localization.MediaPlayer.State.Closed='Fechado';
Localization.MediaPlayer.State.Error='ERRO';
Localization.MediaPlayer.State.Opening='Abrindo';
Localization.MediaPlayer.State.Unknown='ERRO. Clique em AJUDA';
Localization.SubmitQuestionSuccess = 'Sua pergunta/comentário foi enviada com sucesso.<br />Obrigado por participar!';
Localization.SubmitQuestionFailure = 'Houve um erro no envio da pergunta/comentário.<br />Por favor, tente novamente.';
Localization.EmailInviteInvalid = 'Um dos e-mails informados parece ser inválido.<br />Por favor, verifique e tente novamente.';
Localization.ForumEmailInvalid = 'Os e-mails informados parecem ser inválidos.';
Localization.ForumNameRequired = 'Informe o seu nome';
Localization.ForumQuestionRequired = 'Digite sua pergunta ou comentário';
Localization.ForumSubjectRequired = 'Informe a cidade';
Localization.ForumErrorMessage = 'Por favor, corrija os seguintes erros:';
Localization.ForumQuestionTimeError = 'Indique um tempo válido na apresentação';
Localization.PresentationCardResource.Presenters = 'Palestrante(s):';
Localization.PresentationCardResource.Description = 'Descrição:';
Localization.PresentationCardResource.AirDate = 'Data:';
Localization.PresentationCardResource.AirTime =  'Hora:';
Localization.PresentationCardResource.Duration =  'Duração:';
Localization.PresentationCardResource.DefaultTitle =  'WebMeeting';
Localization.PresentationCardResource.DefaultDescription =  'Descrição';
Localization.PresentationCardResource.More =  'Mais...';

/*  Prototype JavaScript framework, version 1.6.0
 *  (c) 2005-2007 Sam Stephenson
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://www.prototypejs.org/
 *
 *--------------------------------------------------------------------------*/

var Prototype = {
  Version: '1.6.0',

  Browser: {
    IE:     !!(window.attachEvent && !window.opera),
    Opera:  !!window.opera,
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1,
    MobileSafari: !!navigator.userAgent.match(/Apple.*Mobile.*Safari/)
  },

  BrowserFeatures: {
    XPath: !!document.evaluate,
    ElementExtensions: !!window.HTMLElement,
    SpecificElementExtensions:
      document.createElement('div').__proto__ &&
      document.createElement('div').__proto__ !==
        document.createElement('form').__proto__
  },

  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,

  emptyFunction: function() { },
  K: function(x) { return x }
};

if (Prototype.Browser.MobileSafari)
  Prototype.BrowserFeatures.SpecificElementExtensions = false;

if (Prototype.Browser.WebKit)
  Prototype.BrowserFeatures.XPath = false;

/* Based on Alex Arnell's inheritance implementation. */
var Class = {
  create: function() {
    var parent = null, properties = $A(arguments);
    if (Object.isFunction(properties[0]))
      parent = properties.shift();

    function klass() {
      this.initialize.apply(this, arguments);
    }

    Object.extend(klass, Class.Methods);
    klass.superclass = parent;
    klass.subclasses = [];

    if (parent) {
      var subclass = function() { };
      subclass.prototype = parent.prototype;
      klass.prototype = new subclass;
      parent.subclasses.push(klass);
    }

    for (var i = 0; i < properties.length; i++)
      klass.addMethods(properties[i]);

    if (!klass.prototype.initialize)
      klass.prototype.initialize = Prototype.emptyFunction;

    klass.prototype.constructor = klass;

    return klass;
  }
};

Class.Methods = {
  addMethods: function(source) {
    var ancestor   = this.superclass && this.superclass.prototype;
    var properties = Object.keys(source);

    if (!Object.keys({ toString: true }).length)
      properties.push("toString", "valueOf");

    for (var i = 0, length = properties.length; i < length; i++) {
      var property = properties[i], value = source[property];
      if (ancestor && Object.isFunction(value) &&
          value.argumentNames().first() == "$super") {
        var method = value, value = Object.extend((function(m) {
          return function() { return ancestor[m].apply(this, arguments) };
        })(property).wrap(method), {
          valueOf:  function() { return method },
          toString: function() { return method.toString() }
        });
      }
      this.prototype[property] = value;
    }

    return this;
  }
};

var Abstract = { };

Object.extend = function(destination, source) {
  for (var property in source)
    destination[property] = source[property];
  return destination;
};

Object.extend(Object, {
  inspect: function(object) {
    try {
      if (object === undefined) return 'undefined';
      if (object === null) return 'null';
      return object.inspect ? object.inspect() : object.toString();
    } catch (e) {
      if (e instanceof RangeError) return '...';
      throw e;
    }
  },

  toJSON: function(object) {
    var type = typeof object;
    switch (type) {
      case 'undefined':
      case 'function':
      case 'unknown': return;
      case 'boolean': return object.toString();
    }

    if (object === null) return 'null';
    if (object.toJSON) return object.toJSON();
    if (Object.isElement(object)) return;

    var results = [];
    for (var property in object) {
      var value = Object.toJSON(object[property]);
      if (value !== undefined)
        results.push(property.toJSON() + ': ' + value);
    }

    return '{' + results.join(', ') + '}';
  },

  toQueryString: function(object) {
    return $H(object).toQueryString();
  },

  toHTML: function(object) {
    return object && object.toHTML ? object.toHTML() : String.interpret(object);
  },

  keys: function(object) {
    var keys = [];
    for (var property in object)
      keys.push(property);
    return keys;
  },

  values: function(object) {
    var values = [];
    for (var property in object)
      values.push(object[property]);
    return values;
  },

  clone: function(object) {
    return Object.extend({ }, object);
  },

  isElement: function(object) {
    return object && object.nodeType == 1;
  },

  isArray: function(object) {
    return object && object.constructor === Array;
  },

  isHash: function(object) {
    return object instanceof Hash;
  },

  isFunction: function(object) {
    return typeof object == "function";
  },

  isString: function(object) {
    return typeof object == "string";
  },

  isNumber: function(object) {
    return typeof object == "number";
  },

  isUndefined: function(object) {
    return typeof object == "undefined";
  }
});

Object.extend(Function.prototype, {
  argumentNames: function() {
    var names = this.toString().match(/^[\s\(]*function[^(]*\((.*?)\)/)[1].split(",").invoke("strip");
    return names.length == 1 && !names[0] ? [] : names;
  },

  bind: function() {
    if (arguments.length < 2 && arguments[0] === undefined) return this;
    var __method = this, args = $A(arguments), object = args.shift();
    return function() {
      return __method.apply(object, args.concat($A(arguments)));
    }
  },

  bindAsEventListener: function() {
    var __method = this, args = $A(arguments), object = args.shift();
    return function(event) {
      return __method.apply(object, [event || window.event].concat(args));
    }
  },

  curry: function() {
    if (!arguments.length) return this;
    var __method = this, args = $A(arguments);
    return function() {
      return __method.apply(this, args.concat($A(arguments)));
    }
  },

  delay: function() {
    var __method = this, args = $A(arguments), timeout = args.shift() * 1000;
    return window.setTimeout(function() {
      return __method.apply(__method, args);
    }, timeout);
  },

  wrap: function(wrapper) {
    var __method = this;
    return function() {
      return wrapper.apply(this, [__method.bind(this)].concat($A(arguments)));
    }
  },

  methodize: function() {
    if (this._methodized) return this._methodized;
    var __method = this;
    return this._methodized = function() {
      return __method.apply(null, [this].concat($A(arguments)));
    };
  }
});

Function.prototype.defer = Function.prototype.delay.curry(0.01);

Date.prototype.toJSON = function() {
  return '"' + this.getUTCFullYear() + '-' +
    (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
    this.getUTCDate().toPaddedString(2) + 'T' +
    this.getUTCHours().toPaddedString(2) + ':' +
    this.getUTCMinutes().toPaddedString(2) + ':' +
    this.getUTCSeconds().toPaddedString(2) + 'Z"';
};

var Try = {
  these: function() {
    var returnValue;

    for (var i = 0, length = arguments.length; i < length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) { }
    }

    return returnValue;
  }
};

RegExp.prototype.match = RegExp.prototype.test;

RegExp.escape = function(str) {
  return String(str).replace(/([.*+?^=!:${}()|[\]\/\\])/g, '\\$1');
};

/*--------------------------------------------------------------------------*/

var PeriodicalExecuter = Class.create({
  initialize: function(callback, frequency) {
    this.callback = callback;
    this.frequency = frequency;
    this.currentlyExecuting = false;

    this.registerCallback();
  },

  registerCallback: function() {
    this.timer = setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  execute: function() {
    this.callback(this);
  },

  stop: function() {
    if (!this.timer) return;
    clearInterval(this.timer);
    this.timer = null;
  },

  onTimerEvent: function() {
    if (!this.currentlyExecuting) {
      try {
        this.currentlyExecuting = true;
        this.execute();
      } finally {
        this.currentlyExecuting = false;
      }
    }
  }
});
Object.extend(String, {
  interpret: function(value) {
    return value == null ? '' : String(value);
  },
  specialChar: {
    '\b': '\\b',
    '\t': '\\t',
    '\n': '\\n',
    '\f': '\\f',
    '\r': '\\r',
    '\\': '\\\\'
  }
});

Object.extend(String.prototype, {
  gsub: function(pattern, replacement) {
    var result = '', source = this, match;
    replacement = arguments.callee.prepareReplacement(replacement);

    while (source.length > 0) {
      if (match = source.match(pattern)) {
        result += source.slice(0, match.index);
        result += String.interpret(replacement(match));
        source  = source.slice(match.index + match[0].length);
      } else {
        result += source, source = '';
      }
    }
    return result;
  },

  sub: function(pattern, replacement, count) {
    replacement = this.gsub.prepareReplacement(replacement);
    count = count === undefined ? 1 : count;

    return this.gsub(pattern, function(match) {
      if (--count < 0) return match[0];
      return replacement(match);
    });
  },

  scan: function(pattern, iterator) {
    this.gsub(pattern, iterator);
    return String(this);
  },

  truncate: function(length, truncation) {
    length = length || 30;
    truncation = truncation === undefined ? '...' : truncation;
    return this.length > length ?
      this.slice(0, length - truncation.length) + truncation : String(this);
  },

  strip: function() {
    return this.replace(/^\s+/, '').replace(/\s+$/, '');
  },

  stripTags: function() {
    return this.replace(/<\/?[^>]+>/gi, '');
  },

  stripScripts: function() {
    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
  },

  extractScripts: function() {
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
    return (this.match(matchAll) || []).map(function(scriptTag) {
      return (scriptTag.match(matchOne) || ['', ''])[1];
    });
  },

  evalScripts: function() {
    return this.extractScripts().map(function(script) { return eval(script) });
  },

  escapeHTML: function() {
    var self = arguments.callee;
    self.text.data = this;
    return self.div.innerHTML;
  },

  unescapeHTML: function() {
    var div = new Element('div');
    div.innerHTML = this.stripTags();
    return div.childNodes[0] ? (div.childNodes.length > 1 ?
      $A(div.childNodes).inject('', function(memo, node) { return memo+node.nodeValue }) :
      div.childNodes[0].nodeValue) : '';
  },

  toQueryParams: function(separator) {
    var match = this.strip().match(/([^?#]*)(#.*)?$/);
    if (!match) return { };

    return match[1].split(separator || '&').inject({ }, function(hash, pair) {
      if ((pair = pair.split('='))[0]) {
        var key = decodeURIComponent(pair.shift());
        var value = pair.length > 1 ? pair.join('=') : pair[0];
        if (value != undefined) value = decodeURIComponent(value);

        if (key in hash) {
          if (!Object.isArray(hash[key])) hash[key] = [hash[key]];
          hash[key].push(value);
        }
        else hash[key] = value;
      }
      return hash;
    });
  },

  toArray: function() {
    return this.split('');
  },

  succ: function() {
    return this.slice(0, this.length - 1) +
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
  },

  times: function(count) {
    return count < 1 ? '' : new Array(count + 1).join(this);
  },

  camelize: function() {
    var parts = this.split('-'), len = parts.length;
    if (len == 1) return parts[0];

    var camelized = this.charAt(0) == '-'
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
      : parts[0];

    for (var i = 1; i < len; i++)
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

    return camelized;
  },

  capitalize: function() {
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
  },

  underscore: function() {
    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
  },

  dasherize: function() {
    return this.gsub(/_/,'-');
  },

  inspect: function(useDoubleQuotes) {
    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
      var character = String.specialChar[match[0]];
      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
    });
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
  },

  toJSON: function() {
    return this.inspect(true);
  },

  unfilterJSON: function(filter) {
    return this.sub(filter || Prototype.JSONFilter, '#{1}');
  },

  isJSON: function() {
    var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
  },

  evalJSON: function(sanitize) {
    var json = this.unfilterJSON();
    try {
      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
    } catch (e) { }
    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
  },

  include: function(pattern) {
    return this.indexOf(pattern) > -1;
  },

  startsWith: function(pattern) {
    return this.indexOf(pattern) === 0;
  },

  endsWith: function(pattern) {
    var d = this.length - pattern.length;
    return d >= 0 && this.lastIndexOf(pattern) === d;
  },

  empty: function() {
    return this == '';
  },

  blank: function() {
    return /^\s*$/.test(this);
  },

  interpolate: function(object, pattern) {
    return new Template(this, pattern).evaluate(object);
  }
});

if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
  escapeHTML: function() {
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  },
  unescapeHTML: function() {
    return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
  }
});

String.prototype.gsub.prepareReplacement = function(replacement) {
  if (Object.isFunction(replacement)) return replacement;
  var template = new Template(replacement);
  return function(match) { return template.evaluate(match) };
};

String.prototype.parseQuery = String.prototype.toQueryParams;

Object.extend(String.prototype.escapeHTML, {
  div:  document.createElement('div'),
  text: document.createTextNode('')
});

with (String.prototype.escapeHTML) div.appendChild(text);

var Template = Class.create({
  initialize: function(template, pattern) {
    this.template = template.toString();
    this.pattern = pattern || Template.Pattern;
  },

  evaluate: function(object) {
    if (Object.isFunction(object.toTemplateReplacements))
      object = object.toTemplateReplacements();

    return this.template.gsub(this.pattern, function(match) {
      if (object == null) return '';

      var before = match[1] || '';
      if (before == '\\') return match[2];

      var ctx = object, expr = match[3];
      var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/, match = pattern.exec(expr);
      if (match == null) return before;

      while (match != null) {
        var comp = match[1].startsWith('[') ? match[2].gsub('\\\\]', ']') : match[1];
        ctx = ctx[comp];
        if (null == ctx || '' == match[3]) break;
        expr = expr.substring('[' == match[3] ? match[1].length : match[0].length);
        match = pattern.exec(expr);
      }

      return before + String.interpret(ctx);
    }.bind(this));
  }
});
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;

var $break = { };

var Enumerable = {
  each: function(iterator, context) {
    var index = 0;
    iterator = iterator.bind(context);
    try {
      this._each(function(value) {
        iterator(value, index++);
      });
    } catch (e) {
      if (e != $break) throw e;
    }
    return this;
  },

  eachSlice: function(number, iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var index = -number, slices = [], array = this.toArray();
    while ((index += number) < array.length)
      slices.push(array.slice(index, index+number));
    return slices.collect(iterator, context);
  },

  all: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var result = true;
    this.each(function(value, index) {
      result = result && !!iterator(value, index);
      if (!result) throw $break;
    });
    return result;
  },

  any: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var result = false;
    this.each(function(value, index) {
      if (result = !!iterator(value, index))
        throw $break;
    });
    return result;
  },

  collect: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var results = [];
    this.each(function(value, index) {
      results.push(iterator(value, index));
    });
    return results;
  },

  detect: function(iterator, context) {
    iterator = iterator.bind(context);
    var result;
    this.each(function(value, index) {
      if (iterator(value, index)) {
        result = value;
        throw $break;
      }
    });
    return result;
  },

  findAll: function(iterator, context) {
    iterator = iterator.bind(context);
    var results = [];
    this.each(function(value, index) {
      if (iterator(value, index))
        results.push(value);
    });
    return results;
  },

  grep: function(filter, iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var results = [];

    if (Object.isString(filter))
      filter = new RegExp(filter);

    this.each(function(value, index) {
      if (filter.match(value))
        results.push(iterator(value, index));
    });
    return results;
  },

  include: function(object) {
    if (Object.isFunction(this.indexOf))
      if (this.indexOf(object) != -1) return true;

    var found = false;
    this.each(function(value) {
      if (value == object) {
        found = true;
        throw $break;
      }
    });
    return found;
  },

  inGroupsOf: function(number, fillWith) {
    fillWith = fillWith === undefined ? null : fillWith;
    return this.eachSlice(number, function(slice) {
      while(slice.length < number) slice.push(fillWith);
      return slice;
    });
  },

  inject: function(memo, iterator, context) {
    iterator = iterator.bind(context);
    this.each(function(value, index) {
      memo = iterator(memo, value, index);
    });
    return memo;
  },

  invoke: function(method) {
    var args = $A(arguments).slice(1);
    return this.map(function(value) {
      return value[method].apply(value, args);
    });
  },

  max: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var result;
    this.each(function(value, index) {
      value = iterator(value, index);
      if (result == undefined || value >= result)
        result = value;
    });
    return result;
  },

  min: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var result;
    this.each(function(value, index) {
      value = iterator(value, index);
      if (result == undefined || value < result)
        result = value;
    });
    return result;
  },

  partition: function(iterator, context) {
    iterator = iterator ? iterator.bind(context) : Prototype.K;
    var trues = [], falses = [];
    this.each(function(value, index) {
      (iterator(value, index) ?
        trues : falses).push(value);
    });
    return [trues, falses];
  },

  pluck: function(property) {
    var results = [];
    this.each(function(value) {
      results.push(value[property]);
    });
    return results;
  },

  reject: function(iterator, context) {
    iterator = iterator.bind(context);
    var results = [];
    this.each(function(value, index) {
      if (!iterator(value, index))
        results.push(value);
    });
    return results;
  },

  sortBy: function(iterator, context) {
    iterator = iterator.bind(context);
    return this.map(function(value, index) {
      return {value: value, criteria: iterator(value, index)};
    }).sort(function(left, right) {
      var a = left.criteria, b = right.criteria;
      return a < b ? -1 : a > b ? 1 : 0;
    }).pluck('value');
  },

  toArray: function() {
    return this.map();
  },

  zip: function() {
    var iterator = Prototype.K, args = $A(arguments);
    if (Object.isFunction(args.last()))
      iterator = args.pop();

    var collections = [this].concat(args).map($A);
    return this.map(function(value, index) {
      return iterator(collections.pluck(index));
    });
  },

  size: function() {
    return this.toArray().length;
  },

  inspect: function() {
    return '#<Enumerable:' + this.toArray().inspect() + '>';
  }
};

Object.extend(Enumerable, {
  map:     Enumerable.collect,
  find:    Enumerable.detect,
  select:  Enumerable.findAll,
  filter:  Enumerable.findAll,
  member:  Enumerable.include,
  entries: Enumerable.toArray,
  every:   Enumerable.all,
  some:    Enumerable.any
});
function $A(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) return iterable.toArray();
  var length = iterable.length, results = new Array(length);
  while (length--) results[length] = iterable[length];
  return results;
}

if (Prototype.Browser.WebKit) {
  function $A(iterable) {
    if (!iterable) return [];
    if (!(Object.isFunction(iterable) && iterable == '[object NodeList]') &&
        iterable.toArray) return iterable.toArray();
    var length = iterable.length, results = new Array(length);
    while (length--) results[length] = iterable[length];
    return results;
  }
}

Array.from = $A;

Object.extend(Array.prototype, Enumerable);

if (!Array.prototype._reverse) Array.prototype._reverse = Array.prototype.reverse;

Object.extend(Array.prototype, {
  _each: function(iterator) {
    for (var i = 0, length = this.length; i < length; i++)
      iterator(this[i]);
  },

  clear: function() {
    this.length = 0;
    return this;
  },

  first: function() {
    return this[0];
  },

  last: function() {
    return this[this.length - 1];
  },

  compact: function() {
    return this.select(function(value) {
      return value != null;
    });
  },

  flatten: function() {
    return this.inject([], function(array, value) {
      return array.concat(Object.isArray(value) ?
        value.flatten() : [value]);
    });
  },

  without: function() {
    var values = $A(arguments);
    return this.select(function(value) {
      return !values.include(value);
    });
  },

  reverse: function(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  },

  reduce: function() {
    return this.length > 1 ? this : this[0];
  },

  uniq: function(sorted) {
    return this.inject([], function(array, value, index) {
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        array.push(value);
      return array;
    });
  },

  intersect: function(array) {
    return this.uniq().findAll(function(item) {
      return array.detect(function(value) { return item === value });
    });
  },

  clone: function() {
    return [].concat(this);
  },

  size: function() {
    return this.length;
  },

  inspect: function() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  },

  toJSON: function() {
    var results = [];
    this.each(function(object) {
      var value = Object.toJSON(object);
      if (value !== undefined) results.push(value);
    });
    return '[' + results.join(', ') + ']';
  }
});

// use native browser JS 1.6 implementation if available
if (Object.isFunction(Array.prototype.forEach))
  Array.prototype._each = Array.prototype.forEach;

if (!Array.prototype.indexOf) Array.prototype.indexOf = function(item, i) {
  i || (i = 0);
  var length = this.length;
  if (i < 0) i = length + i;
  for (; i < length; i++)
    if (this[i] === item) return i;
  return -1;
};

if (!Array.prototype.lastIndexOf) Array.prototype.lastIndexOf = function(item, i) {
  i = isNaN(i) ? this.length : (i < 0 ? this.length + i : i) + 1;
  var n = this.slice(0, i).reverse().indexOf(item);
  return (n < 0) ? n : i - n - 1;
};

Array.prototype.toArray = Array.prototype.clone;

function $w(string) {
  if (!Object.isString(string)) return [];
  string = string.strip();
  return string ? string.split(/\s+/) : [];
}

if (Prototype.Browser.Opera){
  Array.prototype.concat = function() {
    var array = [];
    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
    for (var i = 0, length = arguments.length; i < length; i++) {
      if (Object.isArray(arguments[i])) {
        for (var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
          array.push(arguments[i][j]);
      } else {
        array.push(arguments[i]);
      }
    }
    return array;
  };
}
Object.extend(Number.prototype, {
  toColorPart: function() {
    return this.toPaddedString(2, 16);
  },

  succ: function() {
    return this + 1;
  },

  times: function(iterator) {
    $R(0, this, true).each(iterator);
    return this;
  },

  toPaddedString: function(length, radix) {
    var string = this.toString(radix || 10);
    return '0'.times(length - string.length) + string;
  },

  toJSON: function() {
    return isFinite(this) ? this.toString() : 'null';
  }
});

$w('abs round ceil floor').each(function(method){
  Number.prototype[method] = Math[method].methodize();
});
function $H(object) {
  return new Hash(object);
};

var Hash = Class.create(Enumerable, (function() {
  if (function() {
    var i = 0, Test = function(value) { this.key = value };
    Test.prototype.key = 'foo';
    for (var property in new Test('bar')) i++;
    return i > 1;
  }()) {
    function each(iterator) {
      var cache = [];
      for (var key in this._object) {
        var value = this._object[key];
        if (cache.include(key)) continue;
        cache.push(key);
        var pair = [key, value];
        pair.key = key;
        pair.value = value;
        iterator(pair);
      }
    }
  } else {
    function each(iterator) {
      for (var key in this._object) {
        var value = this._object[key], pair = [key, value];
        pair.key = key;
        pair.value = value;
        iterator(pair);
      }
    }
  }

  function toQueryPair(key, value) {
    if (Object.isUndefined(value)) return key;
    return key + '=' + encodeURIComponent(String.interpret(value));
  }

  return {
    initialize: function(object) {
      this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
    },

    _each: each,

    set: function(key, value) {
      return this._object[key] = value;
    },

    get: function(key) {
      return this._object[key];
    },

    unset: function(key) {
      var value = this._object[key];
      delete this._object[key];
      return value;
    },

    toObject: function() {
      return Object.clone(this._object);
    },

    keys: function() {
      return this.pluck('key');
    },

    values: function() {
      return this.pluck('value');
    },

    index: function(value) {
      var match = this.detect(function(pair) {
        return pair.value === value;
      });
      return match && match.key;
    },

    merge: function(object) {
      return this.clone().update(object);
    },

    update: function(object) {
      return new Hash(object).inject(this, function(result, pair) {
        result.set(pair.key, pair.value);
        return result;
      });
    },

    toQueryString: function() {
      return this.map(function(pair) {
        var key = encodeURIComponent(pair.key), values = pair.value;

        if (values && typeof values == 'object') {
          if (Object.isArray(values))
            return values.map(toQueryPair.curry(key)).join('&');
        }
        return toQueryPair(key, values);
      }).join('&');
    },

    inspect: function() {
      return '#<Hash:{' + this.map(function(pair) {
        return pair.map(Object.inspect).join(': ');
      }).join(', ') + '}>';
    },

    toJSON: function() {
      return Object.toJSON(this.toObject());
    },

    clone: function() {
      return new Hash(this);
    }
  }
})());

Hash.prototype.toTemplateReplacements = Hash.prototype.toObject;
Hash.from = $H;
var ObjectRange = Class.create(Enumerable, {
  initialize: function(start, end, exclusive) {
    this.start = start;
    this.end = end;
    this.exclusive = exclusive;
  },

  _each: function(iterator) {
    var value = this.start;
    while (this.include(value)) {
      iterator(value);
      value = value.succ();
    }
  },

  include: function(value) {
    if (value < this.start)
      return false;
    if (this.exclusive)
      return value < this.end;
    return value <= this.end;
  }
});

var $R = function(start, end, exclusive) {
  return new ObjectRange(start, end, exclusive);
};

var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new XMLHttpRequest()},
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')}
    ) || false;
  },

  activeRequestCount: 0
};

Ajax.Responders = {
  responders: [],

  _each: function(iterator) {
    this.responders._each(iterator);
  },

  register: function(responder) {
    if (!this.include(responder))
      this.responders.push(responder);
  },

  unregister: function(responder) {
    this.responders = this.responders.without(responder);
  },

  dispatch: function(callback, request, transport, json) {
    this.each(function(responder) {
      if (Object.isFunction(responder[callback])) {
        try {
          responder[callback].apply(responder, [request, transport, json]);
        } catch (e) { }
      }
    });
  }
};

Object.extend(Ajax.Responders, Enumerable);

Ajax.Responders.register({
  onCreate:   function() { Ajax.activeRequestCount++ },
  onComplete: function() { Ajax.activeRequestCount-- }
});

Ajax.Base = Class.create({
  initialize: function(options) {
    this.options = {
      method:       'post',
      asynchronous: true,
      contentType:  'application/x-www-form-urlencoded',
      encoding:     'UTF-8',
      parameters:   '',
      evalJSON:     true,
      evalJS:       true
    };
    Object.extend(this.options, options || { });

    this.options.method = this.options.method.toLowerCase();
    if (Object.isString(this.options.parameters))
      this.options.parameters = this.options.parameters.toQueryParams();
  }
});

Ajax.Request = Class.create(Ajax.Base, {
  _complete: false,

  initialize: function($super, url, options) {
    $super(options);
    this.transport = Ajax.getTransport();
    this.request(url);
  },

  request: function(url) {
    this.url = url;
    this.method = this.options.method;
    var params = Object.clone(this.options.parameters);

    if (!['get', 'post'].include(this.method)) {
      // simulate other verbs over post
      params['_method'] = this.method;
      this.method = 'post';
    }

    this.parameters = params;

    if (params = Object.toQueryString(params)) {
      // when GET, append parameters to URL
      if (this.method == 'get')
        this.url += (this.url.include('?') ? '&' : '?') + params;
      else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
        params += '&_=';
    }

    try {
      var response = new Ajax.Response(this);
      if (this.options.onCreate) this.options.onCreate(response);
      Ajax.Responders.dispatch('onCreate', this, response);

      this.transport.open(this.method.toUpperCase(), this.url,
        this.options.asynchronous);

      if (this.options.asynchronous) this.respondToReadyState.bind(this).defer(1);

      this.transport.onreadystatechange = this.onStateChange.bind(this);
      this.setRequestHeaders();

      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
      this.transport.send(this.body);

      /* Force Firefox to handle ready state 4 for synchronous requests */
      if (!this.options.asynchronous && this.transport.overrideMimeType)
        this.onStateChange();

    }
    catch (e) {
      this.dispatchException(e);
    }
  },

  onStateChange: function() {
    var readyState = this.transport.readyState;
    if (readyState > 1 && !((readyState == 4) && this._complete))
      this.respondToReadyState(this.transport.readyState);
  },

  setRequestHeaders: function() {
    var headers = {
      'X-Requested-With': 'XMLHttpRequest',
      'X-Prototype-Version': Prototype.Version,
      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
    };

    if (this.method == 'post') {
      headers['Content-type'] = this.options.contentType +
        (this.options.encoding ? '; charset=' + this.options.encoding : '');

      /* Force "Connection: close" for older Mozilla browsers to work
       * around a bug where XMLHttpRequest sends an incorrect
       * Content-length header. See Mozilla Bugzilla #246651.
       */
      if (this.transport.overrideMimeType &&
          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
            headers['Connection'] = 'close';
    }

    // user-defined headers
    if (typeof this.options.requestHeaders == 'object') {
      var extras = this.options.requestHeaders;

      if (Object.isFunction(extras.push))
        for (var i = 0, length = extras.length; i < length; i += 2)
          headers[extras[i]] = extras[i+1];
      else
        $H(extras).each(function(pair) { headers[pair.key] = pair.value });
    }

    for (var name in headers)
      this.transport.setRequestHeader(name, headers[name]);
  },

  success: function() {
    var status = this.getStatus();
    return !status || (status >= 200 && status < 300);
  },

  getStatus: function() {
    try {
      return this.transport.status || 0;
    } catch (e) { return 0 }
  },

  respondToReadyState: function(readyState) {
    var state = Ajax.Request.Events[readyState], response = new Ajax.Response(this);

    if (state == 'Complete') {
      try {
        this._complete = true;
        (this.options['on' + response.status]
         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
         || Prototype.emptyFunction)(response, response.headerJSON);
      } catch (e) {
        this.dispatchException(e);
      }

      var contentType = response.getHeader('Content-type');
      if (this.options.evalJS == 'force'
          || (this.options.evalJS && contentType
          && contentType.match(/^\s*(text|application)\/(x-)?(java|ecma)script(;.*)?\s*$/i)))
        this.evalResponse();
    }

    try {
      (this.options['on' + state] || Prototype.emptyFunction)(response, response.headerJSON);
      Ajax.Responders.dispatch('on' + state, this, response, response.headerJSON);
    } catch (e) {
      this.dispatchException(e);
    }

    if (state == 'Complete') {
      // avoid memory leak in MSIE: clean up
      this.transport.onreadystatechange = Prototype.emptyFunction;
    }
  },

  getHeader: function(name) {
    try {
      return this.transport.getResponseHeader(name);
    } catch (e) { return null }
  },

  evalResponse: function() {
    try {
      return eval((this.transport.responseText || '').unfilterJSON());
    } catch (e) {
      this.dispatchException(e);
    }
  },

  dispatchException: function(exception) {
    (this.options.onException || Prototype.emptyFunction)(this, exception);
    Ajax.Responders.dispatch('onException', this, exception);
  }
});

Ajax.Request.Events =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Response = Class.create({
  initialize: function(request){
    this.request = request;
    var transport  = this.transport  = request.transport,
        readyState = this.readyState = transport.readyState;

    if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
      this.status       = this.getStatus();
      this.statusText   = this.getStatusText();
      this.responseText = String.interpret(transport.responseText);
      this.headerJSON   = this._getHeaderJSON();
    }

    if(readyState == 4) {
      var xml = transport.responseXML;
      this.responseXML  = xml === undefined ? null : xml;
      this.responseJSON = this._getResponseJSON();
    }
  },

  status:      0,
  statusText: '',

  getStatus: Ajax.Request.prototype.getStatus,

  getStatusText: function() {
    try {
      return this.transport.statusText || '';
    } catch (e) { return '' }
  },

  getHeader: Ajax.Request.prototype.getHeader,

  getAllHeaders: function() {
    try {
      return this.getAllResponseHeaders();
    } catch (e) { return null }
  },

  getResponseHeader: function(name) {
    return this.transport.getResponseHeader(name);
  },

  getAllResponseHeaders: function() {
    return this.transport.getAllResponseHeaders();
  },

  _getHeaderJSON: function() {
    var json = this.getHeader('X-JSON');
    if (!json) return null;
    json = decodeURIComponent(escape(json));
    try {
      return json.evalJSON(this.request.options.sanitizeJSON);
    } catch (e) {
      this.request.dispatchException(e);
    }
  },

  _getResponseJSON: function() {
    var options = this.request.options;
    if (!options.evalJSON || (options.evalJSON != 'force' &&
      !(this.getHeader('Content-type') || '').include('application/json')))
        return null;
    try {
      return this.transport.responseText.evalJSON(options.sanitizeJSON);
    } catch (e) {
      this.request.dispatchException(e);
    }
  }
});

Ajax.Updater = Class.create(Ajax.Request, {
  initialize: function($super, container, url, options) {
    this.container = {
      success: (container.success || container),
      failure: (container.failure || (container.success ? null : container))
    };

    options = options || { };
    var onComplete = options.onComplete;
    options.onComplete = (function(response, param) {
      this.updateContent(response.responseText);
      if (Object.isFunction(onComplete)) onComplete(response, param);
    }).bind(this);

    $super(url, options);
  },

  updateContent: function(responseText) {
    var receiver = this.container[this.success() ? 'success' : 'failure'],
        options = this.options;

    if (!options.evalScripts) responseText = responseText.stripScripts();

    if (receiver = $(receiver)) {
      if (options.insertion) {
        if (Object.isString(options.insertion)) {
          var insertion = { }; insertion[options.insertion] = responseText;
          receiver.insert(insertion);
        }
        else options.insertion(receiver, responseText);
      }
      else receiver.update(responseText);
    }

    if (this.success()) {
      if (this.onComplete) this.onComplete.bind(this).defer();
    }
  }
});

Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
  initialize: function($super, container, url, options) {
    $super(options);
    this.onComplete = this.options.onComplete;

    this.frequency = (this.options.frequency || 2);
    this.decay = (this.options.decay || 1);

    this.updater = { };
    this.container = container;
    this.url = url;

    this.start();
  },

  start: function() {
    this.options.onComplete = this.updateComplete.bind(this);
    this.onTimerEvent();
  },

  stop: function() {
    this.updater.options.onComplete = undefined;
    clearTimeout(this.timer);
    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
  },

  updateComplete: function(response) {
    if (this.options.decay) {
      this.decay = (response.responseText == this.lastText ?
        this.decay * this.options.decay : 1);

      this.lastText = response.responseText;
    }
    this.timer = this.onTimerEvent.bind(this).delay(this.decay * this.frequency);
  },

  onTimerEvent: function() {
    this.updater = new Ajax.Updater(this.container, this.url, this.options);
  }
});
function $(element) {
  if (arguments.length > 1) {
    for (var i = 0, elements = [], length = arguments.length; i < length; i++)
      elements.push($(arguments[i]));
    return elements;
  }
  if (Object.isString(element))
    element = document.getElementById(element);
  return Element.extend(element);
}

if (Prototype.BrowserFeatures.XPath) {
  document._getElementsByXPath = function(expression, parentElement) {
    var results = [];
    var query = document.evaluate(expression, $(parentElement) || document,
      null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
    for (var i = 0, length = query.snapshotLength; i < length; i++)
      results.push(Element.extend(query.snapshotItem(i)));
    return results;
  };
}

/*--------------------------------------------------------------------------*/

if (!window.Node) var Node = { };

if (!Node.ELEMENT_NODE) {
  // DOM level 2 ECMAScript Language Binding
  Object.extend(Node, {
    ELEMENT_NODE: 1,
    ATTRIBUTE_NODE: 2,
    TEXT_NODE: 3,
    CDATA_SECTION_NODE: 4,
    ENTITY_REFERENCE_NODE: 5,
    ENTITY_NODE: 6,
    PROCESSING_INSTRUCTION_NODE: 7,
    COMMENT_NODE: 8,
    DOCUMENT_NODE: 9,
    DOCUMENT_TYPE_NODE: 10,
    DOCUMENT_FRAGMENT_NODE: 11,
    NOTATION_NODE: 12
  });
}

(function() {
  var element = this.Element;
  this.Element = function(tagName, attributes) {
    attributes = attributes || { };
    tagName = tagName.toLowerCase();
    var cache = Element.cache;
    if (Prototype.Browser.IE && attributes.name) {
      tagName = '<' + tagName + ' name="' + attributes.name + '">';
      delete attributes.name;
      return Element.writeAttribute(document.createElement(tagName), attributes);
    }
    if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
    return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
  };
  Object.extend(this.Element, element || { });
}).call(window);

Element.cache = { };

Element.Methods = {
  visible: function(element) {
    return $(element).style.display != 'none';
  },

  toggle: function(element) {
    element = $(element);
    Element[Element.visible(element) ? 'hide' : 'show'](element);
    return element;
  },

  hide: function(element) {
    $(element).style.display = 'none';
    return element;
  },

  show: function(element) {
    $(element).style.display = '';
    return element;
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
    return element;
  },

  update: function(element, content) {
    element = $(element);
    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) return element.update().insert(content);
    content = Object.toHTML(content);
    element.innerHTML = content.stripScripts();
    content.evalScripts.bind(content).defer();
    return element;
  },

  replace: function(element, content) {
    element = $(element);
    if (content && content.toElement) content = content.toElement();
    else if (!Object.isElement(content)) {
      content = Object.toHTML(content);
      var range = element.ownerDocument.createRange();
      range.selectNode(element);
      content.evalScripts.bind(content).defer();
      content = range.createContextualFragment(content.stripScripts());
    }
    element.parentNode.replaceChild(content, element);
    return element;
  },

  insert: function(element, insertions) {
    element = $(element);

    if (Object.isString(insertions) || Object.isNumber(insertions) ||
        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
          insertions = {bottom:insertions};

    var content, t, range;

    for (position in insertions) {
      content  = insertions[position];
      position = position.toLowerCase();
      t = Element._insertionTranslations[position];

      if (content && content.toElement) content = content.toElement();
      if (Object.isElement(content)) {
        t.insert(element, content);
        continue;
      }

      content = Object.toHTML(content);

      range = element.ownerDocument.createRange();
      t.initializeRange(element, range);
      t.insert(element, range.createContextualFragment(content.stripScripts()));

      content.evalScripts.bind(content).defer();
    }

    return element;
  },

  wrap: function(element, wrapper, attributes) {
    element = $(element);
    if (Object.isElement(wrapper))
      $(wrapper).writeAttribute(attributes || { });
    else if (Object.isString(wrapper)) wrapper = new Element(wrapper, attributes);
    else wrapper = new Element('div', wrapper);
    if (element.parentNode)
      element.parentNode.replaceChild(wrapper, element);
    wrapper.appendChild(element);
    return wrapper;
  },

  inspect: function(element) {
    element = $(element);
    var result = '<' + element.tagName.toLowerCase();
    $H({'id': 'id', 'className': 'class'}).each(function(pair) {
      var property = pair.first(), attribute = pair.last();
      var value = (element[property] || '').toString();
      if (value) result += ' ' + attribute + '=' + value.inspect(true);
    });
    return result + '>';
  },

  recursivelyCollect: function(element, property) {
    element = $(element);
    var elements = [];
    while (element = element[property])
      if (element.nodeType == 1)
        elements.push(Element.extend(element));
    return elements;
  },

  ancestors: function(element) {
    return $(element).recursivelyCollect('parentNode');
  },

  descendants: function(element) {
    return $A($(element).getElementsByTagName('*')).each(Element.extend);
  },

  firstDescendant: function(element) {
    element = $(element).firstChild;
    while (element && element.nodeType != 1) element = element.nextSibling;
    return $(element);
  },

  immediateDescendants: function(element) {
    if (!(element = $(element).firstChild)) return [];
    while (element && element.nodeType != 1) element = element.nextSibling;
    if (element) return [element].concat($(element).nextSiblings());
    return [];
  },

  previousSiblings: function(element) {
    return $(element).recursivelyCollect('previousSibling');
  },

  nextSiblings: function(element) {
    return $(element).recursivelyCollect('nextSibling');
  },

  siblings: function(element) {
    element = $(element);
    return element.previousSiblings().reverse().concat(element.nextSiblings());
  },

  match: function(element, selector) {
    if (Object.isString(selector))
      selector = new Selector(selector);
    return selector.match($(element));
  },

  up: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(element.parentNode);
    var ancestors = element.ancestors();
    return expression ? Selector.findElement(ancestors, expression, index) :
      ancestors[index || 0];
  },

  down: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return element.firstDescendant();
    var descendants = element.descendants();
    return expression ? Selector.findElement(descendants, expression, index) :
      descendants[index || 0];
  },

  previous: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
    var previousSiblings = element.previousSiblings();
    return expression ? Selector.findElement(previousSiblings, expression, index) :
      previousSiblings[index || 0];
  },

  next: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
    var nextSiblings = element.nextSiblings();
    return expression ? Selector.findElement(nextSiblings, expression, index) :
      nextSiblings[index || 0];
  },

  select: function() {
    var args = $A(arguments), element = $(args.shift());
    return Selector.findChildElements(element, args);
  },

  adjacent: function() {
    var args = $A(arguments), element = $(args.shift());
    return Selector.findChildElements(element.parentNode, args).without(element);
  },

  identify: function(element) {
    element = $(element);
    var id = element.readAttribute('id'), self = arguments.callee;
    if (id) return id;
    do { id = 'anonymous_element_' + self.counter++ } while ($(id));
    element.writeAttribute('id', id);
    return id;
  },

  readAttribute: function(element, name) {
    element = $(element);
    if (Prototype.Browser.IE) {
      var t = Element._attributeTranslations.read;
      if (t.values[name]) return t.values[name](element, name);
      if (t.names[name]) name = t.names[name];
      if (name.include(':')) {
        return (!element.attributes || !element.attributes[name]) ? null :
         element.attributes[name].value;
      }
    }
    return element.getAttribute(name);
  },

  writeAttribute: function(element, name, value) {
    element = $(element);
    var attributes = { }, t = Element._attributeTranslations.write;

    if (typeof name == 'object') attributes = name;
    else attributes[name] = value === undefined ? true : value;

    for (var attr in attributes) {
      var name = t.names[attr] || attr, value = attributes[attr];
      if (t.values[attr]) name = t.values[attr](element, value);
      if (value === false || value === null)
        element.removeAttribute(name);
      else if (value === true)
        element.setAttribute(name, name);
      else element.setAttribute(name, value);
    }
    return element;
  },

  getHeight: function(element) {
    return $(element).getDimensions().height;
  },

  getWidth: function(element) {
    return $(element).getDimensions().width;
  },

  classNames: function(element) {
    return new Element.ClassNames(element);
  },

  hasClassName: function(element, className) {
    if (!(element = $(element))) return;
    var elementClassName = element.className;
    return (elementClassName.length > 0 && (elementClassName == className ||
      new RegExp("(^|\\s)" + className + "(\\s|$)").test(elementClassName)));
  },

  addClassName: function(element, className) {
    if (!(element = $(element))) return;
    if (!element.hasClassName(className))
      element.className += (element.className ? ' ' : '') + className;
    return element;
  },

  removeClassName: function(element, className) {
    if (!(element = $(element))) return;
    element.className = element.className.replace(
      new RegExp("(^|\\s+)" + className + "(\\s+|$)"), ' ').strip();
    return element;
  },

  toggleClassName: function(element, className) {
    if (!(element = $(element))) return;
    return element[element.hasClassName(className) ?
      'removeClassName' : 'addClassName'](className);
  },

  // removes whitespace-only text node children
  cleanWhitespace: function(element) {
    element = $(element);
    var node = element.firstChild;
    while (node) {
      var nextNode = node.nextSibling;
      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
        element.removeChild(node);
      node = nextNode;
    }
    return element;
  },

  empty: function(element) {
    return $(element).innerHTML.blank();
  },

  descendantOf: function(element, ancestor) {
    element = $(element), ancestor = $(ancestor);

    if (element.compareDocumentPosition)
      return (element.compareDocumentPosition(ancestor) & 8) === 8;

    if (element.sourceIndex && !Prototype.Browser.Opera) {
      var e = element.sourceIndex, a = ancestor.sourceIndex,
       nextAncestor = ancestor.nextSibling;
      if (!nextAncestor) {
        do { ancestor = ancestor.parentNode; }
        while (!(nextAncestor = ancestor.nextSibling) && ancestor.parentNode);
      }
      if (nextAncestor) return (e > a && e < nextAncestor.sourceIndex);
    }

    while (element = element.parentNode)
      if (element == ancestor) return true;
    return false;
  },

  scrollTo: function(element) {
    element = $(element);
    var pos = element.cumulativeOffset();
    window.scrollTo(pos[0], pos[1]);
    return element;
  },

  getStyle: function(element, style) {
    element = $(element);
    style = style == 'float' ? 'cssFloat' : style.camelize();
    var value = element.style[style];
    if (!value) {
      var css = document.defaultView.getComputedStyle(element, null);
      value = css ? css[style] : null;
    }
    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
    return value == 'auto' ? null : value;
  },

  getOpacity: function(element) {
    return $(element).getStyle('opacity');
  },

  setStyle: function(element, styles) {
    element = $(element);
    var elementStyle = element.style, match;
    if (Object.isString(styles)) {
      element.style.cssText += ';' + styles;
      return styles.include('opacity') ?
        element.setOpacity(styles.match(/opacity:\s*(\d?\.?\d*)/)[1]) : element;
    }
    for (var property in styles)
      if (property == 'opacity') element.setOpacity(styles[property]);
      else
        elementStyle[(property == 'float' || property == 'cssFloat') ?
          (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
            property] = styles[property];

    return element;
  },

  setOpacity: function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;
    return element;
  },

  getDimensions: function(element) {
    element = $(element);
    var display = $(element).getStyle('display');
    if (display != 'none' && display != null) // Safari bug
      return {width: element.offsetWidth, height: element.offsetHeight};

    // All *Width and *Height properties give 0 on elements with display none,
    // so enable the element temporarily
    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    var originalDisplay = els.display;
    els.visibility = 'hidden';
    els.position = 'absolute';
    els.display = 'block';
    var originalWidth = element.clientWidth;
    var originalHeight = element.clientHeight;
    els.display = originalDisplay;
    els.position = originalPosition;
    els.visibility = originalVisibility;
    return {width: originalWidth, height: originalHeight};
  },

  makePositioned: function(element) {
    element = $(element);
    var pos = Element.getStyle(element, 'position');
    if (pos == 'static' || !pos) {
      element._madePositioned = true;
      element.style.position = 'relative';
      // Opera returns the offset relative to the positioning context, when an
      // element is position relative but top and left have not been defined
      if (window.opera) {
        element.style.top = 0;
        element.style.left = 0;
      }
    }
    return element;
  },

  undoPositioned: function(element) {
    element = $(element);
    if (element._madePositioned) {
      element._madePositioned = undefined;
      element.style.position =
        element.style.top =
        element.style.left =
        element.style.bottom =
        element.style.right = '';
    }
    return element;
  },

  makeClipping: function(element) {
    element = $(element);
    if (element._overflow) return element;
    element._overflow = Element.getStyle(element, 'overflow') || 'auto';
    if (element._overflow !== 'hidden')
      element.style.overflow = 'hidden';
    return element;
  },

  undoClipping: function(element) {
    element = $(element);
    if (!element._overflow) return element;
    element.style.overflow = element._overflow == 'auto' ? '' : element._overflow;
    element._overflow = null;
    return element;
  },

  cumulativeOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  positionedOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
      if (element) {
        if (element.tagName == 'BODY') break;
        var p = Element.getStyle(element, 'position');
        if (p == 'relative' || p == 'absolute') break;
      }
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  absolutize: function(element) {
    element = $(element);
    if (element.getStyle('position') == 'absolute') return;
    // Position.prepare(); // To be done manually by Scripty when it needs it.

    var offsets = element.positionedOffset();
    var top     = offsets[1];
    var left    = offsets[0];
    var width   = element.clientWidth;
    var height  = element.clientHeight;

    element._originalLeft   = left - parseFloat(element.style.left  || 0);
    element._originalTop    = top  - parseFloat(element.style.top || 0);
    element._originalWidth  = element.style.width;
    element._originalHeight = element.style.height;

    element.style.position = 'absolute';
    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.width  = width + 'px';
    element.style.height = height + 'px';
    return element;
  },

  relativize: function(element) {
    element = $(element);
    if (element.getStyle('position') == 'relative') return;
    // Position.prepare(); // To be done manually by Scripty when it needs it.

    element.style.position = 'relative';
    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);

    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.height = element._originalHeight;
    element.style.width  = element._originalWidth;
    return element;
  },

  cumulativeScrollOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.scrollTop  || 0;
      valueL += element.scrollLeft || 0;
      element = element.parentNode;
    } while (element);
    return Element._returnOffset(valueL, valueT);
  },

  getOffsetParent: function(element) {
    if (element.offsetParent) return $(element.offsetParent);
    if (element == document.body) return $(element);

    while ((element = element.parentNode) && element != document.body)
      if (Element.getStyle(element, 'position') != 'static')
        return $(element);

    return $(document.body);
  },

  viewportOffset: function(forElement) {
    var valueT = 0, valueL = 0;

    var element = forElement;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;

      // Safari fix
      if (element.offsetParent == document.body &&
        Element.getStyle(element, 'position') == 'absolute') break;

    } while (element = element.offsetParent);

    element = forElement;
    do {
      if (!Prototype.Browser.Opera || element.tagName == 'BODY') {
        valueT -= element.scrollTop  || 0;
        valueL -= element.scrollLeft || 0;
      }
    } while (element = element.parentNode);

    return Element._returnOffset(valueL, valueT);
  },

  clonePosition: function(element, source) {
    var options = Object.extend({
      setLeft:    true,
      setTop:     true,
      setWidth:   true,
      setHeight:  true,
      offsetTop:  0,
      offsetLeft: 0
    }, arguments[2] || { });

    // find page position of source
    source = $(source);
    var p = source.viewportOffset();

    // find coordinate system to use
    element = $(element);
    var delta = [0, 0];
    var parent = null;
    // delta [0,0] will do fine with position: fixed elements,
    // position:absolute needs offsetParent deltas
    if (Element.getStyle(element, 'position') == 'absolute') {
      parent = element.getOffsetParent();
      delta = parent.viewportOffset();
    }

    // correct by body offsets (fixes Safari)
    if (parent == document.body) {
      delta[0] -= document.body.offsetLeft;
      delta[1] -= document.body.offsetTop;
    }

    // set position
    if (options.setLeft)   element.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
    if (options.setTop)    element.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
    if (options.setWidth)  element.style.width = source.offsetWidth + 'px';
    if (options.setHeight) element.style.height = source.offsetHeight + 'px';
    return element;
  }
};

Element.Methods.identify.counter = 1;

Object.extend(Element.Methods, {
  getElementsBySelector: Element.Methods.select,
  childElements: Element.Methods.immediateDescendants
});

Element._attributeTranslations = {
  write: {
    names: {
      className: 'class',
      htmlFor:   'for'
    },
    values: { }
  }
};


if (!document.createRange || Prototype.Browser.Opera) {
  Element.Methods.insert = function(element, insertions) {
    element = $(element);

    if (Object.isString(insertions) || Object.isNumber(insertions) ||
        Object.isElement(insertions) || (insertions && (insertions.toElement || insertions.toHTML)))
          insertions = { bottom: insertions };

    var t = Element._insertionTranslations, content, position, pos, tagName;

    for (position in insertions) {
      content  = insertions[position];
      position = position.toLowerCase();
      pos      = t[position];

      if (content && content.toElement) content = content.toElement();
      if (Object.isElement(content)) {
        pos.insert(element, content);
        continue;
      }

      content = Object.toHTML(content);
      tagName = ((position == 'before' || position == 'after')
        ? element.parentNode : element).tagName.toUpperCase();

      if (t.tags[tagName]) {
        var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
        if (position == 'top' || position == 'after') fragments.reverse();
        fragments.each(pos.insert.curry(element));
      }
      else element.insertAdjacentHTML(pos.adjacency, content.stripScripts());

      content.evalScripts.bind(content).defer();
    }

    return element;
  };
}

if (Prototype.Browser.Opera) {
  Element.Methods._getStyle = Element.Methods.getStyle;
  Element.Methods.getStyle = function(element, style) {
    switch(style) {
      case 'left':
      case 'top':
      case 'right':
      case 'bottom':
        if (Element._getStyle(element, 'position') == 'static') return null;
      default: return Element._getStyle(element, style);
    }
  };
  Element.Methods._readAttribute = Element.Methods.readAttribute;
  Element.Methods.readAttribute = function(element, attribute) {
    if (attribute == 'title') return element.title;
    return Element._readAttribute(element, attribute);
  };
}

else if (Prototype.Browser.IE) {
  $w('positionedOffset getOffsetParent viewportOffset').each(function(method) {
    Element.Methods[method] = Element.Methods[method].wrap(
      function(proceed, element) {
        element = $(element);
        var position = element.getStyle('position');
        if (position != 'static') return proceed(element);
        element.setStyle({ position: 'relative' });
        var value = proceed(element);
        element.setStyle({ position: position });
        return value;
      }
    );
  });

  Element.Methods.getStyle = function(element, style) {
    element = $(element);
    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
    var value = element.style[style];
    if (!value && element.currentStyle) value = element.currentStyle[style];

    if (style == 'opacity') {
      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
        if (value[1]) return parseFloat(value[1]) / 100;
      return 1.0;
    }

    if (value == 'auto') {
      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
        return element['offset' + style.capitalize()] + 'px';
      return null;
    }
    return value;
  };

  Element.Methods.setOpacity = function(element, value) {
    function stripAlpha(filter){
      return filter.replace(/alpha\([^\)]*\)/gi,'');
    }
    element = $(element);
    var currentStyle = element.currentStyle;
    if ((currentStyle && !currentStyle.hasLayout) ||
      (!currentStyle && element.style.zoom == 'normal'))
        element.style.zoom = 1;

    var filter = element.getStyle('filter'), style = element.style;
    if (value == 1 || value === '') {
      (filter = stripAlpha(filter)) ?
        style.filter = filter : style.removeAttribute('filter');
      return element;
    } else if (value < 0.00001) value = 0;
    style.filter = stripAlpha(filter) +
      'alpha(opacity=' + (value * 100) + ')';
    return element;
  };

  Element._attributeTranslations = {
    read: {
      names: {
        'class': 'className',
        'for':   'htmlFor'
      },
      values: {
        _getAttr: function(element, attribute) {
          return element.getAttribute(attribute, 2);
        },
        _getAttrNode: function(element, attribute) {
          var node = element.getAttributeNode(attribute);
          return node ? node.value : "";
        },
        _getEv: function(element, attribute) {
          var attribute = element.getAttribute(attribute);
          return attribute ? attribute.toString().slice(23, -2) : null;
        },
        _flag: function(element, attribute) {
          return $(element).hasAttribute(attribute) ? attribute : null;
        },
        style: function(element) {
          return element.style.cssText.toLowerCase();
        },
        title: function(element) {
          return element.title;
        }
      }
    }
  };

  Element._attributeTranslations.write = {
    names: Object.clone(Element._attributeTranslations.read.names),
    values: {
      checked: function(element, value) {
        element.checked = !!value;
      },

      style: function(element, value) {
        element.style.cssText = value ? value : '';
      }
    }
  };

  Element._attributeTranslations.has = {};

  $w('colSpan rowSpan vAlign dateTime accessKey tabIndex ' +
      'encType maxLength readOnly longDesc').each(function(attr) {
    Element._attributeTranslations.write.names[attr.toLowerCase()] = attr;
    Element._attributeTranslations.has[attr.toLowerCase()] = attr;
  });

  (function(v) {
    Object.extend(v, {
      href:        v._getAttr,
      src:         v._getAttr,
      type:        v._getAttr,
      action:      v._getAttrNode,
      disabled:    v._flag,
      checked:     v._flag,
      readonly:    v._flag,
      multiple:    v._flag,
      onload:      v._getEv,
      onunload:    v._getEv,
      onclick:     v._getEv,
      ondblclick:  v._getEv,
      onmousedown: v._getEv,
      onmouseup:   v._getEv,
      onmouseover: v._getEv,
      onmousemove: v._getEv,
      onmouseout:  v._getEv,
      onfocus:     v._getEv,
      onblur:      v._getEv,
      onkeypress:  v._getEv,
      onkeydown:   v._getEv,
      onkeyup:     v._getEv,
      onsubmit:    v._getEv,
      onreset:     v._getEv,
      onselect:    v._getEv,
      onchange:    v._getEv
    });
  })(Element._attributeTranslations.read.values);
}

else if (Prototype.Browser.Gecko && /rv:1\.8\.0/.test(navigator.userAgent)) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1) ? 0.999999 :
      (value === '') ? '' : (value < 0.00001) ? 0 : value;
    return element;
  };
}

else if (Prototype.Browser.WebKit) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;

    if (value == 1)
      if(element.tagName == 'IMG' && element.width) {
        element.width++; element.width--;
      } else try {
        var n = document.createTextNode(' ');
        element.appendChild(n);
        element.removeChild(n);
      } catch (e) { }

    return element;
  };

  // Safari returns margins on body which is incorrect if the child is absolutely
  // positioned.  For performance reasons, redefine Position.cumulativeOffset for
  // KHTML/WebKit only.
  Element.Methods.cumulativeOffset = function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      if (element.offsetParent == document.body)
        if (Element.getStyle(element, 'position') == 'absolute') break;

      element = element.offsetParent;
    } while (element);

    return Element._returnOffset(valueL, valueT);
  };
}

if (Prototype.Browser.IE || Prototype.Browser.Opera) {
  // IE and Opera are missing .innerHTML support for TABLE-related and SELECT elements
  Element.Methods.update = function(element, content) {
    element = $(element);

    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) return element.update().insert(content);

    content = Object.toHTML(content);
    var tagName = element.tagName.toUpperCase();

    if (tagName in Element._insertionTranslations.tags) {
      $A(element.childNodes).each(function(node) { element.removeChild(node) });
      Element._getContentFromAnonymousElement(tagName, content.stripScripts())
        .each(function(node) { element.appendChild(node) });
    }
    else element.innerHTML = content.stripScripts();

    content.evalScripts.bind(content).defer();
    return element;
  };
}

if (document.createElement('div').outerHTML) {
  Element.Methods.replace = function(element, content) {
    element = $(element);

    if (content && content.toElement) content = content.toElement();
    if (Object.isElement(content)) {
      element.parentNode.replaceChild(content, element);
      return element;
    }

    content = Object.toHTML(content);
    var parent = element.parentNode, tagName = parent.tagName.toUpperCase();

    if (Element._insertionTranslations.tags[tagName]) {
      var nextSibling = element.next();
      var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
      parent.removeChild(element);
      if (nextSibling)
        fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
      else
        fragments.each(function(node) { parent.appendChild(node) });
    }
    else element.outerHTML = content.stripScripts();

    content.evalScripts.bind(content).defer();
    return element;
  };
}

Element._returnOffset = function(l, t) {
  var result = [l, t];
  result.left = l;
  result.top = t;
  return result;
};

Element._getContentFromAnonymousElement = function(tagName, html) {
  var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
  div.innerHTML = t[0] + html + t[1];
  t[2].times(function() { div = div.firstChild });
  return $A(div.childNodes);
};

Element._insertionTranslations = {
  before: {
    adjacency: 'beforeBegin',
    insert: function(element, node) {
      element.parentNode.insertBefore(node, element);
    },
    initializeRange: function(element, range) {
      range.setStartBefore(element);
    }
  },
  top: {
    adjacency: 'afterBegin',
    insert: function(element, node) {
      element.insertBefore(node, element.firstChild);
    },
    initializeRange: function(element, range) {
      range.selectNodeContents(element);
      range.collapse(true);
    }
  },
  bottom: {
    adjacency: 'beforeEnd',
    insert: function(element, node) {
      element.appendChild(node);
    }
  },
  after: {
    adjacency: 'afterEnd',
    insert: function(element, node) {
      element.parentNode.insertBefore(node, element.nextSibling);
    },
    initializeRange: function(element, range) {
      range.setStartAfter(element);
    }
  },
  tags: {
    TABLE:  ['<table>',                '</table>',                   1],
    TBODY:  ['<table><tbody>',         '</tbody></table>',           2],
    TR:     ['<table><tbody><tr>',     '</tr></tbody></table>',      3],
    TD:     ['<table><tbody><tr><td>', '</td></tr></tbody></table>', 4],
    SELECT: ['<select>',               '</select>',                  1]
  }
};

(function() {
  this.bottom.initializeRange = this.top.initializeRange;
  Object.extend(this.tags, {
    THEAD: this.tags.TBODY,
    TFOOT: this.tags.TBODY,
    TH:    this.tags.TD
  });
}).call(Element._insertionTranslations);

Element.Methods.Simulated = {
  hasAttribute: function(element, attribute) {
    attribute = Element._attributeTranslations.has[attribute] || attribute;
    var node = $(element).getAttributeNode(attribute);
    return node && node.specified;
  }
};

Element.Methods.ByTag = { };

Object.extend(Element, Element.Methods);

if (!Prototype.BrowserFeatures.ElementExtensions &&
    document.createElement('div').__proto__) {
  window.HTMLElement = { };
  window.HTMLElement.prototype = document.createElement('div').__proto__;
  Prototype.BrowserFeatures.ElementExtensions = true;
}

Element.extend = (function() {
  if (Prototype.BrowserFeatures.SpecificElementExtensions)
    return Prototype.K;

  var Methods = { }, ByTag = Element.Methods.ByTag;

  var extend = Object.extend(function(element) {
    if (!element || element._extendedByPrototype ||
        element.nodeType != 1 || element == window) return element;

    var methods = Object.clone(Methods),
      tagName = element.tagName, property, value;

    // extend methods for specific tags
    if (ByTag[tagName]) Object.extend(methods, ByTag[tagName]);

    for (property in methods) {
      value = methods[property];
      if (Object.isFunction(value) && !(property in element))
        element[property] = value.methodize();
    }

    element._extendedByPrototype = Prototype.emptyFunction;
    return element;

  }, {
    refresh: function() {
      // extend methods for all tags (Safari doesn't need this)
      if (!Prototype.BrowserFeatures.ElementExtensions) {
        Object.extend(Methods, Element.Methods);
        Object.extend(Methods, Element.Methods.Simulated);
      }
    }
  });

  extend.refresh();
  return extend;
})();

Element.hasAttribute = function(element, attribute) {
  if (element.hasAttribute) return element.hasAttribute(attribute);
  return Element.Methods.Simulated.hasAttribute(element, attribute);
};

Element.addMethods = function(methods) {
  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;

  if (!methods) {
    Object.extend(Form, Form.Methods);
    Object.extend(Form.Element, Form.Element.Methods);
    Object.extend(Element.Methods.ByTag, {
      "FORM":     Object.clone(Form.Methods),
      "INPUT":    Object.clone(Form.Element.Methods),
      "SELECT":   Object.clone(Form.Element.Methods),
      "TEXTAREA": Object.clone(Form.Element.Methods)
    });
  }

  if (arguments.length == 2) {
    var tagName = methods;
    methods = arguments[1];
  }

  if (!tagName) Object.extend(Element.Methods, methods || { });
  else {
    if (Object.isArray(tagName)) tagName.each(extend);
    else extend(tagName);
  }

  function extend(tagName) {
    tagName = tagName.toUpperCase();
    if (!Element.Methods.ByTag[tagName])
      Element.Methods.ByTag[tagName] = { };
    Object.extend(Element.Methods.ByTag[tagName], methods);
  }

  function copy(methods, destination, onlyIfAbsent) {
    onlyIfAbsent = onlyIfAbsent || false;
    for (var property in methods) {
      var value = methods[property];
      if (!Object.isFunction(value)) continue;
      if (!onlyIfAbsent || !(property in destination))
        destination[property] = value.methodize();
    }
  }

  function findDOMClass(tagName) {
    var klass;
    var trans = {
      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
      "FrameSet", "IFRAME": "IFrame"
    };
    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName.capitalize() + 'Element';
    if (window[klass]) return window[klass];

    window[klass] = { };
    window[klass].prototype = document.createElement(tagName).__proto__;
    return window[klass];
  }

  if (F.ElementExtensions) {
    copy(Element.Methods, HTMLElement.prototype);
    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
  }

  if (F.SpecificElementExtensions) {
    for (var tag in Element.Methods.ByTag) {
      var klass = findDOMClass(tag);
      if (Object.isUndefined(klass)) continue;
      copy(T[tag], klass.prototype);
    }
  }

  Object.extend(Element, Element.Methods);
  delete Element.ByTag;

  if (Element.extend.refresh) Element.extend.refresh();
  Element.cache = { };
};

document.viewport = {
  getDimensions: function() {
    var dimensions = { };
    $w('width height').each(function(d) {
      var D = d.capitalize();
      dimensions[d] = self['inner' + D] ||
       (document.documentElement['client' + D] || document.body['client' + D]);
    });
    return dimensions;
  },

  getWidth: function() {
    return this.getDimensions().width;
  },

  getHeight: function() {
    return this.getDimensions().height;
  },

  getScrollOffsets: function() {
    return Element._returnOffset(
      window.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft,
      window.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop);
  }
};
/* Portions of the Selector class are derived from Jack Slocum’s DomQuery,
 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
 * license.  Please see http://www.yui-ext.com/ for more information. */

var Selector = Class.create({
  initialize: function(expression) {
    this.expression = expression.strip();
    this.compileMatcher();
  },

  compileMatcher: function() {
    // Selectors with namespaced attributes can't use the XPath version
    if (Prototype.BrowserFeatures.XPath && !(/(\[[\w-]*?:|:checked)/).test(this.expression))
      return this.compileXPathMatcher();

    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
        c = Selector.criteria, le, p, m;

    if (Selector._cache[e]) {
      this.matcher = Selector._cache[e];
      return;
    }

    this.matcher = ["this.matcher = function(root) {",
                    "var r = root, h = Selector.handlers, c = false, n;"];

    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        p = ps[i];
        if (m = e.match(p)) {
          this.matcher.push(Object.isFunction(c[i]) ? c[i](m) :
    	      new Template(c[i]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.matcher.push("return h.unique(n);\n}");
    eval(this.matcher.join('\n'));
    Selector._cache[this.expression] = this.matcher;
  },

  compileXPathMatcher: function() {
    var e = this.expression, ps = Selector.patterns,
        x = Selector.xpath, le, m;

    if (Selector._cache[e]) {
      this.xpath = Selector._cache[e]; return;
    }

    this.matcher = ['.//*'];
    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        if (m = e.match(ps[i])) {
          this.matcher.push(Object.isFunction(x[i]) ? x[i](m) :
            new Template(x[i]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.xpath = this.matcher.join('');
    Selector._cache[this.expression] = this.xpath;
  },

  findElements: function(root) {
    root = root || document;
    if (this.xpath) return document._getElementsByXPath(this.xpath, root);
    return this.matcher(root);
  },

  match: function(element) {
    this.tokens = [];

    var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
    var le, p, m;

    while (e && le !== e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        p = ps[i];
        if (m = e.match(p)) {
          // use the Selector.assertions methods unless the selector
          // is too complex.
          if (as[i]) {
            this.tokens.push([i, Object.clone(m)]);
            e = e.replace(m[0], '');
          } else {
            // reluctantly do a document-wide search
            // and look for a match in the array
            return this.findElements(document).include(element);
          }
        }
      }
    }

    var match = true, name, matches;
    for (var i = 0, token; token = this.tokens[i]; i++) {
      name = token[0], matches = token[1];
      if (!Selector.assertions[name](element, matches)) {
        match = false; break;
      }
    }

    return match;
  },

  toString: function() {
    return this.expression;
  },

  inspect: function() {
    return "#<Selector:" + this.expression.inspect() + ">";
  }
});

Object.extend(Selector, {
  _cache: { },

  xpath: {
    descendant:   "//*",
    child:        "/*",
    adjacent:     "/following-sibling::*[1]",
    laterSibling: '/following-sibling::*',
    tagName:      function(m) {
      if (m[1] == '*') return '';
      return "[local-name()='" + m[1].toLowerCase() +
             "' or local-name()='" + m[1].toUpperCase() + "']";
    },
    className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
    id:           "[@id='#{1}']",
    attrPresence: "[@#{1}]",
    attr: function(m) {
      m[3] = m[5] || m[6];
      return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
    },
    pseudo: function(m) {
      var h = Selector.xpath.pseudos[m[1]];
      if (!h) return '';
      if (Object.isFunction(h)) return h(m);
      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
    },
    operators: {
      '=':  "[@#{1}='#{3}']",
      '!=': "[@#{1}!='#{3}']",
      '^=': "[starts-with(@#{1}, '#{3}')]",
      '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
      '*=': "[contains(@#{1}, '#{3}')]",
      '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
      '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
    },
    pseudos: {
      'first-child': '[not(preceding-sibling::*)]',
      'last-child':  '[not(following-sibling::*)]',
      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
      'empty':       "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
      'checked':     "[@checked]",
      'disabled':    "[@disabled]",
      'enabled':     "[not(@disabled)]",
      'not': function(m) {
        var e = m[6], p = Selector.patterns,
            x = Selector.xpath, le, m, v;

        var exclusion = [];
        while (e && le != e && (/\S/).test(e)) {
          le = e;
          for (var i in p) {
            if (m = e.match(p[i])) {
              v = Object.isFunction(x[i]) ? x[i](m) : new Template(x[i]).evaluate(m);
              exclusion.push("(" + v.substring(1, v.length - 1) + ")");
              e = e.replace(m[0], '');
              break;
            }
          }
        }
        return "[not(" + exclusion.join(" and ") + ")]";
      },
      'nth-child':      function(m) {
        return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
      },
      'nth-last-child': function(m) {
        return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
      },
      'nth-of-type':    function(m) {
        return Selector.xpath.pseudos.nth("position() ", m);
      },
      'nth-last-of-type': function(m) {
        return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
      },
      'first-of-type':  function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
      },
      'last-of-type':   function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
      },
      'only-of-type':   function(m) {
        var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
      },
      nth: function(fragment, m) {
        var mm, formula = m[6], predicate;
        if (formula == 'even') formula = '2n+0';
        if (formula == 'odd')  formula = '2n+1';
        if (mm = formula.match(/^(\d+)$/)) // digit only
          return '[' + fragment + "= " + mm[1] + ']';
        if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
          if (mm[1] == "-") mm[1] = -1;
          var a = mm[1] ? Number(mm[1]) : 1;
          var b = mm[2] ? Number(mm[2]) : 0;
          predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
          "((#{fragment} - #{b}) div #{a} >= 0)]";
          return new Template(predicate).evaluate({
            fragment: fragment, a: a, b: b });
        }
      }
    }
  },

  criteria: {
    tagName:      'n = h.tagName(n, r, "#{1}", c);   c = false;',
    className:    'n = h.className(n, r, "#{1}", c); c = false;',
    id:           'n = h.id(n, r, "#{1}", c);        c = false;',
    attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
    attr: function(m) {
      m[3] = (m[5] || m[6]);
      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
    },
    pseudo: function(m) {
      if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
      return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
    },
    descendant:   'c = "descendant";',
    child:        'c = "child";',
    adjacent:     'c = "adjacent";',
    laterSibling: 'c = "laterSibling";'
  },

  patterns: {
    // combinators must be listed first
    // (and descendant needs to be last combinator)
    laterSibling: /^\s*~\s*/,
    child:        /^\s*>\s*/,
    adjacent:     /^\s*\+\s*/,
    descendant:   /^\s/,

    // selectors follow
    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
    id:           /^#([\w\-\*]+)(\b|$)/,
    className:    /^\.([\w\-\*]+)(\b|$)/,
    pseudo:       /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s)|(?=:))/,
    attrPresence: /^\[([\w]+)\]/,
    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/
  },

  // for Selector.match and Element#match
  assertions: {
    tagName: function(element, matches) {
      return matches[1].toUpperCase() == element.tagName.toUpperCase();
    },

    className: function(element, matches) {
      return Element.hasClassName(element, matches[1]);
    },

    id: function(element, matches) {
      return element.id === matches[1];
    },

    attrPresence: function(element, matches) {
      return Element.hasAttribute(element, matches[1]);
    },

    attr: function(element, matches) {
      var nodeValue = Element.readAttribute(element, matches[1]);
      return Selector.operators[matches[2]](nodeValue, matches[3]);
    }
  },

  handlers: {
    // UTILITY FUNCTIONS
    // joins two collections
    concat: function(a, b) {
      for (var i = 0, node; node = b[i]; i++)
        a.push(node);
      return a;
    },

    // marks an array of nodes for counting
    mark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node._counted = true;
      return nodes;
    },

    unmark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node._counted = undefined;
      return nodes;
    },

    // mark each child node with its position (for nth calls)
    // "ofType" flag indicates whether we're indexing for nth-of-type
    // rather than nth-child
    index: function(parentNode, reverse, ofType) {
      parentNode._counted = true;
      if (reverse) {
        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
          var node = nodes[i];
          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
        }
      } else {
        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
      }
    },

    // filters out duplicates and extends all nodes
    unique: function(nodes) {
      if (nodes.length == 0) return nodes;
      var results = [], n;
      for (var i = 0, l = nodes.length; i < l; i++)
        if (!(n = nodes[i])._counted) {
          n._counted = true;
          results.push(Element.extend(n));
        }
      return Selector.handlers.unmark(results);
    },

    // COMBINATOR FUNCTIONS
    descendant: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, node.getElementsByTagName('*'));
      return results;
    },

    child: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
          if (child.nodeType == 1 && child.tagName != '!') results.push(child);
      }
      return results;
    },

    adjacent: function(nodes) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        var next = this.nextElementSibling(node);
        if (next) results.push(next);
      }
      return results;
    },

    laterSibling: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, Element.nextSiblings(node));
      return results;
    },

    nextElementSibling: function(node) {
      while (node = node.nextSibling)
	      if (node.nodeType == 1) return node;
      return null;
    },

    previousElementSibling: function(node) {
      while (node = node.previousSibling)
        if (node.nodeType == 1) return node;
      return null;
    },

    // TOKEN FUNCTIONS
    tagName: function(nodes, root, tagName, combinator) {
      tagName = tagName.toUpperCase();
      var results = [], h = Selector.handlers;
      if (nodes) {
        if (combinator) {
          // fastlane for ordinary descendant combinators
          if (combinator == "descendant") {
            for (var i = 0, node; node = nodes[i]; i++)
              h.concat(results, node.getElementsByTagName(tagName));
            return results;
          } else nodes = this[combinator](nodes);
          if (tagName == "*") return nodes;
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.tagName.toUpperCase() == tagName) results.push(node);
        return results;
      } else return root.getElementsByTagName(tagName);
    },

    id: function(nodes, root, id, combinator) {
      var targetNode = $(id), h = Selector.handlers;
      if (!targetNode) return [];
      if (!nodes && root == document) return [targetNode];
      if (nodes) {
        if (combinator) {
          if (combinator == 'child') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (targetNode.parentNode == node) return [targetNode];
          } else if (combinator == 'descendant') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Element.descendantOf(targetNode, node)) return [targetNode];
          } else if (combinator == 'adjacent') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Selector.handlers.previousElementSibling(targetNode) == node)
                return [targetNode];
          } else nodes = h[combinator](nodes);
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node == targetNode) return [targetNode];
        return [];
      }
      return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
    },

    className: function(nodes, root, className, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      return Selector.handlers.byClassName(nodes, root, className);
    },

    byClassName: function(nodes, root, className) {
      if (!nodes) nodes = Selector.handlers.descendant([root]);
      var needle = ' ' + className + ' ';
      for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
        nodeClassName = node.className;
        if (nodeClassName.length == 0) continue;
        if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
          results.push(node);
      }
      return results;
    },

    attrPresence: function(nodes, root, attr) {
      if (!nodes) nodes = root.getElementsByTagName("*");
      var results = [];
      for (var i = 0, node; node = nodes[i]; i++)
        if (Element.hasAttribute(node, attr)) results.push(node);
      return results;
    },

    attr: function(nodes, root, attr, value, operator) {
      if (!nodes) nodes = root.getElementsByTagName("*");
      var handler = Selector.operators[operator], results = [];
      for (var i = 0, node; node = nodes[i]; i++) {
        var nodeValue = Element.readAttribute(node, attr);
        if (nodeValue === null) continue;
        if (handler(nodeValue, value)) results.push(node);
      }
      return results;
    },

    pseudo: function(nodes, name, value, root, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      if (!nodes) nodes = root.getElementsByTagName("*");
      return Selector.pseudos[name](nodes, value, root);
    }
  },

  pseudos: {
    'first-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.previousElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'last-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.nextElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'only-child': function(nodes, value, root) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
          results.push(node);
      return results;
    },
    'nth-child':        function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root);
    },
    'nth-last-child':   function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true);
    },
    'nth-of-type':      function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, false, true);
    },
    'nth-last-of-type': function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true, true);
    },
    'first-of-type':    function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, false, true);
    },
    'last-of-type':     function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, true, true);
    },
    'only-of-type':     function(nodes, formula, root) {
      var p = Selector.pseudos;
      return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
    },

    // handles the an+b logic
    getIndices: function(a, b, total) {
      if (a == 0) return b > 0 ? [b] : [];
      return $R(1, total).inject([], function(memo, i) {
        if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
        return memo;
      });
    },

    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
    nth: function(nodes, formula, root, reverse, ofType) {
      if (nodes.length == 0) return [];
      if (formula == 'even') formula = '2n+0';
      if (formula == 'odd')  formula = '2n+1';
      var h = Selector.handlers, results = [], indexed = [], m;
      h.mark(nodes);
      for (var i = 0, node; node = nodes[i]; i++) {
        if (!node.parentNode._counted) {
          h.index(node.parentNode, reverse, ofType);
          indexed.push(node.parentNode);
        }
      }
      if (formula.match(/^\d+$/)) { // just a number
        formula = Number(formula);
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.nodeIndex == formula) results.push(node);
      } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
        if (m[1] == "-") m[1] = -1;
        var a = m[1] ? Number(m[1]) : 1;
        var b = m[2] ? Number(m[2]) : 0;
        var indices = Selector.pseudos.getIndices(a, b, nodes.length);
        for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
          for (var j = 0; j < l; j++)
            if (node.nodeIndex == indices[j]) results.push(node);
        }
      }
      h.unmark(nodes);
      h.unmark(indexed);
      return results;
    },

    'empty': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        // IE treats comments as element nodes
        if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
        results.push(node);
      }
      return results;
    },

    'not': function(nodes, selector, root) {
      var h = Selector.handlers, selectorType, m;
      var exclusions = new Selector(selector).findElements(root);
      h.mark(exclusions);
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node._counted) results.push(node);
      h.unmark(exclusions);
      return results;
    },

    'enabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node.disabled) results.push(node);
      return results;
    },

    'disabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.disabled) results.push(node);
      return results;
    },

    'checked': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.checked) results.push(node);
      return results;
    }
  },

  operators: {
    '=':  function(nv, v) { return nv == v; },
    '!=': function(nv, v) { return nv != v; },
    '^=': function(nv, v) { return nv.startsWith(v); },
    '$=': function(nv, v) { return nv.endsWith(v); },
    '*=': function(nv, v) { return nv.include(v); },
    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
    '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
  },

  matchElements: function(elements, expression) {
    var matches = new Selector(expression).findElements(), h = Selector.handlers;
    h.mark(matches);
    for (var i = 0, results = [], element; element = elements[i]; i++)
      if (element._counted) results.push(element);
    h.unmark(matches);
    return results;
  },

  findElement: function(elements, expression, index) {
    if (Object.isNumber(expression)) {
      index = expression; expression = false;
    }
    return Selector.matchElements(elements, expression || '*')[index || 0];
  },

  findChildElements: function(element, expressions) {
    var exprs = expressions.join(','), expressions = [];
    exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
      expressions.push(m[1].strip());
    });
    var results = [], h = Selector.handlers;
    for (var i = 0, l = expressions.length, selector; i < l; i++) {
      selector = new Selector(expressions[i].strip());
      h.concat(results, selector.findElements(element));
    }
    return (l > 1) ? h.unique(results) : results;
  }
});

function $$() {
  return Selector.findChildElements(document, $A(arguments));
}
var Form = {
  reset: function(form) {
    $(form).reset();
    return form;
  },

  serializeElements: function(elements, options) {
    if (typeof options != 'object') options = { hash: !!options };
    else if (options.hash === undefined) options.hash = true;
    var key, value, submitted = false, submit = options.submit;

    var data = elements.inject({ }, function(result, element) {
      if (!element.disabled && element.name) {
        key = element.name; value = $(element).getValue();
        if (value != null && (element.type != 'submit' || (!submitted &&
            submit !== false && (!submit || key == submit) && (submitted = true)))) {
          if (key in result) {
            // a key is already present; construct an array of values
            if (!Object.isArray(result[key])) result[key] = [result[key]];
            result[key].push(value);
          }
          else result[key] = value;
        }
      }
      return result;
    });

    return options.hash ? data : Object.toQueryString(data);
  }
};

Form.Methods = {
  serialize: function(form, options) {
    return Form.serializeElements(Form.getElements(form), options);
  },

  getElements: function(form) {
    return $A($(form).getElementsByTagName('*')).inject([],
      function(elements, child) {
        if (Form.Element.Serializers[child.tagName.toLowerCase()])
          elements.push(Element.extend(child));
        return elements;
      }
    );
  },

  getInputs: function(form, typeName, name) {
    form = $(form);
    var inputs = form.getElementsByTagName('input');

    if (!typeName && !name) return $A(inputs).map(Element.extend);

    for (var i = 0, matchingInputs = [], length = inputs.length; i < length; i++) {
      var input = inputs[i];
      if ((typeName && input.type != typeName) || (name && input.name != name))
        continue;
      matchingInputs.push(Element.extend(input));
    }

    return matchingInputs;
  },

  disable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('disable');
    return form;
  },

  enable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('enable');
    return form;
  },

  findFirstElement: function(form) {
    var elements = $(form).getElements().findAll(function(element) {
      return 'hidden' != element.type && !element.disabled;
    });
    var firstByIndex = elements.findAll(function(element) {
      return element.hasAttribute('tabIndex') && element.tabIndex >= 0;
    }).sortBy(function(element) { return element.tabIndex }).first();

    return firstByIndex ? firstByIndex : elements.find(function(element) {
      return ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
    });
  },

  focusFirstElement: function(form) {
    form = $(form);
    form.findFirstElement().activate();
    return form;
  },

  request: function(form, options) {
    form = $(form), options = Object.clone(options || { });

    var params = options.parameters, action = form.readAttribute('action') || '';
    if (action.blank()) action = window.location.href;
    options.parameters = form.serialize(true);

    if (params) {
      if (Object.isString(params)) params = params.toQueryParams();
      Object.extend(options.parameters, params);
    }

    if (form.hasAttribute('method') && !options.method)
      options.method = form.method;

    return new Ajax.Request(action, options);
  }
};

/*--------------------------------------------------------------------------*/

Form.Element = {
  focus: function(element) {
    $(element).focus();
    return element;
  },

  select: function(element) {
    $(element).select();
    return element;
  }
};

Form.Element.Methods = {
  serialize: function(element) {
    element = $(element);
    if (!element.disabled && element.name) {
      var value = element.getValue();
      if (value != undefined) {
        var pair = { };
        pair[element.name] = value;
        return Object.toQueryString(pair);
      }
    }
    return '';
  },

  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    return Form.Element.Serializers[method](element);
  },

  setValue: function(element, value) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    Form.Element.Serializers[method](element, value);
    return element;
  },

  clear: function(element) {
    $(element).value = '';
    return element;
  },

  present: function(element) {
    return $(element).value != '';
  },

  activate: function(element) {
    element = $(element);
    try {
      element.focus();
      if (element.select && (element.tagName.toLowerCase() != 'input' ||
          !['button', 'reset', 'submit'].include(element.type)))
        element.select();
    } catch (e) { }
    return element;
  },

  disable: function(element) {
    element = $(element);
    element.blur();
    element.disabled = true;
    return element;
  },

  enable: function(element) {
    element = $(element);
    element.disabled = false;
    return element;
  }
};

/*--------------------------------------------------------------------------*/

var Field = Form.Element;
var $F = Form.Element.Methods.getValue;

/*--------------------------------------------------------------------------*/

Form.Element.Serializers = {
  input: function(element, value) {
    switch (element.type.toLowerCase()) {
      case 'checkbox':
      case 'radio':
        return Form.Element.Serializers.inputSelector(element, value);
      default:
        return Form.Element.Serializers.textarea(element, value);
    }
  },

  inputSelector: function(element, value) {
    if (value === undefined) return element.checked ? element.value : null;
    else element.checked = !!value;
  },

  textarea: function(element, value) {
    if (value === undefined) return element.value;
    else element.value = value;
  },

  select: function(element, index) {
    if (index === undefined)
      return this[element.type == 'select-one' ?
        'selectOne' : 'selectMany'](element);
    else {
      var opt, value, single = !Object.isArray(index);
      for (var i = 0, length = element.length; i < length; i++) {
        opt = element.options[i];
        value = this.optionValue(opt);
        if (single) {
          if (value == index) {
            opt.selected = true;
            return;
          }
        }
        else opt.selected = index.include(value);
      }
    }
  },

  selectOne: function(element) {
    var index = element.selectedIndex;
    return index >= 0 ? this.optionValue(element.options[index]) : null;
  },

  selectMany: function(element) {
    var values, length = element.length;
    if (!length) return null;

    for (var i = 0, values = []; i < length; i++) {
      var opt = element.options[i];
      if (opt.selected) values.push(this.optionValue(opt));
    }
    return values;
  },

  optionValue: function(opt) {
    // extend element because hasAttribute may not be native
    return Element.extend(opt).hasAttribute('value') ? opt.value : opt.text;
  }
};

/*--------------------------------------------------------------------------*/

Abstract.TimedObserver = Class.create(PeriodicalExecuter, {
  initialize: function($super, element, frequency, callback) {
    $super(callback, frequency);
    this.element   = $(element);
    this.lastValue = this.getValue();
  },

  execute: function() {
    var value = this.getValue();
    if (Object.isString(this.lastValue) && Object.isString(value) ?
        this.lastValue != value : String(this.lastValue) != String(value)) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  }
});

Form.Element.Observer = Class.create(Abstract.TimedObserver, {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.Observer = Class.create(Abstract.TimedObserver, {
  getValue: function() {
    return Form.serialize(this.element);
  }
});

/*--------------------------------------------------------------------------*/

Abstract.EventObserver = Class.create({
  initialize: function(element, callback) {
    this.element  = $(element);
    this.callback = callback;

    this.lastValue = this.getValue();
    if (this.element.tagName.toLowerCase() == 'form')
      this.registerFormCallbacks();
    else
      this.registerCallback(this.element);
  },

  onElementEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  },

  registerFormCallbacks: function() {
    Form.getElements(this.element).each(this.registerCallback, this);
  },

  registerCallback: function(element) {
    if (element.type) {
      switch (element.type.toLowerCase()) {
        case 'checkbox':
        case 'radio':
          Event.observe(element, 'click', this.onElementEvent.bind(this));
          break;
        default:
          Event.observe(element, 'change', this.onElementEvent.bind(this));
          break;
      }
    }
  }
});

Form.Element.EventObserver = Class.create(Abstract.EventObserver, {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.EventObserver = Class.create(Abstract.EventObserver, {
  getValue: function() {
    return Form.serialize(this.element);
  }
});
if (!window.Event) var Event = { };

Object.extend(Event, {
  KEY_BACKSPACE: 8,
  KEY_TAB:       9,
  KEY_RETURN:   13,
  KEY_ESC:      27,
  KEY_LEFT:     37,
  KEY_UP:       38,
  KEY_RIGHT:    39,
  KEY_DOWN:     40,
  KEY_DELETE:   46,
  KEY_HOME:     36,
  KEY_END:      35,
  KEY_PAGEUP:   33,
  KEY_PAGEDOWN: 34,
  KEY_INSERT:   45,

  cache: { },

  relatedTarget: function(event) {
    var element;
    switch(event.type) {
      case 'mouseover': element = event.fromElement; break;
      case 'mouseout':  element = event.toElement;   break;
      default: return null;
    }
    return Element.extend(element);
  }
});

Event.Methods = (function() {
  var isButton;

  if (Prototype.Browser.IE) {
    var buttonMap = { 0: 1, 1: 4, 2: 2 };
    isButton = function(event, code) {
      return event.button == buttonMap[code];
    };

  } else if (Prototype.Browser.WebKit) {
    isButton = function(event, code) {
      switch (code) {
        case 0: return event.which == 1 && !event.metaKey;
        case 1: return event.which == 1 && event.metaKey;
        default: return false;
      }
    };

  } else {
    isButton = function(event, code) {
      return event.which ? (event.which === code + 1) : (event.button === code);
    };
  }

  return {
    isLeftClick:   function(event) { return isButton(event, 0) },
    isMiddleClick: function(event) { return isButton(event, 1) },
    isRightClick:  function(event) { return isButton(event, 2) },

    element: function(event) {
      var node = Event.extend(event).target;
      return Element.extend(node.nodeType == Node.TEXT_NODE ? node.parentNode : node);
    },

    findElement: function(event, expression) {
      var element = Event.element(event);
      return element.match(expression) ? element : element.up(expression);
    },

    pointer: function(event) {
      return {
        x: event.pageX || (event.clientX +
          (document.documentElement.scrollLeft || document.body.scrollLeft)),
        y: event.pageY || (event.clientY +
          (document.documentElement.scrollTop || document.body.scrollTop))
      };
    },

    pointerX: function(event) { return Event.pointer(event).x },
    pointerY: function(event) { return Event.pointer(event).y },

    stop: function(event) {
      Event.extend(event);
      event.preventDefault();
      event.stopPropagation();
      event.stopped = true;
    }
  };
})();

Event.extend = (function() {
  var methods = Object.keys(Event.Methods).inject({ }, function(m, name) {
    m[name] = Event.Methods[name].methodize();
    return m;
  });

  if (Prototype.Browser.IE) {
    Object.extend(methods, {
      stopPropagation: function() { this.cancelBubble = true },
      preventDefault:  function() { this.returnValue = false },
      inspect: function() { return "[object Event]" }
    });

    return function(event) {
      if (!event) return false;
      if (event._extendedByPrototype) return event;

      event._extendedByPrototype = Prototype.emptyFunction;
      var pointer = Event.pointer(event);
      Object.extend(event, {
        target: event.srcElement,
        relatedTarget: Event.relatedTarget(event),
        pageX:  pointer.x,
        pageY:  pointer.y
      });
      return Object.extend(event, methods);
    };

  } else {
    Event.prototype = Event.prototype || document.createEvent("HTMLEvents").__proto__;
    Object.extend(Event.prototype, methods);
    return Prototype.K;
  }
})();

Object.extend(Event, (function() {
  var cache = Event.cache;

  function getEventID(element) {
    if (element._eventID) return element._eventID;
    arguments.callee.id = arguments.callee.id || 1;
    return element._eventID = ++arguments.callee.id;
  }

  function getDOMEventName(eventName) {
    if (eventName && eventName.include(':')) return "dataavailable";
    return eventName;
  }

  function getCacheForID(id) {
    return cache[id] = cache[id] || { };
  }

  function getWrappersForEventName(id, eventName) {
    var c = getCacheForID(id);
    return c[eventName] = c[eventName] || [];
  }

  function createWrapper(element, eventName, handler) {
    var id = getEventID(element);
    var c = getWrappersForEventName(id, eventName);
    if (c.pluck("handler").include(handler)) return false;

    var wrapper = function(event) {
      if (!Event || !Event.extend ||
        (event.eventName && event.eventName != eventName))
          return false;

      Event.extend(event);
      handler.call(element, event)
    };

    wrapper.handler = handler;
    c.push(wrapper);
    return wrapper;
  }

  function findWrapper(id, eventName, handler) {
    var c = getWrappersForEventName(id, eventName);
    return c.find(function(wrapper) { return wrapper.handler == handler });
  }

  function destroyWrapper(id, eventName, handler) {
    var c = getCacheForID(id);
    if (!c[eventName]) return false;
    c[eventName] = c[eventName].without(findWrapper(id, eventName, handler));
  }

  function destroyCache() {
    for (var id in cache)
      for (var eventName in cache[id])
        cache[id][eventName] = null;
  }

  if (window.attachEvent) {
    window.attachEvent("onunload", destroyCache);
  }

  return {
    observe: function(element, eventName, handler) {
      element = $(element);
      var name = getDOMEventName(eventName);

      var wrapper = createWrapper(element, eventName, handler);
      if (!wrapper) return element;

      if (element.addEventListener) {
        element.addEventListener(name, wrapper, false);
      } else {
        element.attachEvent("on" + name, wrapper);
      }

      return element;
    },

    stopObserving: function(element, eventName, handler) {
      element = $(element);
      var id = getEventID(element), name = getDOMEventName(eventName);

      if (!handler && eventName) {
        getWrappersForEventName(id, eventName).each(function(wrapper) {
          element.stopObserving(eventName, wrapper.handler);
        });
        return element;

      } else if (!eventName) {
        Object.keys(getCacheForID(id)).each(function(eventName) {
          element.stopObserving(eventName);
        });
        return element;
      }

      var wrapper = findWrapper(id, eventName, handler);
      if (!wrapper) return element;

      if (element.removeEventListener) {
        element.removeEventListener(name, wrapper, false);
      } else {
        element.detachEvent("on" + name, wrapper);
      }

      destroyWrapper(id, eventName, handler);

      return element;
    },

    fire: function(element, eventName, memo) {
      element = $(element);
      if (element == document && document.createEvent && !element.dispatchEvent)
        element = document.documentElement;

      if (document.createEvent) {
        var event = document.createEvent("HTMLEvents");
        event.initEvent("dataavailable", true, true);
      } else {
        var event = document.createEventObject();
        event.eventType = "ondataavailable";
      }

      event.eventName = eventName;
      event.memo = memo || { };

      if (document.createEvent) {
        element.dispatchEvent(event);
      } else {
        element.fireEvent(event.eventType, event);
      }

      return event;
    }
  };
})());

Object.extend(Event, Event.Methods);

Element.addMethods({
  fire:          Event.fire,
  observe:       Event.observe,
  stopObserving: Event.stopObserving
});

Object.extend(document, {
  fire:          Element.Methods.fire.methodize(),
  observe:       Element.Methods.observe.methodize(),
  stopObserving: Element.Methods.stopObserving.methodize()
});

(function() {
  /* Support for the DOMContentLoaded event is based on work by Dan Webb,
     Matthias Miller, Dean Edwards and John Resig. */

  var timer, fired = false;

  function fireContentLoadedEvent() {
    if (fired) return;
    if (timer) window.clearInterval(timer);
    document.fire("dom:loaded");
    fired = true;
  }

  if (document.addEventListener) {
    if (Prototype.Browser.WebKit) {
      timer = window.setInterval(function() {
        if (/loaded|complete/.test(document.readyState))
          fireContentLoadedEvent();
      }, 0);

      Event.observe(window, "load", fireContentLoadedEvent);

    } else {
      document.addEventListener("DOMContentLoaded",
        fireContentLoadedEvent, false);
    }

  } else {
    document.write("<script id=__onDOMContentLoaded defer src=//:><\/script>");
    $("__onDOMContentLoaded").onreadystatechange = function() {
      if (this.readyState == "complete") {
        this.onreadystatechange = null;
        fireContentLoadedEvent();
      }
    };
  }
})();
/*------------------------------- DEPRECATED -------------------------------*/

Hash.toQueryString = Object.toQueryString;

var Toggle = { display: Element.toggle };

Element.Methods.childOf = Element.Methods.descendantOf;

var Insertion = {
  Before: function(element, content) {
    return Element.insert(element, {before:content});
  },

  Top: function(element, content) {
    return Element.insert(element, {top:content});
  },

  Bottom: function(element, content) {
    return Element.insert(element, {bottom:content});
  },

  After: function(element, content) {
    return Element.insert(element, {after:content});
  }
};

var $continue = new Error('"throw $continue" is deprecated, use "return" instead');

// This should be moved to script.aculo.us; notice the deprecated methods
// further below, that map to the newer Element methods.
var Position = {
  // set to true if needed, warning: firefox performance problems
  // NOT neeeded for page scrolling, only if draggable contained in
  // scrollable elements
  includeScrollOffsets: false,

  // must be called before calling withinIncludingScrolloffset, every time the
  // page is scrolled
  prepare: function() {
    this.deltaX =  window.pageXOffset
                || document.documentElement.scrollLeft
                || document.body.scrollLeft
                || 0;
    this.deltaY =  window.pageYOffset
                || document.documentElement.scrollTop
                || document.body.scrollTop
                || 0;
  },

  // caches x/y coordinate pair to use with overlap
  within: function(element, x, y) {
    if (this.includeScrollOffsets)
      return this.withinIncludingScrolloffsets(element, x, y);
    this.xcomp = x;
    this.ycomp = y;
    this.offset = Element.cumulativeOffset(element);

    return (y >= this.offset[1] &&
            y <  this.offset[1] + element.offsetHeight &&
            x >= this.offset[0] &&
            x <  this.offset[0] + element.offsetWidth);
  },

  withinIncludingScrolloffsets: function(element, x, y) {
    var offsetcache = Element.cumulativeScrollOffset(element);

    this.xcomp = x + offsetcache[0] - this.deltaX;
    this.ycomp = y + offsetcache[1] - this.deltaY;
    this.offset = Element.cumulativeOffset(element);

    return (this.ycomp >= this.offset[1] &&
            this.ycomp <  this.offset[1] + element.offsetHeight &&
            this.xcomp >= this.offset[0] &&
            this.xcomp <  this.offset[0] + element.offsetWidth);
  },

  // within must be called directly before
  overlap: function(mode, element) {
    if (!mode) return 0;
    if (mode == 'vertical')
      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
        element.offsetHeight;
    if (mode == 'horizontal')
      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
        element.offsetWidth;
  },

  // Deprecation layer -- use newer Element methods now (1.5.2).

  cumulativeOffset: Element.Methods.cumulativeOffset,

  positionedOffset: Element.Methods.positionedOffset,

  absolutize: function(element) {
    Position.prepare();
    return Element.absolutize(element);
  },

  relativize: function(element) {
    Position.prepare();
    return Element.relativize(element);
  },

  realOffset: Element.Methods.cumulativeScrollOffset,

  offsetParent: Element.Methods.getOffsetParent,

  page: Element.Methods.viewportOffset,

  clone: function(source, target, options) {
    options = options || { };
    return Element.clonePosition(target, source, options);
  }
};

/*--------------------------------------------------------------------------*/

if (!document.getElementsByClassName) document.getElementsByClassName = function(instanceMethods){
  function iter(name) {
    return name.blank() ? null : "[contains(concat(' ', @class, ' '), ' " + name + " ')]";
  }

  instanceMethods.getElementsByClassName = Prototype.BrowserFeatures.XPath ?
  function(element, className) {
    className = className.toString().strip();
    var cond = /\s/.test(className) ? $w(className).map(iter).join('') : iter(className);
    return cond ? document._getElementsByXPath('.//*' + cond, element) : [];
  } : function(element, className) {
    className = className.toString().strip();
    var elements = [], classNames = (/\s/.test(className) ? $w(className) : null);
    if (!classNames && !className) return elements;

    var nodes = $(element).getElementsByTagName('*');
    className = ' ' + className + ' ';

    for (var i = 0, child, cn; child = nodes[i]; i++) {
      if (child.className && (cn = ' ' + child.className + ' ') && (cn.include(className) ||
          (classNames && classNames.all(function(name) {
            return !name.toString().blank() && cn.include(' ' + name + ' ');
          }))))
        elements.push(Element.extend(child));
    }
    return elements;
  };

  return function(className, parentElement) {
    return $(parentElement || document.body).getElementsByClassName(className);
  };
}(Element.Methods);

/*--------------------------------------------------------------------------*/

Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
  initialize: function(element) {
    this.element = $(element);
  },

  _each: function(iterator) {
    this.element.className.split(/\s+/).select(function(name) {
      return name.length > 0;
    })._each(iterator);
  },

  set: function(className) {
    this.element.className = className;
  },

  add: function(classNameToAdd) {
    if (this.include(classNameToAdd)) return;
    this.set($A(this).concat(classNameToAdd).join(' '));
  },

  remove: function(classNameToRemove) {
    if (!this.include(classNameToRemove)) return;
    this.set($A(this).without(classNameToRemove).join(' '));
  },

  toString: function() {
    return $A(this).join(' ');
  }
};

Object.extend(Element.ClassNames.prototype, Enumerable);

/*--------------------------------------------------------------------------*/

Element.addMethods();

// End prototype.js

function SfKernel(){}

SfKernel.RequestVariables =
{
    PresentationId : "peid",
    PlaybackTicketId : "playbackTicket"  
}

SfKernel.MediaPlayerType = 
{
	WM7 : "WM7",
	Port25: "Port25",
	SL1 : "SL1"
}

SfKernel.CursorType =
{
    Default: 0,
    Hand: 1
}

SfKernel.SlideType =
{
	Normal: 0,
	FullSize: 1,
	ThumbNail: 2,
	Unknown: 3
}

SfKernel.ScriptCmdType = 
{
	EndPresentation : "EndPresentation",
	ShowSlide : "ShowSlide",
	Pause : "Pause",
	Resume : "Resume"
}

SfKernel.SliderNotifyType =
{
	NewPosition : "NewPosition",
	DragPosition : "DragPosition",
	BeginDrag : "BeginDrag",
	EndDrag : "EndDrag"
}

SfKernel.MediaState =
{
	Undefined:		0,
    Stopped:        1,
    Paused:         2,
    Playing:        3,
    ScanForward:    4,
    ScanReverse:    5,
    Buffering:		6,
    Waiting:		7,
    MediaEnded:		8,
    Transitioning:	9,
    Ready:			10,
    Reconnecting:   11,
	Closed:			12,
	Error:			13,
	Opening:		14
}


SfKernel.PresentationPlayStatus =
{       
    NotAvailable : "NotAvailable",
    ScheduledForLive : "ScheduledForLive",
    OpenForLive : "OpenForLive",
    Live : "Live",
    LiveEnded : "LiveEnded",
    OnDemand : "OnDemand",
    LivePaused : "LivePaused"
}

SfKernel.EventType =
{
	Script : "Script",
	LivePlaybackStarted : "LivePlaybackStarted",
	PlayingFromBeginning : "PlayingFromBeginning",
	MediaOpened : "MediaOpened",
	PlayStateChanged : "PlayStateChanged",
	MediaLengthObtained : "MediaLengthObtained",
	PositionChanged : "PositionChanged",
	TimerLoop : "TimerLoop",
	SliderNotify : "SliderNotify",
	VolumeInitialized : "VolumeInitialized",
	MuteToggled : "MuteToggled",
	OptionChanged : "OptionChanged"
}

SfKernel.CommandEventId =
{
	NavigateToSlide : "NavigateToSlide",
	NavigateToTime : "NavigateToTime",
	NavigateToChapter : "NavigateToChapter",	
	Play : "Play",
	Pause : "Pause",
	Stop : "Stop",
	SetVolume : "SetVolume",
	Mute : "Mute",
	FullScreen : "FullScreen",
	SkipBack : "SkipBack",
	SkipForward : "SkipForward",
	ChangePlaybackSpeed: "ChangePlaybackSpeed"
}

SfKernel.GetQueryStringValue = function(key)
{
    var queryString = document.location.search;
    
    if(queryString.length > 1)
    {
        var nvPairs = queryString.substring(1).split('&');
        var queryParams = new Array(nvPairs.length);
        for(var i=0;i<nvPairs.length;i++)
        {
            var parts = nvPairs[i].split('=');                  
            queryParams[parts[0].toLowerCase()] = parts[1];            
        }
        
        return queryParams[key.toLowerCase()];       
    }
    return null;
}


SfKernel.EncodeHTML = function(val)
{
    if(val == null)
    {
        return val;
    }   
    val = val.toString();
    val = val.replace(/\\r/g,"");
    val = val.replace(/\\n/g, "<br/>");
    val = val.replace(/\&/g, "&amp;");
    return val;
}


SfKernel.EncodeClean = function(val)
{
    if(val == null)
    {
        return val;
    }   
    val = val.toString();
    val = val.replace(/\\r/g,"");
    val = val.replace(/\\n/g," ");
    return val;
}

SfKernel.DurationDisplayToMS = function(durationDisplay)
{
    var segments = durationDisplay.split(":");         

    for(var i = 0;i<segments.length;i++)
    {
        segments[i] = parseInt(segments[i], 10);
        if(isNaN(segments[i]))
        {     
            return 0;
        }
    }

    var timeInMS = 0;

    switch(segments.length) {
        case 3:      
            timeInMS = segments[0] * 3600000 + segments[1] * 60000 + segments[2] * 1000;
            break;
        case 2:
            timeInMS = segments[0] * 60000 + segments[1] * 1000; 
            break;
        case 1:
            timeInMS = segments[0] * 1000;
            break;
    }      

    return timeInMS;
}

SfKernel.GetDisplayDuration = function(durationInMS,padHours)
{
    if(durationInMS < 0)
    {
        return "";
    }
    var whole = durationInMS;
    
    var hours = Math.floor(whole/3600000);
    whole = whole- (hours*3600000);
    if (hours<10)
    {
        hours="0"+hours;
    }
    
    var minutes = Math.floor(whole/60000);
    whole = whole- (minutes*60000);
    var seconds = Math.floor(whole/1000);
    
    whole = whole-(seconds*1000);
    
    if (minutes<10)
    {
        minutes="0"+minutes;
    }
    if (seconds<10)
    {
        seconds="0"+seconds;
    }
    if(hours == "00" && !padHours)
    {   
        return (minutes+":"+seconds);
    }
	return (hours+":"+minutes+":"+seconds);
}


SfKernel.SliderArgs = function(notifyType, position)
{
	this.NotifyType = notifyType;
	this.Position = position;
}

SfKernel.AudioLanguageEntry = function(index, locale, displayName)
{
    this.Index = index;
    this.Locale = locale;
    this.DisplayName = displayName;
}


SfKernel.GetPlayStateName = function(state)
{
	switch (state)
	{
		case SfKernel.MediaState.Undefined:
			return Localization.MediaPlayer.State.Undefined;
		case SfKernel.MediaState.Stopped:
			return Localization.MediaPlayer.State.Stopped;
		case SfKernel.MediaState.Paused:
			return Localization.MediaPlayer.State.Paused;
		case SfKernel.MediaState.Playing:
			return Localization.MediaPlayer.State.Playing;
		case SfKernel.MediaState.ScanForward:
			return Localization.MediaPlayer.State.ScanForward;
		case SfKernel.MediaState.ScanReverse:
			return Localization.MediaPlayer.State.ScanReverse;
		case SfKernel.MediaState.Buffering:
			return Localization.MediaPlayer.State.Buffering;
		case SfKernel.MediaState.Waiting:
			return Localization.MediaPlayer.State.Waiting;
		case SfKernel.MediaState.MediaEnded:
			return Localization.MediaPlayer.State.MediaEnded;
		case SfKernel.MediaState.Transitioning:
			return Localization.MediaPlayer.State.Transitioning;
		case SfKernel.MediaState.Ready:
			return Localization.MediaPlayer.State.Ready;
		case SfKernel.MediaState.Reconnecting:
		    return Localization.MediaPlayer.State.Reconnecting;
		case SfKernel.MediaState.Closed:
			return Localization.MediaPlayer.State.Closed;
		case SfKernel.MediaState.Error:
			return Localization.MediaPlayer.State.Error;
		case SfKernel.MediaState.Opening:
			return Localization.MediaPlayer.State.Opening;
		default:
			return Localization.MediaPlayer.State.Unknown;
	}
}


Panel = function(container, containingWindow, id)
{
	this.Container = container;
	this.ContainingWindow = containingWindow;
	this.ID = id;
	this.div = null;
	this.originalDisplay = null;
}

Panel.prototype = 
{

    GetElement: function(e)
    {
        return document.getElementById(e);
    },

	GetDiv : function()
	{
		if (this.div == null)
		{
			this.div = this.GetElement(this.ID);
		}
		return this.div;
	},
	
	Hide : function()
	{
		var divElement = this.GetDiv();
		
		if (this.originalDisplay == null)
		{
			this.originalDisplay = divElement.style.display;
		}
		
		divElement.style.display = 'none';		
	},
	
	Show : function()
	{
		var divElement = this.GetDiv();
		
		var currentDisplay = divElement.style.display;
		if (currentDisplay != 'none')
		{
			this.originalDisplay = currentDisplay;
			return;
		}
		
		if (this.originalDisplay == null)
		{
			this.originalDisplay =  'none';
			divElement.style.display = '';
		}
		else
		{
			if (this.originalDisplay == 'none')
			{
				divElement.style.display = '';
			}
			else
			{
				divElement.style.display = this.originalDisplay;
			}
		}
	},
	
	IsShowing : function()
	{
		var displayVal = this.GetDiv().style.display;
		if (displayVal == 'none')
		{
			return false;	
		}
		else
		{
			return true;
		}
	}
}

SfKernel.Util = function(){}

SfKernel.Util.SetCursor = function(element, cursorType)
{
	if (cursorType == SfKernel.CursorType.Default)
	{
		element.style.cursor = 'default';
	}
	else if (cursorType == SfKernel.CursorType.Hand)
	{
		try
		{
			element.style.cursor = 'pointer';
		}
		catch (e)
		{
			element.style.cursor = 'hand';
		}
	}
}

SfKernel.Util.IsNullOrUndefined = function(obj)
{
	return (typeof(obj) == 'undefined' || !obj);
}

SfKernel.Util.SetToolTip = function(element, tooltip)
{
	element.setAttribute("title", tooltip);
	element.setAttribute("alt", tooltip);
}


SfKernel.Util.SetText = function(element, text)
{
	var firstChild = element.childNodes[0];
	var newNode = document.createTextNode(text);
	if (firstChild)
	{
		element.replaceChild(newNode, firstChild);
	}
	else
	{
		element.appendChild(newNode);
	}
}



SfKernel.PlayerDetect = function() {
    this._playerType = null;

    this.GetPlayerType = function() {
        if (this._playerType == null) {
            this.DetectPlayerType();
        }
        return this._playerType;
    }

    this.DetectPlayerType = function() {
        if (GlobalOptions.AlwaysUseSilverlight) {
            this._playerType = SfKernel.MediaPlayerType.SL1;
            return;
        }

        var slPref = SfKernel.GetQueryStringValue("UseSilverlight");
        if (slPref && slPref.toLowerCase() == "true") {
            this._playerType = SfKernel.MediaPlayerType.SL1;
            return;
        }

        if (Sys.Browser.agent == Sys.Browser.Firefox && this.IsWindows()) {
            this._SetFirefoxWinPlayerType();
            return;
        }

        if (Sys.Browser.agent == Sys.Browser.InternetExplorer && this.IsWindows()) {
            this._playerType = SfKernel.MediaPlayerType.WM7;
            return;
        }

        this._playerType = SfKernel.MediaPlayerType.SL1;
    }

    this.DisplaySilverlightOption = function() {
        if (this.IsWindows()) {
            if (this.IsInternetExplorer()) {
                return true;
            }

            if (this.IsFirefox() && this.IsPort25Present()) {
                return true;
            }
        }
        return false;
    }

    this._SetFirefoxWinPlayerType = function() {
        this._playerType = SfKernel.MediaPlayerType.SL1;

        if (this.IsPort25Present() == true) {
            this._playerType = SfKernel.MediaPlayerType.Port25;
            return;
        }
    }

    this.IsPort25Present = function() {
        var test
        for (var i = 0; i < navigator.plugins.length; ++i) {
            test += navigator.plugins[i];
            test += "\n";

            var plugin = navigator.plugins[i];
            if (
				(plugin.name && plugin.name.indexOf("np-mswmp") > -1)
				||
				(plugin.description && plugin.description.indexOf("np-mswmp") > -1)
				) {
                return true;
            }
        }
        return false;
    }

    this.IsWindows = function() {
        if (navigator.userAgent) {
            return (navigator.userAgent.toLowerCase().indexOf('windows') > -1);
        }
        return false;
    }

    this.IsMac = function() {
        if (navigator.userAgent) {
            return (navigator.userAgent.toLowerCase().indexOf('macintosh') > -1);
        }
        return false;
    }

    this.IsMacPPC = function() {
        if (navigator.userAgent) {
            return (navigator.userAgent.toLowerCase().indexOf('ppc mac os x') > -1);
        }
        return false;
    }

    this.IsFirefox = function() {
        if (navigator.userAgent) {
            return (navigator.userAgent.toLowerCase().indexOf('firefox') > -1);
        }
        return false;
    }

    this.IsInternetExplorer = function() {
        if (navigator.userAgent) {
            return (navigator.userAgent.toLowerCase().indexOf('msie') > -1);
        }
        return false;
    }

    this.IsInternetExplorer6 = function() {
        if (navigator.userAgent) {
            return (navigator.userAgent.toLowerCase().indexOf('msie 6.') > -1);
        }
        return false;
    }

    this.IsChrome = function() {
        if (navigator.userAgent) {
            return (navigator.userAgent.toLowerCase().indexOf('chrome') > -1);
        }
        return false;
    }
}


function EventManager()
{
	this.Events = new Sys.EventHandlerList();
	this.CommandEvents = new Sys.EventHandlerList();
}

EventManager.prototype = 
{
	PostEvent : function(eventId, sender, args)
	{
		var handler = this.Events.getHandler(eventId);
		if (handler == null)
		{
			return;
		}
		handler(sender, args);
	},

	PostCommandEvent : function(eventId, sender, args)
	{
		var handler = this.CommandEvents.getHandler(eventId);
		if (handler == null)
		{
			return;
		}
		handler(sender, args);
	}
}

////////////////////////////////////////////////////////////////////////////////
// Dialog Box
DialogBox = function DialogBox(container, containingWindow, id) {
    DialogBox.initializeBase(this, [ container, containingWindow, id, false ]);
    
    this.Message = null;
    this.Title = null;
    this.Id = id;
    this.okButton = null;
    this.cancelButton = null;
    this.okButtonFunction = null;
    this.okCancelButtonFunction = null;
}
DialogBox.prototype = {
    _container: null,
    _elements: null,
    _title: null,
    _closeButton: null,

    OnLoad: function DialogBox$OnLoad()
    {
        this._createDialog(this.Id);
    },

    _createDialog: function DialogBox$_createDialog(id)
    {
        var dialogFrame = this._createDiv(this.Id, 'dialogFrame');

        var dialogWidth;
        var dialogFrameLeft = 20;

        if (LayoutOptions.SlideWidth > 0)
        {
            dialogFrameLeft += parseInt($('CurrentSlideArea').style.left);
            dialogWidth = LayoutOptions.SlideWidth - 40;
        }
        else
        {
            if (LayoutOptions.DefaultPosition == 1 || LayoutOptions.DefaultPosition == 4)
            {
                dialogFrameLeft += LayoutOptions.VideoWidth;
            }
            dialogWidth = (LayoutOptions.PlayerWidth - LayoutOptions.VideoWidth - 40);
        }

        if (dialogWidth > 400)
        {
            dialogWidth = 400;
        }

        dialogFrame.style.position = 'absolute';
        dialogFrame.style.left = dialogFrameLeft + 'px';
        dialogFrame.style.width = dialogWidth + 'px';


        var dialogHeader = this._createDiv(this.Id + 'Header', 'dialogTitle');
        var dialogIcon = this._createDiv(this.Id + 'HeaderIcon', 'dialogIcon');
        var dialogHeaderText = this._createDiv(this.Id + 'HeaderText', 'dialogTitleText', this.Title);
        this._closeButton = this._createCloseButton(this.Id + 'HeaderCloseButton');

        this._closeButton.observe('mouseover', Function.createDelegate(this, this._closeButtonOnMouseOver));
        this._closeButton.observe('mouseout', Function.createDelegate(this, this._closeButtonOnMouseOut));
        this._closeButton.observe('click', Function.createDelegate(this, this._closeButtonOnClick));

        var dialogMessage = this._createDiv(this.Id + 'Message', 'dialogMessageText', this.Message);
        var dialogButtonContainer = this._createDiv(this.Id + 'MessageButton', 'dialogButtonContainer');
        if (this.okButton)
        {
            var okButton = this._createButton(this.Id + '_okButton', 'OK', true, 'return true', this._okButtonOnClick);
            okButton.observe('click', Function.createDelegate(this, this._okButtonOnClick));
            dialogButtonContainer.appendChild(okButton);
        }
        if (this.cancelButton)
        {
            var cancelButton = this._createButton(this.Id + '_cancelButton', 'Cancel', false, 'return false', this.cancelButtonFunction);
            dialogButtonContainer.appendChild(cancelButton);
        }

        dialogHeader.appendChild(dialogIcon);
        dialogHeader.appendChild(dialogHeaderText);
        dialogHeader.appendChild(this._closeButton);

        dialogFrame.appendChild(dialogHeader);
        dialogFrame.appendChild(dialogMessage);
        dialogFrame.appendChild(dialogButtonContainer);

        document.body.appendChild(dialogFrame);
    },

    _createCloseButton: function DialogBox$_createCloseButton(id)
    {
        var element = $(document.createElement('div'));
        element.setAttribute('id', this.Id + '_closeButton');
        element.className = 'dialogCloseButtonNormal';
        return element;
    },

    _closeButtonOnMouseOver: function DialogBox$_closeButtonOnMouseOver(sender, args)
    {
        this._closeButton.className = 'dialogCloseButtonOver';
    },

    _closeButtonOnMouseOut: function DialogBox$_closeButtonOnMouseOut(sender, args)
    {
        this._closeButton.className = 'dialogCloseButtonNormal';
    },

    _closeButtonOnClick: function DialogBox$_closeButtonOnClick(sender, args)
    {
        this._closeButton.className = 'dialogCloseButtonNormal';
        document.body.removeChild($(this.Id));
    },

    _okButtonOnClick: function DialogBox$_okButtonOnClick(sender, args)
    {
        document.body.removeChild($(this.Id));
    },

    _addButton: function DialogBox$_createButton(id, text, dismiss, returns, clickevent)
    {
        var parentElement = document.getElementById(this.Id + 'MessageButton');
        var newButton = this._createButton(id, text, dismiss, returns, clickevent);
        parentElement.appendChild(newButton);
    },

    _createButton: function DialogBox$_createButton(id, text, dismiss, returns, clickevent)
    {
        var element = $(document.createElement('div'));
        element.setAttribute('id', id);
        element.className = 'dialogButton';
        element.innerHTML = text;
        if (dismiss)
        {
            clickevent = 'document.body.removeChild($(\'' + this.Id + '\'));' + clickevent + ';';
            //element.setAttribute('onclick', 'document.body.removeChild($(\''+ this.Id +'\'));' + returns +'');
        }
        if (returns)
        {
            clickevent = clickevent + returns;
        }
        element.setAttribute('onclick', clickevent);
        return element;
    },

    _createDiv: function DialogBox$_createDiv(id, className, html)
    {
        var element = $(document.createElement('div'));
        element.setAttribute('id', id);
        element.className = className;
        if (html)
        {
            element.innerHTML = html;
        }
        return element;
    }
}

function PresentationFailedToLoad(id,error)
{
    if(GlobalOptions.ErrorPage.length > 0)
    {
        var errorPage = GlobalOptions.ErrorPage;
        if(errorPage.indexOf('?') > -1)
        {
            errorPage += '&';    
        }
        else
        {
            errorPage += '?';
        }
        
        if(window.ErrorStatus)
        {
            var errorMessage = String.format("Manifest Load Error : {0} - {1}",ErrorStatus.Code,ErrorStatus.Text);
            errorPage = String.format("{0}errorType=ClientLoad&errorDetails={1}",errorPage,encodeURIComponent(errorMessage));
        }
        else
        {
            errorPage = String.format("{0}errorType=ClientLoad&errorDetails={1}",errorPage,encodeURIComponent(error));   
        }
        
        window.location = errorPage;
    }
	    
    var errorMessage = 'The requested presentation failed to load.<br/><br/>';
    var presentationFailureErrorDialog = new DialogBox(id);
    presentationFailureErrorDialog.Message= errorMessage + error;
    presentationFailureErrorDialog.Title= 'Mediasite Error';
    presentationFailureErrorDialog.Id = id;
    presentationFailureErrorDialog.okButton= true;
    presentationFailureErrorDialog.OnLoad();
    return false;
}


function ReportingCallManager()
{	
	ReportingCallManager.prototype.OnSuccess = function(result, context)
	{
	}

	ReportingCallManager.prototype.OnFailure = function(error, context)
	{
	    //need to eat abort errors
	}
}

OptionsManager = function()
{
	this._options = {};
	this._Initialize();
}

OptionsManager.prototype =
{	
	_Initialize : function()
	{
	},
		
	_GetBoolOptionFromCookie : function(optionType, def)
	{
	    return new MediasitePlayerCookie().GetBoolValue(optionType, def);
	},
	
	_SetBoolOptionToCookie : function(optionType, val)
	{
	    return new MediasitePlayerCookie().SetBoolValue(optionType, val);
	},
		
	GetOption : function(optionType)
	{
		var val = this._options[optionType];
		if (typeof(val) != 'undefined')
		{
			return val;
		}
		return null;
	},
		
	SetOption : function(optionType, val)
	{
		this._options[optionType] = val;
		this._FireOptionChanged(optionType, val);
	    this._SetBoolOptionToCookie(optionType, val);
	},
	
	_FireOptionChanged : function(optionType, val)
	{
		mPlayer.EventManager.PostEvent(SfKernel.EventType.OptionChanged, this, {OptionType:optionType, Value:val});
	}
}



SfKernel.XMLHttpSyncExecutor = function SfKernel$XMLHttpSyncExecutor() {

    SfKernel.XMLHttpSyncExecutor.initializeBase(this);
}

    function SfKernel$XMLHttpSyncExecutor$executeRequest() {
        if (arguments.length !== 0) throw Error.parameterCount();
        this._webRequest = this.get_webRequest();

        if (this._started) {
            throw Error.invalidOperation(String.format(Sys.Res.cannotCallOnceStarted, 'executeRequest'));
        }
        if (this._webRequest === null) {
            throw Error.invalidOperation(Sys.Res.nullWebRequest);
        }

        var body = this._webRequest.get_body();
        var headers = this._webRequest.get_headers();
        this._xmlHttpRequest = new XMLHttpRequest();
        this._xmlHttpRequest.onreadystatechange = this._onReadyStateChange;

        var verb = this._webRequest.get_httpVerb();        
        this._xmlHttpRequest.open(verb, this._webRequest.getResolvedUrl(), false /*SYNC*/);
        if (headers) {
            for (var header in headers) {
                var val = headers[header];
                if (typeof(val) !== "function")
                    this._xmlHttpRequest.setRequestHeader(header, val);
            }
        }

        if (verb.toLowerCase() === "post") {
            // If it's a POST but no Content-Type was specified, default to application/x-www-form-urlencoded
            if ((headers === null) || !headers['Content-Type']) {
                this._xmlHttpRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            }

            // DevDiv 15893: If POST with no body, default to ""(FireFox needs this)
            if (!body) {
                body = "";
            }
        }

        this._xmlHttpRequest.send(body);
        this._started = true;
    }   

SfKernel.XMLHttpSyncExecutor.prototype = {

    executeRequest: SfKernel$XMLHttpSyncExecutor$executeRequest
}
SfKernel.XMLHttpSyncExecutor.registerClass('SfKernel.XMLHttpSyncExecutor', Sys.Net.XMLHttpExecutor);

function MediasitePlayerCookie()
{
	this.name = "MediasitePlayerOptions";	
    this.expires = null;
	this.path = "/";
	
	this.values = new Object();
	this.valueDelimiter = "&";

	this.SetExpires = function(value)
	{
		this.expires = value;
	}
	
	this.SetValue = function(name, value)
	{
	    this.ReadCookieData();
	    this.values[name] = value;
	    this.WriteCookieData();
	}
	
    this.SetBoolValue = function(name, isTrue)
	{
	    this.ReadCookieData();
		if (isTrue)
		{
			this.values[name] = "true";
		}
		else
		{
			this.values[name] = "false";
		}
        this.WriteCookieData();
	}
	    
	this.GetValue= function(name)
	{
	    this.ReadCookieData();
	    return this.values[name];
	}

 	this.GetNumberValue = function(name, def)
	{
		this.ReadCookieData();
		if (this.values[name] == null)
		{
			return def;
		}
		
		return Number(this.values[name]);
	}
   
    this.GetBoolValue = function(name, def)
	{
	    this.ReadCookieData();
		if (this.values[name] == null)
		{
			return def;
		}
		
		if (this.values[name] == "true")
		{
			return true;
		}
		else
		{
			return false;
		}
	}
    
    this.WriteCookieData= function()
    {
		if (this.expires == null)
		{
			var now = new Date();
	        this.expires =  new Date(now.getFullYear()+1, now.getMonth(), now.getDate());			
		}
		var cookieData ="";
        for(var key in this.values)
        {
            cookieData += key;
            cookieData += "=";
            cookieData += escape(this.values[key]);
            cookieData += this.valueDelimiter;
        }
        cookieData = cookieData.substring(0,cookieData.length-1)
	    				
		var newCookie = this.name + "=" + cookieData +
		((this.path) ? "; path=" + this.path : "") +
		((this.expires) ? "; expires=" + this.expires.toGMTString() : "");
		
		document.cookie = newCookie;
    
    }
    	
	this.ReadCookieData= function()
	{
		if (document.cookie)
		{
			var begin = document.cookie.indexOf(this.name + "=");
			if (begin != -1)
			{
				begin += this.name.length + 1;
				var end = document.cookie.indexOf(";",begin);
				if (end == -1)
				{
					end = document.cookie.length;
				}
				
				var rawCookie = document.cookie.substring(begin,end);
				var entries = rawCookie.split(this.valueDelimiter);
				
				for(var i=0;i<entries.length;i++)
				{
				    var parts = entries[i].split("=");
				    
				    if(parts.length=2)
				    {
				        this.values[parts[0]] = unescape(parts[1]);				    
				    }
				}							
			}
		}
	}

	
}

Type.registerNamespace('SfEmail');

SfEmail.ValidateEmailAddress = function(address)
{ 
    var emailRegEx = /^[A-Z0-9.'_%+-]+@(?:[A-Z0-9-]+\.)+[A-Z]{2,4}$/i;
    return emailRegEx.test(address);
}

SfEmail.EnableStartTime = function()
{
    var enable = $("emailInviteStartcb").checked;
    $("emailInviteArea_emailInviteStartTimetxt").disabled = !enable;
    SfEmail.UpdateMessage();
}

SfEmail.UpdateMessage = function()
{
    var startTimeInputElement = $("emailInviteArea_emailInviteStartTimetxt");
    var startTimeInput = startTimeInputElement.value;
    
    var checkboxElement = $("emailInviteStartcb");
    var messageFieldElement = $("emailInviteArea_emailInviteMessageFieldtxt");
    if(checkboxElement.checked)
    {
        var startTimeMS = SfKernel.DurationDisplayToMS(startTimeInput);
        messageFieldElement.value = replaceStartPoint(startTimeMS);
    }
    else
    {
        messageFieldElement.value = replaceStartPoint(0);
    }
        
    function replaceStartPoint(startTimeMS)
    {
        var messageText = $("emailInviteArea_emailInviteMessageFieldtxt").value;
        var playFromString = "&playfrom=";
        var peidString = "peid=";
        var startTimeHMS = SfKernel.GetDisplayDuration(startTimeMS, true);

        if(messageText.match(playFromString) ==  null && startTimeMS > 0)
        {
            messageText = messageText.replace(peidString + getPeId(),peidString + getPeId() + playFromString + startTimeMS);
        }
        else
        {
            var startIndex = messageText.indexOf(playFromString);
            var endIndex = messageText.indexOf("\n",startIndex);
            var oldStartTime = messageText.substring(startIndex,endIndex);
            if(startTimeMS > 0)
            {
                messageText = messageText.replace(peidString + getPeId() + oldStartTime,peidString + getPeId() + playFromString + startTimeMS);
            }
            else
            {
                messageText = messageText.replace(peidString + getPeId() + oldStartTime,peidString + getPeId());                    
            }
        }        
        return messageText;        
    }
    
    function getPeId(){return Manifest.PresentationId.replace(/-/g,"");}
    
}
  
SfEmail.SetInviteStartTime = function()
{
    var startTimeInputElement = $("emailInviteArea_emailInviteStartTimetxt");
    var currentTimeDisplay = $("PlayerPositionArea").innerHTML;
    startTimeInputElement.value = currentTimeDisplay.substring(0,currentTimeDisplay.indexOf("/"));
    SfEmail.EnableStartTime();
}


SfEmail.ClientExport = function()
{
    SfEmail.CloseEmailInvitation();
    SfEmailIsShowing = false;

    var invite = SfEmail.CollectData();
    var mailTo = String.format("mailto:{0}?subject={1}&body={2}",
                                encodeURIComponent(invite.ToAddresses.join(",")),
                                encodeURIComponent(invite.Subject),
                                encodeURIComponent(invite.MessageBody));
    location.href = mailTo;
}

var SfEmailInvite = null;
var SfEmailIsShowing = false;

SfEmail.OpenEmailInvitation = function()
{
    if($("EmailInviteArea").style.display != "block")
    {        
        SfEmail.HidePresentationCardScrollbars();
        $("emailInviteArea_emailInviteToFieldtxt").value = "";   
        
        var fromAddress = new MediasitePlayerCookie().GetValue("UserFromEmail");
        if(fromAddress != undefined)
        {
            $("emailInviteArea_emailInviteFromFieldtxt").value = fromAddress;   
        }
                               
        if(Manifest.PlayStatus != SfKernel.PresentationPlayStatus.OnDemand)
        {
            $("emailInviteStartcb").disabled = true;
        }
        
        if(SfEmailInvite)
        {      
            SfEmail.SetInviteStartTime();
            
            if(!SfEmailInvite.UseServerForSMTP)
            {
                SfEmail.ClientExport();
            }
            else
            {
                show("EmailInviteArea");
                SfEmailIsShowing = true;
            }
        }
        else
        {
            SonicFoundry.Mediasite.Player.DataAccess.PlayerService.GetInvite(Manifest.PlaybackTicketId, SfEmail.GetInviteOnSuccess);  
        }        
    }
}

SfEmail.CloseEmailInvitation = function()
{
    hide("EmailInviteArea");
}

// workaround for issue in firefox 2 on mac where scrollbars show on top layer regardless of zIndex.
SfEmail.HidePresentationCardScrollbars = function()
{
    if($('CurrentSlideArea').offsetLeft == ($('PresentationCardArea').offsetLeft+1))
    {
        $('PresentationCardAreaScrollDiv').style.overflow = 'hidden';
        $('PresentationCardAreaScrollDiv').style.overflowY = 'hidden';
    }	
}

SfEmail.ShowPresentationCardScrollbars = function()
{
    if($('CurrentSlideArea').offsetLeft == ($('PresentationCardArea').offsetLeft+1))
    {
        $('PresentationCardAreaScrollDiv').style.overflowY = 'scroll';
        $('PresentationCardAreaScrollDiv').style.overflowX = 'hidden';
    }	
}

SfEmail.GetInviteOnSuccess = function(emailData) {
    $("emailInviteArea_emailInviteSubjectFieldtxt").value = emailData.Subject;
    var message = emailData.MessageBody;
    var messageCleaned = message.replace(/\t/g, "");
    $("emailInviteArea_emailInviteMessageFieldtxt").value = messageCleaned;

    SfEmailInvite = emailData;
    SfEmail.SetInviteStartTime();

    if (!emailData.UseServerForSMTP) {
        SfEmail.ClientExport();
    }
    else {
        show("EmailInviteArea");
        SfEmailIsShowing = true;
    }
}

SfEmail.SendEmail = function()
{
    var invite = SfEmail.CollectData();
    
    if(validateInvite(invite))
    {
        SonicFoundry.Mediasite.Player.DataAccess.PlayerService.SendInvite(Manifest.PlaybackTicketId, invite, SfEmail.SendOnSuccess);        
        new MediasitePlayerCookie().SetValue("UserFromEmail", invite.FromAddress);
    }
    else
    {
        SfEmail.ShowMessage(Localization.EmailInviteInvalid,false)
    }
    
    function validateInvite(invite)
    {   
        if(!SfEmail.ValidateEmailAddress(invite.FromAddress))
        {
            return false;
        }            

        for (var i=0;i<invite.ToAddresses.length;i++)
        {
            if(!SfEmail.ValidateEmailAddress(invite.ToAddresses[i])) 
            {
                return false;
            }
        }
        return true;
    }

}

SfEmail.SendOnSuccess = function(message)
{
    SfEmail.ShowMessage(message,true);
}


SfEmail.ShowMessage = function(message,closeParent)
{
    show('emailInviteModalMask');
    show('emailInviteReturnDiv');
    $("emailInviteReturnDivMessage").innerHTML = message; 
    $("emailInviteReturnDivCloseButtonFlag").innerHTML = closeParent;
}

SfEmail.CloseMessage = function()
{
    hide('emailInviteModalMask');
    hide('emailInviteReturnDiv');
    if($("emailInviteReturnDivCloseButtonFlag").innerHTML != "false")
    {
        SfEmail.CloseEmailInvitation();
        SfEmailIsShowing = false;
    }
    else
    {
        $("emailInviteReturnDivCloseButtonFlag").innerHTML = "true";
    }
}

function show(e)
{
    $(e).style.display = "block";
}
function hide(e)
{
    $(e).style.display = "none";    
}


SfEmail.CollectData = function()
{
    var invite = new SonicFoundry.Mediasite.Player.DataAccess.PlayerEmailMessage();
    invite.FromAddress = $("emailInviteArea_emailInviteFromFieldtxt").value;
    
    var recipients = $("emailInviteArea_emailInviteToFieldtxt").value.split(";");
    
    for (var i=0;i<recipients.length;i++)
    {
        recipients[i] = recipients[i].trim();
    }     
        
    invite.ToAddresses = recipients;
    invite.Subject = $("emailInviteArea_emailInviteSubjectFieldtxt").value;
    invite.MessageBody = $("emailInviteArea_emailInviteMessageFieldtxt").value;    
    return invite;
}

/// Ask Question Area

Type.registerNamespace('SfForum');

var SfForumIsShowing = false;

SfForum.EnableQuestionTime = function()
{
    var enable = $("askQuestionTimecb").checked;
    $("askQuestionArea_askQuestionTimetxt").disabled = !enable;
}

SfForum.OpenAskQuestion = function()
{
    if($("AskQuestionArea").style.display != "block")
    {
        SfEmail.HidePresentationCardScrollbars();
        show("AskQuestionArea");
        SfForumIsShowing = true;

        this.TextAreasInit();  
        
        var userFromName = new MediasitePlayerCookie().GetValue("UserFromName");
        if(userFromName != undefined)
        {
          $("askQuestionArea_askQuestionNameFieldtxt").value = userFromName;   
        }
        var userFromEmail = new MediasitePlayerCookie().GetValue("UserFromEmail");
        if(userFromEmail != undefined)
        {
          $("askQuestionArea_askQuestionEmailFieldtxt").value = userFromEmail;
        }
        
        if(Manifest.PlayStatus != SfKernel.PresentationPlayStatus.OnDemand)
        {
            // hide checkbox and move send button off form field
            $("askQuestionButtons").style.height = '44px';
            $("askQuestionButtons").style.top = '12px';
            $("askQuestionButtons").style.right = '12px';
            $("askQuestionTime").style.display = "none";
            $("askQuestionTimecb").checked = false;
            $("askQuestionArea_askQuestionTimetxt").value = "00:00:00";
        }
        else
        {
            $("askQuestionTimecb").checked = true;
            SfForum.SetPresentationTime();
        }               
    }
}

SfForum.CloseAskQuestion = function()
{
    hide('AskQuestionArea');
}

SfForum.SetPresentationTime = function()
{
    var currentTimeDisplay = $("PlayerPositionArea").innerHTML;    
    $("askQuestionArea_askQuestionTimetxt").value = currentTimeDisplay.substring(0,currentTimeDisplay.indexOf("/"));
    SfForum.EnableQuestionTime();
}

SfForum.TextAreasInit = function() {
    var obj = document.getElementById("askQuestionArea_askQuestionMessageFieldtxt");
    obj.onkeyup = SfForum.ForceMaxLength;
    obj.onblur = SfForum.ForceMaxLength;
}

SfForum.ForceMaxLength = function() {
var characterLimit = 2048;
if (this.value.length > characterLimit) {
        this.value = this.value.substring(0, characterLimit);
    }
}

SfForum.SendQuestion = function()
{
    var questionInfo = new SonicFoundry.Mediasite.Player.DataAccess.PresentationQuestion();
    
    questionInfo.Submitter = $("askQuestionArea_askQuestionNameFieldtxt").value;
    questionInfo.SubmitterEmail = $("askQuestionArea_askQuestionEmailFieldtxt").value;
    questionInfo.Subject = $("askQuestionArea_askQuestionSubjectFieldtxt").value;
    questionInfo.Question = $("askQuestionArea_askQuestionMessageFieldtxt").value;      
              
    if($("askQuestionTimecb").checked)
    {
        questionInfo.TimeInPresentation = SfKernel.DurationDisplayToMS($("askQuestionArea_askQuestionTimetxt").value);
    }   
    else
    {
        questionInfo.TimeInPresentation = 0;
    }
    
    var errors = SfForum.AskQuestionFormErrors(questionInfo);
    
    if(errors.length > 0)
    {
        SfForum.ShowAskQuestionMessage(errors,false);
        return;
    }
        
    SonicFoundry.Mediasite.Player.DataAccess.PlayerService.SendQuestion(Manifest.PlaybackTicketId, questionInfo, SfForum.SendQuestionOnSuccess);               
    
    new MediasitePlayerCookie().SetValue("UserFromName", questionInfo.Submitter);
    
    if(questionInfo.SubmitterEmail.length > 0)
    {
        new MediasitePlayerCookie().SetValue("UserFromEmail", questionInfo.SubmitterEmail);
    }    
}

SfForum.AskQuestionFormErrors = function(questionInfo)
{
    var errors = "";
    
    if(questionInfo.Submitter.length < 1)
    {
    
        errors += "<br/> - " + Localization.ForumNameRequired;
    }    
    
    if(questionInfo.SubmitterEmail.length > 0 && !SfEmail.ValidateEmailAddress(questionInfo.SubmitterEmail))
    {
        errors += "<br/> - " + Localization.ForumEmailInvalid;
    }

    if(questionInfo.Subject.length < 1)
    {
        errors += "<br/> - " + Localization.ForumSubjectRequired;
    }
            
    if(questionInfo.Question.length < 1)
    {
        errors += "<br/> - " + Localization.ForumQuestionRequired;
    }
    
    if(questionInfo.TimeInPresentation > Manifest.Duration)
    {
        errors += "<br/> - " + Localization.ForumQuestionTimeError;
    }
    
    if(errors.length > 0)
    {
        errors = Localization.ForumErrorMessage +"<br/>" + errors;
    }
    return errors;
}

SfForum.SendQuestionOnSuccess = function(response)
{
            
    if (response.Success)
    {
        SfForum.ShowAskQuestionMessage(Localization.SubmitQuestionSuccess, true);
    
        $("askQuestionArea_askQuestionMessageFieldtxt").value = "";        
        $("askQuestionArea_askQuestionSubjectFieldtxt").value = "";    
    }
    else
    {
        if(response.Message.length > 0)
        {
            SfForum.ShowAskQuestionMessage(response.Message, false);            
        }
        else
        {
            SfForum.ShowAskQuestionMessage(Localization.SubmitQuestionFailure, false);            
        }        
    }

}

SfForum.ShowAskQuestionMessage = function(message,closeParent)
{
    show('askQuestionModalMask');
    show('askQuestionReturnDiv');
    $("askQuestionReturnDivMessage").innerHTML = message; 
    $("askQuestionReturnDivCloseButtonFlag").innerHTML = closeParent;
}

SfForum.CloseAskQuestionMessage = function()
{
    hide('askQuestionModalMask');
    hide('askQuestionReturnDiv');
    if($("askQuestionReturnDivCloseButtonFlag").innerHTML != "false")
    {
        SfForum.CloseAskQuestion();
        SfForumIsShowing = false;
    }
    else
    {
        $("askQuestionReturnDivCloseButtonFlag").innerHTML = "true";
    }
}
    


ChangePosition=function(){};

ChangePosition.test=function(q)
{
    var positionArray = this.BuildPositionArray(q);
    this.SetPositions(positionArray);
}

ChangePosition.OnLoad=function()
{
    var positionArray = this.BuildPositionArray(parseInt(LayoutOptions.DefaultPosition));
    this.SetPositions(positionArray);
}

ChangePosition.BuildPositionArray = function(quadrant) {
    var changeArray = new Array();

    var vW = LayoutOptions.VideoWidth;
    var vH = LayoutOptions.VideoHeight;
    var sW = LayoutOptions.SlideWidth; // padding surrounding the currentslide
    var sH = LayoutOptions.SlideHeight;
    var pW = LayoutOptions.PlayerWidth;
    var pH = LayoutOptions.PlayerHeight;
    var adBannerHeight = 0;
    var adBannerWidth = 0;
    var titleBannerHeight = 0;
    var titleBannerWidth = 0;

    if (LayoutOptions.Images["AdBanner"]) {
        adBannerHeight = parseInt(LayoutOptions.Images["AdBanner"].Height);
        adBannerWidth = parseInt(LayoutOptions.Images["AdBanner"].Width);
    }
    if (LayoutOptions.Images["TitleBanner"]) {
        titleBannerHeight = parseInt(LayoutOptions.Images["TitleBanner"].Height);
        titleBannerWidth = parseInt(LayoutOptions.Images["TitleBanner"].Width);
    }

    // see if we have a value for these... otherwise use the following values.


//Atitude Abre
    var btnPollWidth = 116;
    var btnEmailWidth = 40;
    var btnLinksWidth = 82;
    var btnAskButtonWidth = 126;
//Atitude Fecha


    var btnHelpWidth = $('btnHelp').offsetWidth;
    var btnPlayPauseWidth = 30;
    var btnSkipBackWidth = 30;
    var btnMuteWidth = 15;
    var btnCCWidth = 30;
    var btnChaptWidth = 28;
    var btnFullScreenWidth = 30;
    if (mPlayer.PlayerDetect.GetPlayerType() == SfKernel.MediaPlayerType.SL1) {
        btnFullScreenWidth = 0;
    }
    var liveIndicatorWidth = 20;
    var playerControlsPadding = 4;
    var statusBarHeight = 16;
    var playerControlsHeight = 42;
    var videoElementPadding = 4;
    var playerControlsButtonSpacing = 0;
    var playerSliderPadding = playerControlsPadding * 2;
    var playerSliderWidth = vW - (playerSliderPadding * 2);
    var volumeSliderWidth = 33;
    var speedControlWidth = 35;
    var languageSelectionAreaWidth = 40;
    var commandBarPadding = 4;
    var linksPanelWidth = 340;
    var playerPadding = 3;
    var playerPaddingRight = 6;
    var playerPaddingLeft = 2;
    var playerMarginBottom = 1;
    var playerMarginRight = 4;
    var playerMarginLeft = 4;
    var commandBarButtonSpacing = -3;
    var commandBarHeight = 28;
    var currentSlideAreaTopPadding = 4;
    var currentSlideAreaLeftPadding = 4;
    var currentSlideAreaBorderThickness = 1;
    var currentSlideAreaLeft = ((pW - (vW + sW + playerPadding * 2)) / 2) + vW; // obsolete?
    var presentationCardBorderThickness = 1;
    var applicationVersionAreaWidth = 83;
    var slideBrowserWidth = sW;
    var slideBrowserHeight = sH - (slideBrowserToolbarHeight - currentSlideAreaTopPadding);
    var slideBrowserWidth = 200;
    var slideBrowserHeight = 100 - (slideBrowserToolbarHeight - currentSlideAreaTopPadding);
    var slideBrowserToolbarHeight = 26;
    var thumbNailPropertiesContainerWidth = 190;
    var thumbNailPropertiesContainerHeight = 112;

    var totalMediaWidth = 0;
    var playerRemainingSpace = 0;
    var presentationCardWidth = pW - vW - 8;

    if (sW > 0) { totalMediaWidth = sW + (currentSlideAreaLeftPadding * 2) + vW + 2; }
    else { totalMediaWidth = presentationCardWidth + (currentSlideAreaLeftPadding * 2) + vW + 2; }
    playerRemainingSpace = Math.floor((pW - totalMediaWidth) / 3);

    if (playerRemainingSpace < 0) {
        playerRemainingSpace = 0
    }
    else {
        playerMarginLeft = playerRemainingSpace;
        playerMarginRight = playerRemainingSpace;
        playerPaddingLeft = playerRemainingSpace;
        currentSlideAreaLeft = (2 * playerRemainingSpace) + vW + 2;
    }

    var tabsLeft = currentSlideAreaLeft + 4;
    var tabsRight = tabsLeft;
    if ($("btnSlideShowImg")) {
        tabsRight += $("btnSlideShowImg").offsetWidth;
    }
    if ($("btnSlideListImg")) {
        tabsRight += $("btnSlideListImg").offsetWidth;
    }
    var currentSlideToolbarWidth = 50;
    var slideTickerWidth;
    if ($("SlideTicker")) {
        slideTickerWidth = $("SlideTicker").offsetWidth;
    }
    var remainingCommandBarWidth = (pW - tabsRight - applicationVersionAreaWidth - btnHelpWidth - currentSlideToolbarWidth);
    var remainingCommandBarSpacing = Math.floor((remainingCommandBarWidth - slideTickerWidth) / 2);
    if (remainingCommandBarWidth < 0) { remainingCommandBarSpacing = 0 }
    var presentationCardTop = titleBannerHeight + commandBarHeight + videoElementPadding + vH + statusBarHeight + playerControlsHeight + playerRemainingSpace;
    var presentationCardHeight = pH - (titleBannerHeight + commandBarHeight + videoElementPadding + vH + statusBarHeight + playerControlsHeight + playerRemainingSpace) - playerMarginBottom;
    var presentationCardFooterHeight = 16;
    var speedControlRemainingSpace = (vW - playerControlsPadding - btnFullScreenWidth - volumeSliderWidth - playerControlsButtonSpacing - btnMuteWidth - btnCCWidth - 4) - (playerControlsPadding + btnPlayPauseWidth + btnSkipBackWidth + (2 * playerControlsButtonSpacing));
    var speedControlLeft = ((speedControlRemainingSpace / 2) - (speedControlWidth / 2)) + (playerControlsPadding + btnPlayPauseWidth + btnSkipBackWidth + (2 * playerControlsButtonSpacing));
    var linksPanelHeight = sH == 0 ? (vH + playerControlsHeight - 18) : sH - 18;
    linksPanelHeight = linksPanelHeight > 280 ? 280 : linksPanelHeight;

    var basePositionArray = new Array(
    "backgroundImage,w," + pW,
    "backgroundImage,h," + pH,
    "PageContent,w," + pW,
    "PageContent,h," + pH,
    // banners
    "AdBanner,w," + adBannerWidth,
    "AdBanner,h," + adBannerHeight,
    "AdBanner,l," + titleBannerWidth,
    "AdBannerImage,w," + adBannerWidth,
    "AdBannerImage,h," + adBannerHeight,
    "TitleBanner,w," + titleBannerWidth,
    "TitleBanner,h," + titleBannerHeight,
    "TitleBannerImage,w," + titleBannerWidth,
    "TitleBannerImage,h," + titleBannerHeight,
    "CommandBar,t," + titleBannerHeight,
    "CommandBar,h," + commandBarHeight,
    "CommandBar,w," + pW,
    "InnerBackground,w," + pW,
    "InnerBackground,h," + (pH - titleBannerHeight - commandBarHeight),
    "InnerBackground,t," + (titleBannerHeight + commandBarHeight),

    "EmbeddedPlayer,w," + vW,
    "EmbeddedPlayer,h," + vH,
    "VideoContainer,w," + vW,
    "VideoContainer,h," + vH,
    "PlayerContainer,w," + vW,
    "PlayerControls,w," + vW,
    "StatusBar,w," + vW,
    "SamiDropDownArea,w," + vW,
    "PlayerAudioOnlyImage,w," + vW,
    "PlayerAudioOnlyImage,h," + vH,
    "PlayerNotStartedImage,w," + vW,
    "PlayerNotStartedImage,h," + vH,

    // playerControls
    "PlayerSlider,w," + playerSliderWidth,
    "PlayerSlider,l," + playerSliderPadding,
    "PlayerSlider_positionGuide,w," + playerSliderWidth,
    // if btnFullScreen exists... subtract its width the below
    "VolumeSlider,l," + (vW - volumeSliderWidth - btnFullScreenWidth - playerControlsPadding - 3),
    "VolumeSlider,w," + volumeSliderWidth,
    "VolumeSlider_positionGuide,w," + volumeSliderWidth,
    "LanguageSelectionArea,r," + ((vW + languageSelectionAreaWidth) / 2),
    // if btnFullScreen exists... subtract its width the below
    "btnMute,l," + (vW - playerControlsPadding - btnFullScreenWidth - volumeSliderWidth - playerControlsButtonSpacing - btnMuteWidth - 7),
    "btnCC,l," + (vW - playerControlsPadding - btnFullScreenWidth - volumeSliderWidth - playerControlsButtonSpacing - btnMuteWidth - btnCCWidth - 6),
    "btnChapters,l," + (vW - playerControlsPadding - btnFullScreenWidth - volumeSliderWidth - playerControlsButtonSpacing - btnMuteWidth - btnCCWidth - btnChaptWidth - 6),
    "btnFullScreen,l," + (vW - playerControlsPadding - btnFullScreenWidth),
    "btnPlayPause,l," + playerControlsPadding,
    "btnSkipback,l," + (playerControlsPadding + btnPlayPauseWidth + playerControlsButtonSpacing),
    "PlayerSpeedControl,l," + speedControlLeft,

    // windows (check that its not wider than the current slide, if it is, downsize it.)
    "AskQuestionArea,t," + (titleBannerHeight + commandBarHeight),
    "EmailInviteArea,t," + (titleBannerHeight + commandBarHeight),
    "LinksPanel,t," + (titleBannerHeight + commandBarHeight),

    // command bar
    "btnPoll,t," + (titleBannerHeight),
    "btnAskButton,t," + (titleBannerHeight),
    "btnEmail,t," + (titleBannerHeight),
    "btnLinks,t," + (titleBannerHeight),
    "LiveIndicatorArea,t," + (titleBannerHeight + 2),
    "LiveIndicatorAreaImg,t," + (titleBannerHeight + 2),
    "SlideTicker,t," + (titleBannerHeight),
    "btnHelp,t," + (titleBannerHeight + 1),
    "btnHelpImg,t," + (titleBannerHeight + 1),
    "ApplicationVersionArea,t," + (titleBannerHeight + 2),
    "SlideTabs,t," + (titleBannerHeight)
    );
    changeArray = basePositionArray.concat(basePositionArray);

    if ((vH / vW) < .75) // widescreen player
    {
        if (quadrant == 1 || quadrant == 4) {
            playerPadding = 0;
        }
        else {
            playerPadding = 4;
            playerPaddingLeft = 0;
            playerMarginRight = 2;
        }
    }

    if (sW > 0 && sH > 0) // if slide area is shown
    {
        var slidePositionArray = new Array(
        "CurrentSlideArea,h," + sH,
        "CurrentSlideArea,w," + sW,
        "CurrentSlideArea,t," + (titleBannerHeight + commandBarHeight - 3),
        "CurrentSlideAreaSlideImage,h," + sH,
        "CurrentSlideAreaSlideImage,w," + sW,
        "CurrentSlideAreaSlideDescription,h," + sH,
        "CurrentSlideAreaSlideDescription,w," + sW,

        "ThumbNailsArea,w," + (sW + (2 * currentSlideAreaLeftPadding)),
        "thumbnailToolbar,w," + (sW + (2 * currentSlideAreaLeftPadding)),
        "ChapterPointsArea,w," + (sW + (2 * currentSlideAreaLeftPadding)),
        "ThumbNailsArea,h," + (sH + (2 * currentSlideAreaTopPadding)),
        "ThumbNailsArea,t," + (titleBannerHeight + commandBarHeight - 3),
        "thumbNailSlidesContainer,h," + (sH - slideBrowserToolbarHeight + (2 * currentSlideAreaTopPadding)),
        "thumbNailSlidesContainer,w," + (sW + (2 * currentSlideAreaLeftPadding)),
        "ChapterPointsArea,w," + (sW + (2 * currentSlideAreaLeftPadding)),
        "ChapterPointsArea,h," + (sH + (2 * currentSlideAreaTopPadding) - slideBrowserToolbarHeight),
        "TextSlideSorterArea,w," + (sW + (2 * currentSlideAreaLeftPadding)),
        "TextSlideSorterArea,h," + (sH + (2 * currentSlideAreaTopPadding) - slideBrowserToolbarHeight),
        "TextSlideSorterAreaInside,w," + (sW + (2 * currentSlideAreaLeftPadding)),
        "TextSlideSorterAreaInside,h," + (sH + (2 * currentSlideAreaTopPadding) - slideBrowserToolbarHeight),

        "EmailInviteArea,w," + (sW - 20),
        "emailInviteArea_emailInviteMessageFieldtxt,h," + (sH - 179),
        "emailInviteArea_emailInviteMessageFieldtxt,maxH," + (sH - 179),
        "emailInviteArea_emailInviteFromFieldtxt,w," + (sW - 100),
        "emailInviteArea_emailInviteToFieldtxt,w," + (sW - 100),
        "emailInviteArea_emailInviteSubjectFieldtxt,w," + (sW - 100),
        "emailInviteStartingPoint,w," + (sW - 100),
        "emailInviteArea_emailInviteMessageFieldtxt,w," + (sW - 100),
        "emailInviteArea_emailInviteMessageFieldtxt,maxW," + (sW - 100),
// Atitude Abre
        "AskQuestionArea,w," + (sW - 120),
        "askQuestionArea_askQuestionMessageFieldtxt,h," + (sH - 150),
        "askQuestionArea_askQuestionMessageFieldtxt,maxH," + (sH - 150),
        "askQuestionArea_askQuestionNameFieldtxt,w," + (sW - 220),
        "askQuestionArea_askQuestionEmailFieldtxt,w," + (sW - 220),
        "askQuestionArea_askQuestionSubjectFieldtxt,w," + (sW - 220),
        "askQuestionArea_askQuestionMessageFieldtxt,w," + (sW - 220),
        "askQuestionArea_askQuestionMessageFieldtxt,maxW," + (sW - 220),
        "emailInviteStartingPoint,w," + (sW - 120),
// Atitude Fecha
        "LinksPanelContainer,h," + linksPanelHeight
        );
        changeArray = changeArray.concat(slidePositionArray);
    }
    if (quadrant == 1 || quadrant == 4) {
        // players with video on left
        var leftPositionArray = new Array(
        "PlayerContainer,l," + playerPaddingLeft,
        "btnPoll,l," + playerPadding,
        "btnAskButton,l," + (commandBarPadding + btnPollWidth + commandBarButtonSpacing),
//Atitude Abre
        "btnEmail,l," + (commandBarPadding + btnPollWidth + btnAskButtonWidth + btnLinksWidth + (3 * commandBarButtonSpacing)+30),
        "btnLinks,l," + (commandBarPadding + btnPollWidth + btnAskButtonWidth + (2 * commandBarButtonSpacing)),
        "LiveIndicatorArea,l," + (commandBarPadding + vW - liveIndicatorWidth - playerPadding + 125),
        "LiveIndicatorAreaImg,l," + (commandBarPadding + vW - liveIndicatorWidth - playerPadding + 125),
//Atitude Fecha
	"SlideTicker,l," + (tabsRight + remainingCommandBarSpacing),
        "btnHelp,l," + (pW - btnHelpWidth - applicationVersionAreaWidth - playerMarginRight - (2 * commandBarButtonSpacing)),
        "btnHelpImg,l," + (pW - btnHelpWidth - applicationVersionAreaWidth - playerMarginRight - (2 * commandBarButtonSpacing)),
        "ApplicationVersionArea,l," + (pW - applicationVersionAreaWidth + 2),
        "ApplicationVersionArea,backgroundImage,spinnerL.gif",
        "SlideTabs,l," + tabsLeft,
        "CurrentSlideAreaToolbuttonContainer,l," + (sW - btnHelpWidth - applicationVersionAreaWidth - currentSlideToolbarWidth - (3 * commandBarButtonSpacing)),
        "PresentationCardArea,l," + playerPaddingLeft,
        "ThumbNailsArea,l," + currentSlideAreaLeft,
        "CurrentSlideArea,l," + currentSlideAreaLeft,
        "LinksPanel,l," + (currentSlideAreaLeft + 14),
//Atitude Abre
        "AskQuestionArea,l," + (currentSlideAreaLeft + 74),
//Atitude Fecha
        "EmailInviteArea,l," + (currentSlideAreaLeft + 14)
        );
        changeArray = changeArray.concat(leftPositionArray);
    }

    if (quadrant == 3 || quadrant == 2) {
        // players with video on right
        var tabsLeft = ((playerMarginLeft + sW) - $("btnSlideShowImg").offsetWidth - $("btnSlideListImg").offsetWidth);
        var helpRight = (playerMarginLeft + applicationVersionAreaWidth + (3 * commandBarButtonSpacing) + 5);
        var rightPositionArray = new Array(
        "PlayerContainer,l," + (pW - playerMarginRight - vW - 1),
        "PresentationCardArea,l," + (pW - playerMarginRight - vW - 1),
        "btnPoll,l," + (pW - playerMarginRight - btnPollWidth),
        "btnAskButton,l," + (pW - playerMarginRight - btnPollWidth - btnAskButtonWidth - commandBarButtonSpacing),
//Atitude Abre
        "btnEmail,l," + (pW - playerMarginRight - btnPollWidth - btnAskButtonWidth - btnEmailWidth - (2 * commandBarButtonSpacing)-130),
        "btnLinks,l," + (pW - playerMarginRight - btnPollWidth - btnAskButtonWidth - btnEmailWidth - btnLinksWidth - (3 * commandBarButtonSpacing) - 50),
//Atitude Fecha
        "LiveIndicatorArea,l," + (pW - vW + 2),
        "LiveIndicatorAreaImg,l," + (pW - vW + 2),
        "ThumbNailsArea,l," + playerPaddingLeft,
        "CurrentSlideArea,l," + playerPaddingLeft,
        "ApplicationVersionArea,l," + 0,
        "ApplicationVersionArea,backgroundImage,spinnerR.gif",
        "btnHelp,l," + helpRight,
        "btnHelpImg,l," + helpRight,
        "CurrentSlideAreaToolbuttonContainer,l," + (playerMarginLeft + btnHelpWidth + applicationVersionAreaWidth + (2 * commandBarButtonSpacing)),
        "SlideTicker,l," + (playerMarginLeft + applicationVersionAreaWidth + (2 * commandBarButtonSpacing) + currentSlideToolbarWidth + (2 * Math.floor((this.getRemainingSpaceBetweenElements(helpRight, tabsLeft) - currentSlideToolbarWidth - slideTickerWidth) / 3))),
        "SlideTabs,l," + (tabsLeft + 6),
        "LinksPanel,l," + (playerPaddingLeft + 14),
        "AskQuestionArea,l," + (playerPaddingLeft + 14),
        "EmailInviteArea,l," + (playerPaddingLeft + 14)
        );
        changeArray = changeArray.concat(rightPositionArray);
    }

    if (quadrant == 1 || quadrant == 2) {
        // values for Top Viewers
        var topPositionArray = new Array(
        "PlayerContainer,t," + (titleBannerHeight + commandBarHeight + 2),
        "PresentationCardArea,t," + presentationCardTop
        );
        changeArray = changeArray.concat(topPositionArray);
    }

    if (quadrant == 3 || quadrant == 4) {
        // values for Bottom Viewers
        var bottomPositionArray = new Array(
        "PlayerContainer,t," + (pH - playerMarginBottom - (videoElementPadding + vH + statusBarHeight + playerControlsHeight)),
        "PresentationCardArea,t," + (titleBannerHeight + commandBarHeight + 4)
        );
        changeArray = changeArray.concat(bottomPositionArray);
    }

    if ($('VendorLogo')) {
        var bannerSpecificPositionArray = new Array(
        "backgroundImage,h," + pH,
        "VendorLogo,t," + (pH - LayoutOptions.Images["VendorLogo"].Height - playerMarginBottom)
        );
        if (quadrant == 1 || quadrant == 4) {
            var bannerLeftArray = new Array(
            "VendorLogo,l," + (currentSlideAreaLeft + (((sW + 6) - $('VendorLogo').offsetWidth) / 2))
            );
            changeArray = changeArray.concat(bannerLeftArray);
        }
        if (quadrant == 2 || quadrant == 3) {
            var bannerRightArray = new Array(
            "VendorLogo,l," + (playerPaddingLeft + (((sW + 6) - $('VendorLogo').offsetWidth) / 2))
            );
            changeArray = changeArray.concat(bannerRightArray);
        }
        changeArray = changeArray.concat(bannerSpecificPositionArray);
    }

    // special cases ///////////////
    if (vW == '200' && sW == '1024') {
        var tinyVideoArray = new Array(
        "btnPlayPause,l," + 0,
        "btnSkipback,l," + 24,
        "PlayerSpeedControl,l," + 54,
        "btnCC,l," + 89,
        "btnChapters,l," + 75,
        "btnMute,l," + 114,
        "VolumeSlider,l," + 134,
        "btnFullScreen,l," + 170
        );
        changeArray = changeArray.concat(tinyVideoArray);
        $('PresentationCardAreaDurationLabel').style.display = 'none';
        $('PresentationCardAreaDurationText').style.display = 'none';

        if (mPlayer.PlayerDetect.GetPlayerType() == SfKernel.MediaPlayerType.SL1) {
            var tinyVideoSL1Array = new Array(
            "btnCC,l," + 108,
            "btnChapters,l," + 78,
            "btnMute,l," + 138,
            "VolumeSlider,l," + 158
            );
            changeArray = changeArray.concat(tinyVideoSL1Array);
        }
        else {
            var tinyVideoWMArray = new Array("PlayerSpeedControl,l," + 56);
            changeArray = changeArray.concat(tinyVideoWMArray);
        }
    }

    if (vW == '400' && sW == '360') {
        var remainingWidth = sW + 15;
        $('thumbNailViewButtonSmallThumbnails').style.display = 'none';
        var compactViewerSpecialArray = new Array(
            "EmailInviteArea,w," + remainingWidth,
            "AskQuestionArea,w," + remainingWidth,
            "emailInviteDialogInternalContent,w," + (sW + 7),
            "askQuestionDialogInternalContent,w," + (sW + 7),
            "EmailInviteArea,t," + (titleBannerHeight + commandBarHeight - 5),
            "AskQuestionArea,t," + (titleBannerHeight + commandBarHeight - 5),
            "emailInviteReturnDiv,w," + remainingWidth,
            "askQuestionReturnDiv,w," + remainingWidth,
            "LinksPanel,w," + remainingWidth,
            "emailInviteReturnDiv,marginLeft," + (Math.floor(remainingWidth / 2) * -1),
            "askQuestionReturnDiv,marginLeft," + (Math.floor(remainingWidth / 2) * -1),
            "emailInviteArea_emailInviteMessageFieldtxt,h," + (sH - 86),
            "emailInviteArea_emailInviteMessageFieldtxt,maxH," + (sH - 86),
            "emailInviteArea_emailInviteFromFieldtxt,w," + (remainingWidth - 82),
            "emailInviteArea_emailInviteToFieldtxt,w," + (remainingWidth - 82),
            "emailInviteArea_emailInviteSubjectFieldtxt,w," + (remainingWidth - 82),
            "emailInviteStartingPoint,w," + (remainingWidth - 82),
            "emailInviteArea_emailInviteMessageFieldtxt,w," + (remainingWidth - 82),
            "emailInviteArea_emailInviteMessageFieldtxt,maxW," + (remainingWidth - 82),
// Atitude Abre
            "askQuestionArea_askQuestionMessageFieldtxt,h," + (sH - 57),
            "askQuestionArea_askQuestionMessageFieldtxt,maxH," + (sH - 57),
            "askQuestionArea_askQuestionNameFieldtxt,w," + (remainingWidth - 122),
            "askQuestionArea_askQuestionEmailFieldtxt,w," + (remainingWidth - 122),
            "askQuestionArea_askQuestionSubjectFieldtxt,w," + (remainingWidth - 122),
            "askQuestionArea_askQuestionMessageFieldtxt,w," + (remainingWidth - 122),
            "askQuestionArea_askQuestionMessageFieldtxt,maxW," + (remainingWidth - 122),
            "emailInviteStartingPoint,w," + (remainingWidth - 122),
// Atitude Fecha
            "thumbNailViewButtonLargeThumbnails,l," + 18,
            "thumbNailViewButtonChapters,l," + 36,
            "ApplicationVersionArea,t," + (titleBannerHeight + 2),
            "PresentationCardArea,t," + (titleBannerHeight + commandBarHeight + 4 + sH + currentSlideAreaTopPadding * 2),
            "PresentationCardArea,w," + (sW + (currentSlideAreaLeftPadding * 2)),
            "PresentationCardArea,h," + (pH - (titleBannerHeight + commandBarHeight + 4 + sH + currentSlideAreaTopPadding * 2) - playerMarginBottom - 3),
            "CaptioningContainer,h," + (pH - (titleBannerHeight + commandBarHeight + 4 + sH + currentSlideAreaTopPadding * 2) - playerMarginBottom - 3),
            "PresentationCardAreaScrollDiv,h," + (pH - (titleBannerHeight + commandBarHeight + 4 + sH + currentSlideAreaTopPadding * 2) - playerMarginBottom - presentationCardFooterHeight)
        );
        changeArray = changeArray.concat(compactViewerSpecialArray);

        if (quadrant == 1 || quadrant == 4) {
            var compactViewerSpecialLeftArray = new Array(
            "PresentationCardArea,l," + currentSlideAreaLeft,
            "ApplicationVersionArea,l," + 0,
            "ApplicationVersionArea,backgroundImage,spinnerR.gif",
            "btnHelp,l," + (playerMarginLeft + applicationVersionAreaWidth + (2 * commandBarButtonSpacing) + 4),
            "btnPoll,l," + (playerMarginLeft + applicationVersionAreaWidth + btnHelpWidth + (3 * commandBarButtonSpacing) + 6),
            "btnAskButton,l," + (playerMarginLeft + applicationVersionAreaWidth + btnHelpWidth + btnPollWidth + (4 * commandBarButtonSpacing) + 6),
//Atitude Abre
	    "btnEmail,l," + (playerMarginLeft + applicationVersionAreaWidth + btnHelpWidth + btnPollWidth + btnAskButtonWidth + (5 * commandBarButtonSpacing) + 76),

            "btnLinks,l," + (playerMarginLeft + applicationVersionAreaWidth + btnHelpWidth + btnPollWidth + btnAskButtonWidth + btnLinksWidth + (6 * commandBarButtonSpacing)-8),
//Atitude Fecha
            "SlideTabs,l," + (tabsLeft - 3),
            "SlideTicker,l," + (tabsRight + (sW - currentSlideToolbarWidth - slideTickerWidth - 80) / 2),
            "CurrentSlideAreaToolbuttonContainer,l," + (sW - currentSlideToolbarWidth + 10),
            "EmailInviteArea,l," + (currentSlideAreaLeft - 4),
            "AskQuestionArea,l," + (currentSlideAreaLeft - 4),
            "LinksPanel,l," + (currentSlideAreaLeft - 4)
            );
            changeArray = changeArray.concat(compactViewerSpecialLeftArray);
        }
        if (quadrant == 2 || quadrant == 3) {
            var compactViewerSpecialRightArray = new Array(
            "PresentationCardArea,l," + playerPaddingLeft,
            "ApplicationVersionArea,l," + (pW - applicationVersionAreaWidth - playerMarginRight + 4),
            "ApplicationVersionArea,backgroundImage,spinnerR.gif",
            "btnHelp,l," + (pW - btnHelpWidth - applicationVersionAreaWidth - playerMarginRight - (2 * commandBarButtonSpacing)),
            "btnPoll,l," + (pW - btnHelpWidth - applicationVersionAreaWidth - playerMarginRight - btnPollWidth - (3 * commandBarButtonSpacing)),
            "btnAskButton,l," + (pW - btnHelpWidth - applicationVersionAreaWidth - playerMarginRight - btnPollWidth - btnAskButtonWidth - (4 * commandBarButtonSpacing)),
            "btnEmail,l," + (pW - btnHelpWidth - applicationVersionAreaWidth - playerMarginRight - btnPollWidth - btnAskButtonWidth - btnLinksWidth - (5 * commandBarButtonSpacing)),
            "btnLinks,l," + (pW - btnHelpWidth - applicationVersionAreaWidth - playerMarginRight - btnPollWidth - btnAskButtonWidth - btnLinksWidth - btnEmailWidth - (6 * commandBarButtonSpacing)),
            "SlideTabs,l," + (tabsLeft + 5),
            "SlideTicker,l," + (tabsLeft - slideTickerWidth - 24),
            "CurrentSlideAreaToolbuttonContainer,l," + (playerMarginLeft),
            "EmailInviteArea,l," + (playerMarginLeft - 5),
            "AskQuestionArea,l," + (playerMarginLeft - 5),
            "LinksPanel,l," + (playerMarginLeft - 5)
            );
            changeArray = changeArray.concat(compactViewerSpecialRightArray);
        }
    }
    else if (sW == 0 || sH == 0) {
        var presentationCardHeight = vH + statusBarHeight + playerControlsHeight;
        var noSlidesSpecialArray = new Array(
            "ApplicationVersionArea,t," + (titleBannerHeight + 2),
            "PresentationCardArea,t," + (titleBannerHeight + 2 + commandBarHeight),
            "ThumbNailsArea,t," + (titleBannerHeight + 10 + commandBarHeight),
            "PresentationCardArea,w," + presentationCardWidth,
            "PresentationCardArea,h," + presentationCardHeight,
            "CaptioningContainer,h," + presentationCardHeight,
            "PresentationCardAreaScrollDiv,h," + (vH + statusBarHeight + playerControlsHeight + 1 - presentationCardFooterHeight),
            "LinksPanel,w," + (presentationCardWidth),
            "EmailInviteArea,w," + (presentationCardWidth),
            "emailInviteReturnDiv,w," + (presentationCardWidth),
            "emailInviteReturnDiv,marginLeft," + (Math.floor((presentationCardWidth) / 2) * -1),
            "emailInviteArea_emailInviteMessageFieldtxt,h," + (presentationCardHeight - 179),
            "emailInviteArea_emailInviteMessageFieldtxt,maxH," + (presentationCardHeight - 179),
            "emailInviteArea_emailInviteFromFieldtxt,w," + (presentationCardWidth - 80),
            "emailInviteArea_emailInviteToFieldtxt,w," + (presentationCardWidth - 80),
            "emailInviteArea_emailInviteSubjectFieldtxt,w," + (presentationCardWidth - 80),
            "emailInviteStartingPoint,w," + (presentationCardWidth - 80),
            "emailInviteArea_emailInviteMessageFieldtxt,w," + (presentationCardWidth - 80),
            "emailInviteArea_emailInviteMessageFieldtxt,maxW," + (presentationCardWidth - 80),
            "AskQuestionArea,w," + (presentationCardWidth),
            "ChapterPointsPanelDialog,w," + (presentationCardWidth),
            "ChapterPointsPanelDialog,h," + (presentationCardHeight),
            "ChapterPointsPanelDialogMessage,h," + (presentationCardHeight - 25),
            "ChapterPointsPanelDialogMessage,w," + (presentationCardWidth),
            "ChapterPointsPanelDialog,t," + (0),
            "askQuestionReturnDiv,w," + (presentationCardWidth),
            "askQuestionReturnDiv,marginLeft," + (Math.floor((presentationCardWidth) / 2) * -1),
            "askQuestionArea_askQuestionMessageFieldtxt,h," + (presentationCardHeight - 150),
            "askQuestionArea_askQuestionMessageFieldtxt,maxH," + (presentationCardHeight - 150),
            "askQuestionArea_askQuestionNameFieldtxt,w," + (presentationCardWidth - 80),
            "askQuestionArea_askQuestionEmailFieldtxt,w," + (presentationCardWidth - 80),
            "askQuestionArea_askQuestionSubjectFieldtxt,w," + (presentationCardWidth - 80),
            "askQuestionArea_askQuestionMessageFieldtxt,w," + (presentationCardWidth - 80),
            "askQuestionArea_askQuestionMessageFieldtxt,maxW," + (presentationCardWidth - 80),
            "emailInviteStartingPoint,w," + (presentationCardWidth - 80),
            "LinksPanelContainer,h," + linksPanelHeight
        );
        changeArray = changeArray.concat(noSlidesSpecialArray);

        if (quadrant == 1 || quadrant == 4) {
            var noSlidesSpecialLeftArray = new Array(
            "ThumbNailsArea,l," + playerMarginLeft,
            "PresentationCardArea,l," + (vW + 2 + playerRemainingSpace),
            "ApplicationVersionArea,l," + (pW - applicationVersionAreaWidth),
            "ApplicationVersionArea,backgroundImage,spinnerR.gif",
            "btnHelp,l," + (pW - applicationVersionAreaWidth - (3 * commandBarButtonSpacing) - btnHelpWidth - 9),
            "btnPoll,l," + (playerMarginLeft + (3 * commandBarButtonSpacing) + 12),
            "btnAskButton,l," + (playerMarginLeft + btnPollWidth + (4 * commandBarButtonSpacing) + 12),
            "btnEmail,l," + (playerMarginLeft + btnPollWidth + btnAskButtonWidth + (5 * commandBarButtonSpacing) + 12),
            "btnLinks,l," + (playerMarginLeft + btnPollWidth + btnAskButtonWidth + btnLinksWidth + (6 * commandBarButtonSpacing) + 12),
            "EmailInviteArea,l," + (vW + playerMarginLeft),
            "AskQuestionArea,l," + (vW + playerMarginLeft),
            "LinksPanel,l," + (vW + playerMarginLeft)
            );
            changeArray = changeArray.concat(noSlidesSpecialLeftArray);
        }
        if (quadrant == 2 || quadrant == 3) {
            var noSlidesSpecialRightArray = new Array(
            "ThumbNailsArea,l," + (pW - playerMarginRight - 110),
            "PresentationCardArea,l," + (playerPaddingLeft - 1),
            "ApplicationVersionArea,l," + playerMarginLeft,
            "ApplicationVersionArea,backgroundImage,spinnerL.gif",
            "btnHelp,l," + (pW - btnHelpWidth - playerMarginRight - (2 * commandBarButtonSpacing) - 4),
            "btnPoll,l," + (pW - btnHelpWidth - playerMarginRight - btnPollWidth - (3 * commandBarButtonSpacing)),
            "btnAskButton,l," + (pW - btnHelpWidth - playerMarginRight - btnPollWidth - btnAskButtonWidth - (4 * commandBarButtonSpacing)),
            "btnEmail,l," + (pW - btnHelpWidth - playerMarginRight - btnPollWidth - btnAskButtonWidth - btnLinksWidth - (5 * commandBarButtonSpacing)),
            "btnLinks,l," + (pW - btnHelpWidth - playerMarginRight - btnPollWidth - btnAskButtonWidth - btnLinksWidth - btnEmailWidth - (6 * commandBarButtonSpacing)),
            "EmailInviteArea,l," + (0),
            "AskQuestionArea,l," + (0),
            "LinksPanel,l," + (0)
            );
            changeArray = changeArray.concat(noSlidesSpecialRightArray);
        }
        this.HideSlides();
    }
    else {
        var presentationCardArray = new Array(
            "PresentationCardArea,w," + vW,
            "PresentationCardArea,h," + (presentationCardHeight - 3),
            "CaptioningContainer,h," + (presentationCardHeight - 3),
            "PresentationCardAreaScrollDiv,h," + (presentationCardHeight - presentationCardFooterHeight - 3)
        );
        changeArray = changeArray.concat(presentationCardArray);
    }
    return changeArray;
}

ChangePosition.HideSlides=function()
{
    $('SlideTicker').style.display = 'none';
    $('CurrentSlideArea').style.display = 'none';
    $('SlideTabs').style.display = 'none';
    $('ThumbNailsArea').style.display = 'none';
}

ChangePosition.SetPositions=function(changeArray)
{
    for (var changeNum=0; changeNum<changeArray.length; changeNum++)
    {
       var thisChange = changeArray[changeNum].split(",");
       if(document.getElementById(thisChange[0]) != null)
       {
           switch(thisChange[1])
           {
            case "h":
                this.setHeight(thisChange[0],thisChange[2]);
                break;
            case "w":
                this.setWidth(thisChange[0],thisChange[2]);
                break;
            case "l":
                this.setPos(thisChange[0],'left',thisChange[2]);
                break;
            case "r":
                this.setPos(thisChange[0],'right',thisChange[2]);
                break;
            case "t":
                this.setPos(thisChange[0],'top',thisChange[2]);
                break;
            case "marginTop":
                this.setMargin(thisChange[0],'top',thisChange[2]);
                break;
            case "marginRight":
                this.setMargin(thisChange[0],'right',thisChange[2]);
                break;
            case "marginBottom":
                this.setMargin(thisChange[0],'bottom',thisChange[2]);
                break;
            case "marginLeft":
                this.setMargin(thisChange[0],'left',thisChange[2]);
                break;
            case "paddingTop":
                this.setPadding(thisChange[0],'top',thisChange[2]);
                break;
            case "paddingRight":
                this.setPadding(thisChange[0],'right',thisChange[2]);
                break;
            case "paddingBottom":
                this.setPadding(thisChange[0],'bottom',thisChange[2]);
                break;
            case "paddingLeft":
                this.setPadding(thisChange[0],'left',thisChange[2]);
                break;
            case "backgroundImage":
                this.backgroundImageSwap(thisChange[0],thisChange[2]);
                break;
            case "img":
                this.imgSwap(thisChange[0],thisChange[2]);
                break;
            case "vis":
                this.setVisible(thisChange[0],thisChange[2]);
                break;
            case "cssW":
                this.setCSS(thisChange[0],'width',thisChange[2]);
                break;
            case "cssL":
                this.setCSS(thisChange[0],'left',thisChange[2]);
                break;
            case "maxH":
                this.setMaxHeight(thisChange[0], thisChange[2]);
                break;
            case "maxW":
                this.setMaxWidth(thisChange[0], thisChange[2]);
                break;
            }
        }
    }
}

ChangePosition.setMargin=function(e,dir,val)
{
    var E = $(e);
    switch(dir)
    {
    case "top":
        E.style.marginTop=this.withPX(val);
        break;
    case "right": 
        E.style.marginRight=this.withPX(val);
        break;
    case "bottom":
        E.style.marginBottom=this.withPX(val);
        break;
    case "left":   
        E.style.marginLeft=this.withPX(val);
        break;
    }
}


ChangePosition.setPadding=function(e,dir,val)
{
    var E = $(e);
    switch(dir)
    {
    case "top":
        E.style.paddingTop=this.withPX(val);
        break;
    case "right": 
        E.style.paddingRight=this.withPX(val);
        break;
    case "bottom":
        E.style.paddingBottom=this.withPX(val);
        break;
    case "left":   
        E.style.paddingLeft=this.withPX(val);
        break;
    }
}

ChangePosition.getRemainingSpaceBetweenElements=function(leftStop, rightStop)
{
    var spacing = (rightStop - leftStop);
    return spacing;
}
     
ChangePosition.withPX=function(val){return val + "px";}
ChangePosition.setFloat=function(e,f)
{
    $(e).style.cssFloat = f;
    $(e).style.styleFloat = f; /* for old IE */
}

ChangePosition.setZ=function(e,zIndex){$(e).style.zIndex = zIndex;}
ChangePosition.setHeight=   function(e, height){$(e).style.height = this.withPX(height);}
ChangePosition.setWidth=    function(e, width) {$(e).style.width = this.withPX(width); }
ChangePosition.setMaxHeight=function(e, height){$(e).style.maxHeight = this.withPX(height);}
ChangePosition.setMaxWidth= function(e, width) {$(e).style.maxWidth = this.withPX(width);}
ChangePosition.setPos=function(e,direction,val)
{
    var E = $(e);
    switch(direction)
    {
    case "top":
        E.style.top=this.withPX(val);
        break;
    case "right": 
        E.style.right=this.withPX(val);
        break;
    case "bottom":
        E.style.bottom=this.withPX(val);
        break;
    case "left":   
        E.style.left=this.withPX(val);
        break;
    }
}

ChangePosition.imgSwap=function(e,ImageVariant)
{
    /* parses img url, returns old url but with new filename */
    var imageElement = $(e);
    var imgUrl = imageElement.src;
    imgUrl = imgUrl.split("/");
    var oldFileName = imgUrl.pop();
    imgUrl = imgUrl.join("/");
    imgUrl = imgUrl + "/" + ImageVariant;
    imageElement.src = imgUrl;
}

ChangePosition.setCSS=function(theClass,element,value) 
{
	var cssRules;
	if (document.all) 
	{
	    cssRules = 'rules';
	}
	else if (document.getElementById) 
	{
	    cssRules = 'cssRules';
	}
	for (var s = 0; s < document.styleSheets.length; s++)
	{
	    for (var r = 0; r < document.styleSheets[s][cssRules].length; r++) 
	    {
	        if (document.styleSheets[s][cssRules][r].selectorText == theClass) 
	        {
	            document.styleSheets[s][cssRules][r].style[element] = value;
	        }
	    }
    }
}

ChangePosition.backgroundImageSwap=function(e,ImageVariant)
{
    $(e).style.backgroundImage = 'url(' + LayoutOptions.ThemeImageBase + '/' + ImageVariant + ')';
}

ChangePosition.setClass=function(e,newClass)
{    
    $(e).className = newClass;
}

ChangePosition.setVisible=function(e,visibility)
{   
    var E = $(e);
    if(E != null)
    {
        if(visibility ==  "true" || visibility == true){E.style.display = "block";}
        else {E.style.display = "none";}
    }
}

ChaptersPanel = function ChaptersPanel(container, containingWindow, id) {
    ChaptersPanel.initializeBase(this, [container, containingWindow, id, false]);
}
ChaptersPanel.prototype = {
    _chaptersContainer: null,
    _chaptersMessage: null,
    _closeButton: null,
    _chaptersTitleText: null,
    _isHeightInitialized: false,
    IsShowing: false,

    OnLoad: function ChaptersPanel$OnLoad() {
        this._initialize();
    },

    OnUnLoad: function ChaptersPanel$OnUnLoad() {
    },

    _initialize: function ChaptersPanel$_initialize() {
        if (Manifest.Chapters.length < 1) {
            if ($('btnChapters')) {$('btnChapters').style.display = "none";}
            this.Hide();
            return;
        }

        this._chaptersTitleText = $('ChapterPointsPanelTitleText');
        SfKernel.Util.SetText(this._chaptersTitleText, Localization.ThumbnailsResource.Chapters);

        this._closeButton = $('ChapterPointsPanelCloseButton');
        this._closeButton.setAttribute('title', Localization.LinksResource.Close);
        this._closeButton.observe('mouseover', Function.createDelegate(this, this._closeButtonOnMouseOver));
        this._closeButton.observe('mouseout', Function.createDelegate(this, this._closeButtonOnMouseOut));
        this._closeButton.observe('click', Function.createDelegate(this, this._closeButtonOnClick));
        this._chaptersMessage = $('ChapterPointsPanelDialogMessage');
        this.elements = new Array(Manifest.Chapters.length);
        for (var i = 0; i < Manifest.Chapters.length; ++i) {
            this._addChapterElement(i + 1);
            this.elements[i] = new ChapterPointElement(this, i + 1, Manifest.Chapters[i].Time);
            this.elements[i].addEvents();
        }
        this._chaptersContainer = $('ChapterPointsPanel');
    },

    Show: function ChaptersPanel$Show() {
        $(this.ID).style.display = 'block';
        this.IsShowing = true;
        // firefox 2 on mac has an issue with scrollbars showing through, so we disable them when we pop a box.
        if ($('CurrentSlideArea').offsetLeft == ($('PresentationCardArea').offsetLeft + 1)) {
            $('PresentationCardAreaScrollDiv').style.overflowY = 'hidden';
        }
    },

    Hide: function ChaptersPanel$Hide() {
        $(this.ID).style.display = 'none';
        this.IsShowing = false;
    },

    _initializeHeight: function ChaptersPanel$_initializeHeight() {
        var containerHeight = this.GetDiv().getHeight() - $(this.ID + 'Heading').getHeight() - 2;
        $(this.ID + 'Container').setStyle({ height: containerHeight + 'px' });
        this._isHeightInitialized = true;
    },

    _onPlay: function ChaptersPanel$_onPlay(sender, args) {
    },

    _closeButtonOnMouseOver: function ChaptersPanel$_closeButtonOnMouseOver(sender, args) {
        this._closeButton.className = 'dialogCloseButtonOver';
    },

    _closeButtonOnMouseOut: function ChaptersPanel$_closeButtonOnMouseOut(sender, args) {
        this._closeButton.className = 'dialogCloseButtonNormal';
    },

    _closeButtonOnClick: function ChaptersPanel$_closeButtonOnClick(sender, args) {
        this._closeButton.className = 'dialogCloseButtonNormal'; //add onclick state?
        this.Hide();
    },

    _addChapterElement: function(chapterNumber) {
        var div1 = this._createDiv('chapterDiv' + chapterNumber, 'chapterItem', null);
        this._chaptersMessage.appendChild(div1);
        var div2 = this._createDiv('chapterNumberSpan' + chapterNumber, 'chapterNumber', 'Chapter ' + chapterNumber);
        div1.appendChild(div2);
        var div3 = this._createDiv('chapterTimeSpan' + chapterNumber, 'chapterTime', SfKernel.GetDisplayDuration(Manifest.Chapters[chapterNumber - 1].Time));
        div1.appendChild(div3);
        var div4 = this._createDiv('chapterTitleSpan' + chapterNumber, 'chapterTitle', SfKernel.EncodeClean(Manifest.Chapters[chapterNumber - 1].Text));
        div4.title = SfKernel.EncodeClean(Manifest.Chapters[chapterNumber - 1].Text);
        div1.appendChild(div4);
    },

    _createDiv: function(id, className, text) {
        var element = $(document.createElement('div'));
        element.setAttribute('id', id);
        element.className = className;
        if (text) {
            SfKernel.Util.SetText(element, text);
        }
        return element;
    }
}    

ChapterPointElement = function(parentArea, chapterNumber, timing) {
    this._parentArea = parentArea;
    this._chapterNumber = chapterNumber;
    this._timing = timing;
    this._titleElement = $('chapterTitleSpan' + this._chapterNumber);
    this._chapterElement = $('chapterDiv' + this._chapterNumber);

    this.addEvents = function() {
        this._chapterElement.observe('mouseover', Function.createDelegate(this, function(sender, args) {
            this._chapterElement.className = 'chapterItemOver';
            this._titleElement.className = 'chapterTitleOver';
            SfKernel.Util.SetCursor(this._chapterElement, SfKernel.CursorType.Hand);
        }));
        this._chapterElement.observe('mouseout', Function.createDelegate(this, function(sender, args) {
            this._chapterElement.className = 'chapterItem';
            this._titleElement.className = 'chapterTitle';
            SfKernel.Util.SetCursor(this._chapterElement, SfKernel.CursorType.Default);
        }));
        this._chapterElement.observe('click', Function.createDelegate(this, function(sender, args) {
            mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.NavigateToChapter, this, { Number: this._chapterNumber, Time: this._timing });
        }));
        this._chapterElement.observe('dblclick', Function.createDelegate(this, function(sender, args) {
            mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.NavigateToChapter, this, { Number: this._chapterNumber, Time: this._timing });
            mPlayer.btnSlideShowInstance.OnClick();
        }));
    }
}

LinksPanel = function LinksPanel(container, containingWindow, id) {
    LinksPanel.initializeBase(this, [ container, containingWindow, id, false ]);
}
LinksPanel.prototype = {
    _linksContainer: null,
    _closeButton: null,
    _linksTitleText: null,
    _isHeightInitialized: false,
    IsShowing: false,
    
    OnLoad: function LinksPanel$OnLoad() {
        this._initialize();
    }, 
    
    OnUnLoad: function LinksPanel$OnUnLoad() {
    },
    
    _initialize: function LinksPanel$_initialize() {
        if (Manifest.SupportingLinks.length < 1) {
            this.Hide();
            return;
        }
        
        this._linksTitleText = $(this.ID + 'LinksTitleText');
        SfKernel.Util.SetText(this._linksTitleText, Localization.LinksResource.PresentationLinks);
        
        this._closeButton = $(this.ID + 'CloseButton');
        this._closeButton.setAttribute('title', Localization.LinksResource.Close);
        this._closeButton.observe('mouseover', Function.createDelegate(this, this._closeButtonOnMouseOver));
        this._closeButton.observe('mouseout', Function.createDelegate(this, this._closeButtonOnMouseOut));
        this._closeButton.observe('click', Function.createDelegate(this, this._closeButtonOnClick));
        
        this._linksContainer = $(this.ID + 'Container');
        for (var i = 0; i < Manifest.SupportingLinks.length; ++i) 
        {
            this._appendLinkElement(Manifest.SupportingLinks[i], (!(i % 2)));
        }
    },
    
    Show: function LinksPanel$Show() {
        $(this.ID).style.display = 'block';
        this.IsShowing = true;
        // firefox 2 on mac has an issue with scrollbars showing through, so we disable them when we pop a box.
        if($('CurrentSlideArea').offsetLeft == ($('PresentationCardArea').offsetLeft+1))
        {
            $('PresentationCardAreaScrollDiv').style.overflowY = 'hidden';
        }	
    },
    
    Hide: function LinksPanel$Hide() {
        $(this.ID).style.display = 'none';
        this.IsShowing = false;
    },
    
    _initializeHeight: function LinksPanel$_initializeHeight() {
        var containerHeight = this.GetDiv().getHeight() - $(this.ID + 'Heading').getHeight() - 2;
        $(this.ID + 'Container').setStyle({ height: containerHeight + 'px' });
        this._isHeightInitialized = true;
    },
    
    _onPlay: function LinksPanel$_onPlay(sender, args) {
    },
    
    _closeButtonOnMouseOver: function LinksPanel$_closeButtonOnMouseOver(sender, args) {
        this._closeButton.className = 'dialogCloseButtonOver';
    },
    
    _closeButtonOnMouseOut: function LinksPanel$_closeButtonOnMouseOut(sender, args) {
        this._closeButton.className = 'dialogCloseButtonNormal';
    }, 
     
    _closeButtonOnClick: function LinksPanel$_closeButtonOnClick(sender, args) {
        this._closeButton.className = 'dialogCloseButtonNormal'; //add onclick state?
        this.Hide();
    },   
    
    _appendLinkElement: function LinksPanel$_appendLinkElement(link, isEven) {
        var element = document.createElement('div');
        this._linksContainer.appendChild(element);
        element.className = (isEven) ? 'linksItem' : 'linksItemAlt';
        var a = document.createElement('a');
        element.appendChild(a);
        a.setAttribute('href', link.Url);
        a.setAttribute('target', 'new');
        a.setAttribute('title', link.Url);
        a.appendChild(document.createTextNode(link.Description));
    }
}
function WindowHelper(){}
    
    WindowHelper.PopupNames =
    {
        FullSize : "FullSize",
	    Help : "Help",
	    ShowPolls : "ShowPolls",
	    PreviewSlide : "PreviewSlide"
    }

	WindowHelper.IsOpen = function (wnd)
	{
		if (!wnd)
		{
			return false;
		}
		if (wnd == null)
		{
			return false;
		}
		if (wnd.closed == true)
		{
			return false;
		}
		return true;
	}

	WindowHelper.CreateNamedPopup=function(popupName, name, width, height, scrollbars, resizeable)
	{
		return this.CreatePopup(WindowHelper.GetPopupURL(popupName), name, width, height, scrollbars, resizeable);
	}

	WindowHelper.CreatePopup=function(sUrl,sName,nWidth,nHeight,fScrollbars,fResizeable)
	{
		// extra offset for mac
		var offsetX = 0;
		var offsetY = 0;

		nWidth=Math.floor(nWidth) + offsetX;
		nHeight=Math.floor(nHeight) + offsetY;

		var sFeatures = "width=" + nWidth + ",height=" + nHeight;
	       
		if (fScrollbars)
		{
			sFeatures += ",scrollbars=yes";
		}
		else
		{
			sFeatures += ",scrollbars=no";
		}
	        
		if (fResizeable)
		{
			sFeatures += ",resizable=yes";
		}
		else
		{
			sFeatures += ",resizable=no";
		}

		this.PlayerDetect = new SfKernel.PlayerDetect();
		var popup = window.open(sUrl, sName, sFeatures);
		
		if(popup)
		{
		    if(!this.PlayerDetect.IsChrome())
		    {
		        // chrome has troubles positioning after resize
		        this.Center(popup, nWidth, nHeight);
		    }
		}		
		return popup;
	}

	WindowHelper.Center=function(wnd,nWidth,nHeight)
	{
		var posX = Math.round((screen.availWidth-nWidth)/2);
		var posY = Math.round((screen.availHeight - nHeight) / 2);
		wnd.moveTo(posX,posY);
	}

	WindowHelper.PopupHelp = function(sUrl, nWidth, nHeight) {
	    window.popuphelp = this.CreatePopup(sUrl, "__help", nWidth, nHeight, true, true);
	    if (!this.PlayerDetect.IsChrome()) {
	        WindowHelper.Center(window.popuphelp, nWidth, nHeight);
	    }
	    window.popuphelp.focus();
	}

	WindowHelper.MaximizeOrCenter = function(wnd, width, height)
	{
		if (WindowHelper.IsWidthOrHeightGreater(width, height))
		{
			WindowHelper.Maximize(wnd);
		}
		else
		{
			WindowHelper.Center(wnd, width, height);
		}
	}

	WindowHelper.Maximize = function(wnd) {
	    wnd.resizeTo(screen.availWidth, screen.availHeight);
	    if (!this.PlayerDetect.IsChrome()) {
	        wnd.moveTo(0, 0);
	    }
	}

	WindowHelper.IsWidthOrHeightGreater = function(width, height)
	{
		var screenWidth = screen.availWidth;
		var screenHeight = screen.availHeight;
		
		if (width > screenWidth || height > screenHeight)
		{
			return true;
			
		}
		else
		{
			return false;
		}
	}
	
    WindowHelper.GetPopupURL = function(popupName)
    {
	    switch (popupName)
	    {
		    case WindowHelper.PopupNames.Help:
		        if(Manifest.IsStandAlone)
		        {
		            //return GlobalOptions.AppRoot + "/Players/Popups/Help/Overview.htm";
				 return "http://suporte.webmeeting.com.br/escolhe.asp"
		        }
		        else
		        {
			     //   return GlobalOptions.AppRoot + "/Popups/Help/OverviewFullVersion.htm";
				return "http://suporte.webmeeting.com.br/escolhe.asp"
			    }
		    case WindowHelper.PopupNames.ShowPolls:
			    //return GlobalOptions.AppRoot + "/Popups/Polls/PollList.aspx?" + SfKernel.RequestVariables.PlaybackTicketId + "=" + Manifest.PlaybackTicketId;
		    URLCompleta = document.location.search;
				RemoverString = "http://application.webmeeting.com.br/WebMeeting2009/Viewer/";
				URLEnquete = URLCompleta.replace(RemoverString,"");
				return "http://application.webmeeting.com.br/enquetes.asp" + URLEnquete;


		    case WindowHelper.PopupNames.PreviewSlide:
			    return GlobalOptions.AppRoot + "/" + LayoutOptions.PreviewViewer;
		    case WindowHelper.PopupNames.FullSize:
			    return GlobalOptions.AppRoot + "/" + LayoutOptions.FullSizeViewer;
	    }
    }


Type.registerNamespace('SfUI');

SfUI.ButtonType = function() { };
SfUI.ButtonType.prototype = {
    Push: 0, 
    Check: 1
}
SfUI.ButtonType.registerEnum('SfUI.ButtonType', false);

SfUI.Button = function SfUI_Button(id) {
    this._buttonType = SfUI.ButtonType.Push;
    this._id = id;
    this._link = $(this._id + 'Link');
    this._img = $(this._id + 'Img');
    this._link.observe('mouseover', Function.createDelegate(this, function(sender, args) {
        this._isHilited = true;
        this._paint();
    }));
    this._link.observe('mouseout', Function.createDelegate(this, function(sender, args) {
        this._isHilited = false;
        this._paint();
    }));
    this._link.observe('mouseup', Function.createDelegate(this, function(sender, args) {
        this._isPressed = true;
        this._paint();
    }));
    this._link.observe('mousedown', Function.createDelegate(this, function(sender, args) {
        this._isPressed = false;
        this._paint();
    }));
    this._link.observe('click', Function.createDelegate(this, function(sender, args) {
        this._isPressed = false;
        if (this._enabled) {
            if (this._click) {
                this._click(this, Sys.EventArgs.Empty);
            }
        }
        this._paint();
    }));
    this._link.observe('dblclick', Function.createDelegate(this, function(sender, args) {
        this._isPressed = false;
        if (this._enabled) {
            if (this._dblClick) {
                this._dblClick(this, Sys.EventArgs.Empty);
            }
        }
        this._paint();
    }));
    this._images = new Array(2);
    this._images[0] = new SfUI.ButtonImage();
    this._images[1] = new SfUI.ButtonImage();
}
SfUI.Button.prototype = {
    _link: null,
    _img: null,
    _id: null,
    _enabled: true,
    _isHilited: false,
    _isPressed: false,
    _isChecked: false,
    _images: null,
    _click: null,
    _dblClick: null,
    
    SetButtonType: function Buttons_Button$SetButtonType(type) {
        this._buttonType = type;
    },
    
    SetChecked: function Buttons_Button$SetChecked(isChecked) {
        if (this._buttonType !== SfUI.ButtonType.Check) {
            throw Error.invalidOperation('Button must be check type');
        }
        this._isChecked = isChecked;
        this._paint();
    },
    
    GetChecked: function Buttons_Button$GetChecked() {
        return this._isChecked;
    },
    
    SetNormalImage: function Buttons_Button$SetNormalImage(index, val) {
        this._images[index].set_normal(val);
    },
    
    SetOverImage: function Buttons_Button$SetOverImage(index, val) {
        this._images[index].set_over(val);
    },
    
    SetPressedImage: function Buttons_Button$SetPressedImage(index, val) {
        this._images[index].set_pressed(val);
    },
    
    SetDisabledImage: function Buttons_Button$SetDisabledImage(index, val) {
        this._images[index].set_disabled(val);
    },
    
    Enable: function Buttons_Button$Enable(enabled) {
        this._enabled = enabled;
        this._paint();
    },
    
    Initialize: function Buttons_Button$Initialize() {
        this._paint();
    },
    
    SetTooltip: function Buttons_Button$SetTooltip(val) {
        this._link.setAttribute('title', val);
        this._img.setAttribute('alt', val);
    },
    
    SetClickHandler: function Buttons_Button$SetClickHandler(handler) {
        this._click = handler;
    },
    
    SetDblClickHandler: function Buttons_Button$SetDblClickHandler(handler) {
        this._dblClick = handler;
    },
    
    _paint: function Buttons_Button$_paint() {    
        var imageSrc = this._getCurrentImageSrcFromButtonImage(this._getCurrentButtonImage());    
        if(imageSrc != null)
        {
            this._img.setAttribute('src', imageSrc);
        }
    },
    
    _getCurrentButtonImage: function Buttons_Button$_getCurrentButtonImage() {
        if (this._buttonType === SfUI.ButtonType.Push) {
            return this._images[0];
        }
        else {
            if (this._isChecked) {
                return this._images[1];
            }
            else {
                return this._images[0];
            }
        }
    },
    
    _getCurrentImageSrcFromButtonImage: function Buttons_Button$_getCurrentImageSrcFromButtonImage(currentImage) {
        if (!this._enabled) {
            if(this._link){this._link.setStyle({ cursor: 'default' })};
            return currentImage.get_disabled();
        }
        if (this._isPressed) {
            if (currentImage.get_pressed()) {
                return currentImage.get_pressed();
            }
            else {
                return currentImage.get_normal();
            }
        }
        if (this._isHilited) {
            return currentImage.get_over();
        }
        if(this._link){this._link.setStyle({ cursor: 'pointer' })};
        return currentImage.get_normal();
    }
}

SfUI.Button.registerClass('SfUI.Button');


SfUI.ButtonImage = function SfUI_ButtonImage() {}
SfUI.ButtonImage.prototype = {
    _normal: null,
    
    get_normal: function Buttons_ButtonImage$get_normal() {
        return this._normal;
    },
    set_normal: function Buttons_ButtonImage$set_normal(value) {
        this._normal = value;
        return value;
    },
    
    _over: null,
    
    get_over: function Buttons_ButtonImage$get_over() {
        return this._over;
    },
    set_over: function Buttons_ButtonImage$set_over(value) {
        this._over = value;
        return value;
    },
    
    _pressed: null,
    
    get_pressed: function Buttons_ButtonImage$get_pressed() {
        return this._pressed;
    },
    set_pressed: function Buttons_ButtonImage$set_pressed(value) {
        this._pressed = value;
        return value;
    },
    
    _disabled: null,
    
    get_disabled: function Buttons_ButtonImage$get_disabled() {
        return this._disabled;
    },
    set_disabled: function Buttons_ButtonImage$set_disabled(value) {
        this._disabled = value;
        return value;
    }
}

SfUI.ButtonImage.registerClass('SfUI.ButtonImage');

Type.registerNamespace('SfImage');

SfImage.CachedImageStatus = function()
{
    Error = "Error";
    Complete = "Complete";
    Loading = "Loading";
}

SfImage.ImageCache = function(container)
{
	this.Container = container;
	this.CachedImages = new Array();
	this.NumItemsToCache = 1;
 	
	this.AddImage = function(url, shouldDelayLoad)
	{
		if (shouldDelayLoad == true)
		{
			// random time between 2 and 4 seconds
			var randomTime = Math.floor(2000*Math.random() +2000);
			setTimeout(this.Container + '.Internal_AddImage("' + url + '")', randomTime);
		}
		else
		{	
			this.Internal_AddImage(url);
		}
	}
		
	this.Internal_AddImage = function(url)
	{
		var length = this.CachedImages.length;
		var currentIndex = 0;
		if (length >= this.NumItemsToCache)
		{
			currentIndex = length-1;
		}
		else
		{
			currentIndex = length;
		}
		
		var cachedImage = new CachedImage(url, this.Container + ".CachedImages[" + currentIndex + "]");
		this.CachedImages[currentIndex] = cachedImage;
		cachedImage.Load();
	}
	
	this.FindInCache = function(url)
	{
		var i;
		for (i=0; i<this.CachedImages.length; ++i)
		{
			if (this.CachedImages[i].Source == url)
			{
				return this.CachedImages[i]; 
			}
		}
		return null;
	}
	
	function CachedImage(source, container)
	{
		this.Source = source;
		this.Container = container;
		this.Status = SfImage.CachedImageStatus.Loading;
		
		this.Load = function()
		{
			this.Img = new Image();
			this.Img.onerror = new Function("", this.Container + ".OnError()");
			this.Img.onload = new Function("", this.Container + ".OnLoad()");
			this.Img.src = this.Source;
		}
		
		this.OnError = function()
		{
			this.Status = SfImage.CachedImageStatus.Error;
		}	
		
		this.OnLoad = function()
		{
			this.Status = SfImage.CachedImageStatus.Complete;
		}
		
		this.toString = function()
		{
			var retVal =
				"Source: " + this.Source + 
				", Status: " + this.Status
			return retVal;
		}
	}
}

Type.registerNamespace('SfImage.Popup');

SfImage.Popup.Position = function()
{
	Top = 0;
	Right = 1;
	Left = 2;
	Bottom = 3;
}

SfImage.Popup.PositionCalculator = function(containerDimension, boxDimension)
{
	this._separation = 4;// is the gap
	this._paddingLeft = 5;//padding shortens the container
	this._paddingRight = 20;
	this._paddingTop = 0;
	this._containerDimension = containerDimension;
	this._boxDimension = boxDimension;
}

SfImage.Popup.PositionCalculator.prototype =
{
	_CreateParams : function(location)
	{
		var params = new Object();
		params.t = location.Top - this._paddingTop - this._separation;
		params.l = location.Left - this._paddingLeft - this._separation;
		params.w = location.Width + 2 * this._separation;
		params.h = location.Height + 2 * this._separation;
		
		params.CW = this._containerDimension.Width - (this._paddingLeft + this._paddingRight);
		params.CH = this._containerDimension.Height - this._paddingTop;
		
		params.W = this._boxDimension.Width;
		params.H = this._boxDimension.Height;
		
		return params;
	},
	
	GetPopupPosition : function(location)
	{
		var params = this._CreateParams(location);
		var calc = new SfImage.Popup.RawPopupCalculator(params);
		var pos = calc.GetPosition();
		pos.Left = pos.Left + this._paddingLeft;
		pos.Top = pos.Top + this._paddingTop;
		return pos;
    }
}

SfImage.Popup.RawPopupCalculator = function(params)
{
	this._params = params;
	// right	
	//	popup.style.top = t + h/2 - H/2;
	//	popup.style.left = l + w;	

	// left
	//	popup.style.top = t + h/2 - H/2;
	//	popup.style.left = l - W;
		
	// top	
	//	popup.style.top = t - H;
	//	popup.style.left = l + w/2 - W/2;
		
	// bottom
	//	popup.style.top = t + h;
	//	popup.style.left = l + w/2 - W/2;
}

SfImage.Popup.RawPopupCalculator.prototype =
{
	GetPosition : function()
	{
		var position = new Object();
		if (this._CanPlaceOnTop() == true)
		{
			//position.Top = this._params.t - this._params.H;
			//position.Left = this._CalculateLeftOffset();
			//position.Where = SfImage.Popup.Position.Top;
			position.Top = this._params.t - this._params.H + 22;
			position.Left = this._params.l + this._params.w;
			position.Where = SfImage.Popup.Position.Right;
			return position;
		}
		if (this._CanPlaceOnRight() == true)
		{
			position.Top = this._CalculateTopOffset();
			position.Left = this._params.l + this._params.w;
			position.Where = SfImage.Popup.Position.Right;
			return position;
		}
		if (this._CanPlaceOnLeft() == true)
		{
			position.Top = this._CalculateTopOffset();
			position.Left = this._params.l - this._params.W;
			position.Where = SfImage.Popup.Position.Left;
			return position;
		}
		
		position.Top = this._params.t + this._params.h;
		position.Left = this._CalculateLeftOffset();
		position.Where = SfImage.Popup.Position.Bottom;
		return position;
	},
	
	_CanPlaceOnTop : function()
	{
		return (this._params.t - this._params.H >= 0);
	},
	
	_CanPlaceOnRight : function()
	{
		return (this._params.CW >= this._params.l + this._params.w + this._params.W);
	},
	
	_CanPlaceOnLeft : function()
	{
		return (this._params.l - this._params.W >= 0);
	},
	
	_CalculateLeftOffset : function()
	{
		var intendedLeft = this._params.l + this._params.w/2 - this._params.W/2;
		if (intendedLeft <=0)
		{
			return 0;
		}
		var resultingRight = intendedLeft + this._params.W;
		if (resultingRight <= this._params.CW)
		{
			return intendedLeft;
		}
		else
		{
			return this._params.CW - this._params.W;
		}
	},
	
	_CalculateTopOffset : function()
	{
		var intendedTop = this._params.t + this._params.h/2 - this._params.H/2;
		if (intendedTop >=0)
		{
			return intendedTop;
		}
		else
		{
			return 0;
		}
	}
}

SfImage.Popup.PopupHelper = function(input)
{
	this._input = input;
	
	this._zoomElement = null;
	this._imageElement = null;
	this._positionCalculator = null;
	this._borderWidth = 1;
	this._padding = 3;
	this._isInitialized = false;
	this._CreateZoomElement();
	
}
SfImage.Popup.PopupHelper.prototype = 
{
	GetZoomElement : function()
	{
		return this._zoomElement;
	},
	
	_CreateZoomElement : function()
	{
		this._zoomElement = $(document.createElement('div'));
		this._zoomElement.className = 'imagePopupZoomElement';
		this._zoomElement.setStyle({'z-index':'2','position':'absolute','top':'0px','left':'0px','visibility':'hidden','border-width':''+this._borderWidth + 'px','padding':'' + this._padding + 'px'});
		this._imageElement = document.createElement('img');
		this._imageElement = $(this._imageElement);
		this._zoomElement.appendChild(this._imageElement);
		this._imageElement.setStyle({'width':this._input.ZoomWidth + 'px','height':this._input.ZoomHeight+'px','left':'0px','display':'block'});
	},
	
	_Initialize : function()
	{
		var containerDimension = this._input.ContainingElement.getDimensions();

		var boxDimension = new Object();
		boxDimension.Width = this._input.ZoomWidth + 2 * this._borderWidth + 2 * this._padding;
		boxDimension.Height = this._input.ZoomHeight + 2 * this._borderWidth + 2 * this._padding;

		this._positionCalculator = new SfImage.Popup.PositionCalculator({Width:containerDimension.width,Height:containerDimension.height}, boxDimension);
		this._isInitialized = true;
	},

	ShowSlideNumber : function(slideNumber, anchorInfo)
	{
		if (this._isInitialized == false)
		{
			this._Initialize();
		}
	
		this._imageElement.setAttribute("src", mPlayer.GetImageLocationUsingWidthAndHeight(slideNumber, this._input.ZoomWidth, this._input.ZoomHeight));
		
		var scrollOffsets = {Top:this._input.ContainingElement.scrollTop,Left:this._input.ContainingElement.scrollLeft};

		anchorInfo.Top = anchorInfo.Top - scrollOffsets.Top;
		anchorInfo.Left = anchorInfo.Left - scrollOffsets.Left;

		var displayPos = this._positionCalculator.GetPopupPosition(anchorInfo);
		displayPos.Top = displayPos.Top + scrollOffsets.Top;
		displayPos.Left = displayPos.Left + scrollOffsets.Left;
		
		var initial;
		if (displayPos.Where == SfImage.Popup.Position.Top)
		{
			initial = {Top:displayPos.Top, Left:displayPos.Left, Width:this._input.ZoomWidth, Height:this._input.ZoomHeight};
		}
		else if (displayPos.Where == SfImage.Popup.Position.Right)
		{
			initial = {Top:displayPos.Top, Left:displayPos.Left, Width:this._input.ZoomWidth, Height:this._input.ZoomHeight};
		}
		else if (displayPos.Where == SfImage.Popup.Position.Left)
		{
			initial = {Top:displayPos.Top, Left:displayPos.Left+this._input.ZoomWidth-30, Width:this._input.ZoomWidth, Height:this._input.ZoomHeight};
		}
		else
		{
			initial = {Top:displayPos.Top, Left:displayPos.Left, Width:this._input.ZoomWidth, Height:this._input.ZoomHeight};
		}

		this.SetBounds({Top:initial.Top + 'px', 
			Left:initial.Left + 'px',
			Width:initial.Width + 'px',
			Height:initial.Height + 'px'
			});
		this._zoomElement.style.visibility = 'visible';
		this._zoomElement.style.zIndex = '2';
		
	},
	

	SetBounds: function(bounds)
	{
		this._zoomElement.style.top = bounds.Top;
		this._zoomElement.style.left = bounds.Left;
		this._imageElement.style.width = bounds.Width;
		this._imageElement.style.height = bounds.Height;
		this._zoomElement.style.width = bounds.Width;
	},

	Clear : function(e)
	{
		this.SetBounds({Top:0 + 'px', 
			Left:0 + 'px',
			Width:0 + 'px',
			Height:0 + 'px'
			});
		this._zoomElement.style.visibility = 'hidden';
        this._imageElement.setAttribute('src', LayoutOptions.ThemeImageBase + '/1x1.gif');
	}
}

SfImage.ImageUpdater = function(container, imageElement, extraWidth, extraHeight, minWidth, minHeight)
{	
	this.Container = container;
	this.ImageElement = imageElement;

	this.ExtraWidth = extraWidth;
	this.ExtraHeight = extraHeight;
	
	this.MinWidth = minWidth;
	this.MinHeight = minHeight;
	
	this.PreviousImageWidth = null;
	this.PreviousImageHeight = null;
		
	this.ChangeImage = function(imageSrc)
	{
		this.ImageElement.onload = new Function("", this.Container + ".ChangeSizes();");
		this.ImageElement.src = imageSrc;
	}

	this.ChangeSizes = function()
	{
		var imageDimension = this.GetImageDimension();
		if (!this.ValidateDimension(imageDimension))
		{
			return;
		}
		
		if (this.IsChangeNecessary(imageDimension.Width, imageDimension.Height))
		{    		
    		this.PreviousImageWidth = imageDimension.Width;
    		this.PreviousImageHeight = imageDimension.Height;		

    		this.ChangeWindowSize(imageDimension.Width, imageDimension.Height);
		}				
	}
	
	this.ChangeWindowSize = function(imageWidth, imageHeight)
	{
		var dimension = this.GetOptimumWindowDimension(imageWidth, imageHeight);
		if (dimension == null)
		{
			return;
		}
		
        var currentSize = document.viewport.getDimensions();                              
        window.resizeBy((dimension.Width - currentSize.width),(dimension.Height - currentSize.height));
		
	}
	
	this.GetImageDimension = function()
	{
		var ret = new Object();
		if (!this.ImageElement)
		{
			return null;
		}
		
		ret.Width = this.ImageElement.width;
		ret.Height = this.ImageElement.height;

		return ret;
	}
	
	this.ValidateDimension = function(dimension)
	{
		if (dimension == null)
		{
			return false;
		}
		
		if (!dimension.Width)
		{
			return false;
		}
		if (dimension.Width < 100)
		{
			return false;
		}
		
		if (!dimension.Height)
		{
			return false;
		}
		if (dimension.Height < 100)
		{
			return false;
		}
		
		return true;
	}
	
	this.IsChangeNecessary = function(imageWidth, imageHeight)
	{
		if (this.PreviousImageWidth == null || this.PreviousImageHeight == null)
		{
			return true;
		}
		
		if (this.PreviousImageWidth != imageWidth || this.PreviousImageHeight != imageHeight)
		{
			return true;
		}
		
		return false;	
	}
	
	this.GetOptimumWindowDimension = function(imageWidth, imageHeight)
	{		
		var ret = new Object();

		var availWidth = screen.availWidth;
		var availHeight = screen.availHeight;

		var windowWidth = imageWidth + this.ExtraWidth; 
		if (windowWidth > availWidth)
		{
			ret.Width = availWidth;
		}
		else if(windowWidth < this.MinWidth)
		{
		    ret.Width = this.MinWidth;
		}
		else
		{
			ret.Width = windowWidth;
		}
		
		var windowHeight = imageHeight + this.ExtraHeight;
		if (windowHeight > availHeight)
		{
			ret.Height = availHeight;
		}
		else if(windowHeight < this.MinHeight)
		{
		    ret.Height = this.MinHeight;
		}
		else
		{
			ret.Height = windowHeight;
		}
		
		return ret;				
	}
			
	this.GetMainPlayer = function()
	{
		if (opener.closed)
		{
			return null;
		}
		
		if (!opener.mPlayer)
		{
			return null;
		}
		return opener.mPlayer;
	}
}


Type.registerNamespace('SfUI');

Type.registerNamespace('SfUI.Menu');
SfUI.Menu.MenuType = function(){}
SfUI.Menu.MenuType.prototype = 
{
	RootMenu : 0,
	SubMenu : 1,
	Leaf : 2
}
SfUI.Menu.MenuType.registerEnum('SfUI.Menu.MenuType');
SfUI.Menu.LocationInfo = function(topOffset, leftOffset, width, height)
{
	this.Width = width;
	this.Height = height;
	this.TopOffset = topOffset;
	this.LeftOffset = leftOffset;
}
SfUI.Menu.LocationInfo.registerClass('SfUI.Menu.LocationInfo', null);

SfUI.Menu.SizeInfo = function (width, height)
{
	this.Width = width;
	this.Height = height;
}
SfUI.Menu.SizeInfo.registerClass('SfUI.Menu.SizeInfo', null);

SfUI.Menu.MenuTemplate = function()
{
	this.LocationInfo = new SfUI.Menu.LocationInfo();
	this.SubMenuSizeInfo = new SfUI.Menu.SizeInfo();
	
	this.LeftDivWidth = 0;//13;
	this.RightDivWidth = 0;//13;
	this.BaseLeftDivWidth = 0;
	this.BaseRightDivWidth = 0;//13;
	
	this.PaddingTop = 2;
	this.PaddingLeft = 10;
	
	this.BaseBorderWidth = 1;
	this.ChildBorderWidth = 1;
	this.BaseBorderColor = '#777';
	this.ChildBorderColor = '#777';
	
	this.CssPrefix = "";
}
SfUI.Menu.MenuTemplate.prototype =
{	
	Clone : function()
	{
		var copy = new SfUI.Menu.MenuTemplate();
		copy.LocationInfo = this.LocationInfo;
		copy.SubMenuSizeInfo = this.SubMenuSizeInfo;
		copy.LeftDivWidth = this.LeftDivWidth;
		copy.RightDivWidth = this.RightDivWidth;
		copy.BaseLeftDivWidth = this.BaseLeftDivWidth;
		copy.BaseRightDivWidth = this.BaseRightDivWidth;
		copy.PaddingTop = this.PaddingTop;
		copy.PaddingLeft = this.PaddingLeft;
		copy.BaseBorderColor = this.BaseBorderColor;
		copy.ChildBorderColor = this.ChildBorderColor;
		copy.CssPrefix = this.CssPrefix;
		return copy;
	}
}
SfUI.Menu.MenuTemplate.registerClass('SfUI.Menu.MenuTemplate', null);

SfUI.Menu.Calculator = function()
{
}
SfUI.Menu.Calculator.prototype =
{
	GetCalculatedChildLeftOffset : function(intended, borderWidth)
	{
		return intended - 2*borderWidth;
	},
	
	GetCalculatedChildTopOffset : function(intended, borderWidth)
	{
		return intended - 1*borderWidth;
	},

	GetWidth : function(intended, borderWidth)
	{
		return intended-2*borderWidth;
	},
	
	GetHeight : function(intended, borderWidth)
	{
		return intended-2*borderWidth;
	},
	
	GetPaddingBorderAdjustment : function(intended, borderWidth, padding)
	{
		return intended - 2*borderWidth - padding;
	}
}
SfUI.Menu.Calculator.registerClass('SfUI.Menu.Calculator', null);

SfUI.Menu.MenuItem = function(container, text, template)
{
	this.Container = container;
	this.Text = text;
	this.Width = template.LocationInfo.Width;
	this.Height = template.LocationInfo.Height;
	this.TopOffset = template.LocationInfo.TopOffset;
	this.LeftOffset = template.LocationInfo.LeftOffset;
	this.Template = template;

	this.MenuType = null;
	this.Parent = null;

	this.RootDiv = null;
	this.TextDiv = null;
	this.DivLeft = null;
	this.DivMiddle = null;
	this.DivRight = null;
	
	this.ZIndex = 1;
}
SfUI.Menu.MenuItem.prototype =
{
	InitializeCalculator : function()
	{
		this.Calculator = new SfUI.Menu.Calculator();
	},

	CreateElement : function(top, left, width, height)
	{
		var elem = document.createElement("div");
		elem.style.position = 'absolute';
		elem.style.top = top + 'px';
		elem.style.left = left + 'px';
		elem.style.width = width + 'px';
		elem.style.height = height + 'px';
		return elem;
	},

	GetDivClassName : function(hilite, loc)
	{
	},

	Hide : function()
	{
		this.RootDiv.style.visibility = 'hidden';
		this.UnHiliteDiv();
	},

	Show : function()
	{
		this.RootDiv.style.visibility = 'visible';
	},

	OnMouseOver : function()
	{
		if (this.Parent != null)
		{
			var children = this.Parent.GetChildren();
			for (var i=0; i<children.length; ++i)
			{
				children[i].CollapseChildrenNow();
			}
		}
		this.ExpandChildrenNow();

		this.HiliteDiv();
		this.HiliteAllParents();	
	},

	HiliteAllParents : function()
	{
		var current = this;
		var par = current.Parent;
		while (par != null)
		{
			par.HiliteDiv();
			var children = par.GetChildren();
			for (var i=0; i<children.length; ++i)
			{
				if (children[i].Container != current.Container)
				{
					children[i].UnHiliteDiv();
				}
			}
			current = par;
			par = par.Parent;
		}
	},

	HiliteDiv : function()
	{
		this.DivLeft.className = this.GetDivClassName(true, 'Left');
		this.DivRight.className = this.GetDivClassName(true, 'Right');
		this.DivMiddle.className = this.GetDivClassName(true, 'Middle');
	},

	OnMouseOut : function()
	{
		this.UnHiliteDiv();
	},

	UnHiliteDiv : function()
	{
		this.DivLeft.className = this.GetDivClassName(false, 'Left');
		this.DivRight.className = this.GetDivClassName(false, 'Right');
		this.DivMiddle.className = this.GetDivClassName(false, 'Middle');
	},

	GetRootParent : function()
	{
		var currentElem = this;
		while (currentElem.Parent != null)
		{
			currentElem = currentElem.Parent;
		}
		return currentElem;
	},

	CollapseChildrenNow : function()
	{
	},

	ExpandChildrenNow : function()
	{
	},

	CreateRootDiv : function()
	{
		this.RootDiv = this.CreateElement(this.TopOffset, this.LeftOffset, this.Calculator.GetWidth(this.Width, this.GetBorderWidth()), this.Calculator.GetHeight(this.Height, this.GetBorderWidth()));
	},

	GetLeftDivWidth : function()
	{
		return this.Template.LeftDivWidth;
	},

	GetRightDivWidth : function()
	{
		return this.Template.RightDivWidth;
	},

	GetBorderWidth : function()
	{
		return this.Template.ChildBorderWidth;
	},

	CreateTextDiv : function()
	{
		this.TextDiv = this.CreateElement(0, 0, this.Calculator.GetWidth(this.Width, this.GetBorderWidth()), this.Calculator.GetHeight(this.Height, this.GetBorderWidth()));
		this.RootDiv.appendChild(this.TextDiv);

		this.DivLeft = this.CreateElement(0, 0, this.GetLeftDivWidth(), this.Height-2*this.GetBorderWidth());
		this.DivLeft.className = this.GetDivClassName(false, 'Left');
		this.TextDiv.appendChild(this.DivLeft);

		this.DivMiddle = this.CreateElement(0, this.GetLeftDivWidth(), this.Calculator.GetPaddingBorderAdjustment(this.Width - (this.GetLeftDivWidth() + this.GetRightDivWidth()), this.GetBorderWidth(), this.Template.PaddingLeft), this.Calculator.GetPaddingBorderAdjustment(this.Height, this.GetBorderWidth(), this.Template.PaddingTop));
		this.DivMiddle.className = this.GetDivClassName(false, 'Middle');
		this.DivMiddle.style.paddingLeft = this.Template.PaddingLeft + 'px';
		this.DivMiddle.style.paddingTop = this.Template.PaddingTop + 'px';
		this.DivMiddle.appendChild(document.createTextNode(this.Text));
		this.TextDiv.appendChild(this.DivMiddle);

		this.DivRight = this.CreateElement(0, this.Width-this.GetRightDivWidth()-2*this.GetBorderWidth(), this.GetRightDivWidth(), this.Height-2*this.GetBorderWidth());
		this.DivRight.className = this.GetDivClassName(false, 'Right');
		this.TextDiv.appendChild(this.DivRight);

		this.TextDiv.onmouseover = new Function("", this.Container + ".OnMouseOver();");
		this.TextDiv.onmouseout = new Function("", this.Container + ".OnMouseOut();");
	}
}
SfUI.Menu.MenuItem.registerClass('SfUI.Menu.MenuItem', null);
SfUI.Menu.LeafItem = function(container, text, template, onClickFunction)
{
	SfUI.Menu.LeafItem.initializeBase(this, [container, text, template]);
	this.OnClickFunction = onClickFunction;

	this.MenuType = SfUI.Menu.MenuType.Leaf;
	this.IsSelectedLeaf = false;
}
SfUI.Menu.LeafItem.prototype =
{
	Create : function()
	{
		this.InitializeCalculator();
		this.CreateRootDiv();
		this.CreateTextDiv();
		this.TextDiv.onclick = new Function("", this.Container + ".OnClick();");
	},

	OnClick : function()
	{
		var rootParent = this.GetRootParent();
		rootParent.CollapseChildrenNow();
		rootParent.Expanded = false;
		rootParent.UnHiliteDiv();

		if (this.OnClickFunction)
		{
			this.OnClickFunction();
		}
		
		if (this.Group)
		{
			this.Group.Select(this);
		}
	},

	GetDivClassName : function(hilite, loc)
	{
		if (hilite == true)
		{
			if (this.IsSelectedLeaf == true)
			{
				return 'div' + this.Template.CssPrefix + 'SelectedLeaf' + loc + 'Over';
			}
			else
			{
				return 'div' + this.Template.CssPrefix + loc + 'Over';
			}
		}
		else
		{
			if (this.IsSelectedLeaf == true)
			{
				return 'div' + this.Template.CssPrefix + 'SelectedLeaf' + loc;
			}
			else
			{
				return 'div' + this.Template.CssPrefix + loc;
			}
		}
	}
}
SfUI.Menu.LeafItem.registerClass('SfUI.Menu.LeafItem', SfUI.Menu.MenuItem);

SfUI.Menu.LeafGroup = function()
{
	this.Leafs = new Array();
}
SfUI.Menu.LeafGroup.prototype = 
{
	Add : function(leaf)
	{
		this.Leafs[this.Leafs.length] = leaf;
		leaf.Group = this;
	},
	
	Select : function(leaf)
	{
		for (var i=0; i<this.Leafs.length; ++i)
		{
			if (this.Leafs[i].Container == leaf.Container)
			{
				this.Leafs[i].IsSelectedLeaf = true;
			}
			else
			{
				this.Leafs[i].IsSelectedLeaf = false;
			}
			this.Leafs[i].UnHiliteDiv();
		}
	}
}
SfUI.Menu.LeafGroup.registerClass('SfUI.Menu.LeafGroup', null);

SfUI.Menu.SubMenuItem = function(container, text, template)
{
	SfUI.Menu.SubMenuItem.initializeBase(this, [container, text, template]);

	this.SubMenuWidth = this.Template.SubMenuSizeInfo.Width;
	this.SubMenuHeight = this.Template.SubMenuSizeInfo.Height;
	this.MenuType = SfUI.Menu.MenuType.SubMenu;

	this.ChildDiv = null;
	this.Children = null;
}

SfUI.Menu.SubMenuItem.prototype =
{	
	GetDivClassName : function(hilite, loc)
	{
		if (hilite == true)
		{
			return 'div' + this.Template.CssPrefix + 'SubMenu' + loc + 'Over';
		}
		else
		{
			return 'div' + this.Template.CssPrefix + 'SubMenu' + loc;
		}
	},

	GetChildren : function()
	{
		return this.Children;
	},

	AddLeaf : function(text, onClickFunction)
	{
		var template = this.Template.Clone();
		template.LocationInfo = new SfUI.Menu.LocationInfo(this.GetCurrentChildTopOffset(), 0, this.SubMenuWidth, this.SubMenuHeight);
 		var item = new SfUI.Menu.LeafItem(this.GetCurrentChildContainer(), 
 			text, 
 			template,
 			onClickFunction);
 		item.Create();
		this.AddChild(item);
		return item;
	},

	AddSubMenu : function(text, subSubMenuWidth, subSubMenuHeight)
	{
		var template = this.Template.Clone();
		template.LocationInfo = new SfUI.Menu.LocationInfo(this.GetCurrentChildTopOffset(), 0, this.SubMenuWidth, this.SubMenuHeight);
		template.SubMenuSizeInfo = new SfUI.Menu.SizeInfo(subSubMenuWidth, subSubMenuHeight);
		var sub = new SfUI.Menu.SubMenuItem(this.GetCurrentChildContainer(), text, template);
		sub.Create();
		this.AddChild(sub);
		return sub;
	},

	GetCurrentChildContainer : function()
	{
		return this.Container + ".GetChildItem(" + this.Children.length + ")";
	},

	GetChildItem : function(index)
	{
		return this.Children[index];
	},

	ExpandChildrenNow : function()
	{
		this.ChildDiv.style.visibility = 'visible';
		for (var i=0; i<this.Children.length; ++i)
		{
			this.Children[i].Show();
		}
	},

	CollapseChildrenNow : function()
	{
		this.ChildDiv.style.visibility = 'hidden';
		for (var i=0; i<this.Children.length; ++i)
		{
			this.Children[i].Hide();
			if (this.Children[i].MenuType == SfUI.Menu.MenuType.SubMenu)
			{
				this.Children[i].CollapseChildrenNow();
			}
		}
	},
	
	AddChild : function(item)
	{
		item.Parent = this;
		item.ZIndex = this.ZIndex+1;

		item.TextDiv.style.zIndex = item.ZIndex;

		this.ChildDiv.appendChild(item.RootDiv);
		this.Children[this.Children.length] = item;
		this.ChildDiv.style.height = this.Calculator.GetHeight(((this.SubMenuHeight-2*this.Template.ChildBorderWidth)*this.Children.length+2*this.Template.ChildBorderWidth), this.Template.ChildBorderWidth) + 'px';
	},

	GetCurrentChildTopOffset : function()
	{
		return this.Children.length * (this.SubMenuHeight-2*this.Template.ChildBorderWidth);
	},

	Create : function()
	{
		this.InitializeCalculator();
		this.CreateRootDiv();
		this.CreateTextDiv();
		this.CreateChildDiv();
		this.Children = new Array(0);
	},

	CreateChildDiv : function()
	{
		this.ChildDiv = this.CreateElement(
			this.Calculator.GetCalculatedChildTopOffset(0, this.GetBorderWidth()), 
			this.Calculator.GetCalculatedChildLeftOffset(this.Width, this.GetBorderWidth()), 
			this.Calculator.GetWidth(this.SubMenuWidth, this.GetBorderWidth()), 
			this.Calculator.GetHeight(this.Height, this.GetBorderWidth()));
		this.RootDiv.appendChild(this.ChildDiv);
	}
}
SfUI.Menu.SubMenuItem.registerClass('SfUI.Menu.SubMenuItem', SfUI.Menu.MenuItem);

SfUI.Menu.BaseMenuItem = function(container, text, template, tooltip)
{
	SfUI.Menu.BaseMenuItem.initializeBase(this, [container, text, template, tooltip]);

	this.Expanded = false;

	this.Create();
	
    this.TextDiv.setAttribute('title', tooltip);
	this.TextDiv.onclick = new Function("", this.Container + ".OnClick();");

}
SfUI.Menu.BaseMenuItem.prototype =
{
	GetBorderWidth : function()
	{
		return this.Template.BaseBorderWidth;
	},

	GetDivClassName : function(hilite, loc)
	{
		if (hilite == true)
		{
			return 'div' + this.Template.CssPrefix + 'Base' + loc + 'Over';
		}
		else
		{
			return 'div' + this.Template.CssPrefix + 'Base' + loc;
		}
	},

	CreateChildDiv : function()
	{
		this.ChildDiv = this.CreateElement(
			this.Height,
			0,
			this.Calculator.GetWidth(this.SubMenuWidth, this.Template.ChildBorderWidth), 
			this.Calculator.GetHeight(this.Height, this.Template.ChildBorderWidth));
		this.RootDiv.appendChild(this.ChildDiv);
	},

	GetLeftDivWidth : function()
	{
		return this.Template.BaseLeftDivWidth;
	},

	GetRightDivWidth : function()
	{
		return this.Template.BaseRightDivWidth;
	},

	OnMouseOver : function()
	{
		this.HiliteDiv();
	},

	OnMouseOut : function()
	{
		if (this.Expanded == true)
		{
			return;
		}
		this.UnHiliteDiv();

	},

	OnClick : function()
	{
		if (this.Expanded == true)
		{
			this.CollapseChildrenNow();
		}
		else
		{
			this.ExpandChildrenNow();
		}
		this.Expanded = !this.Expanded;
	}

}
SfUI.Menu.BaseMenuItem.registerClass('SfUI.Menu.BaseMenuItem', SfUI.Menu.SubMenuItem);


Type.registerNamespace('SfUI.Tooltip');			
SfUI.Tooltip.TooltipEnabled = function(container, client, toolTip)
{
	this._container = container;
	this._client = client;
	this._tooltip = toolTip;
	this._handleClient = null;
	this._handleTooltip = null;
	
	this._Initialize();
}

SfUI.Tooltip.TooltipEnabled.prototype = 
{
	_Initialize : function()
	{
		this._client.observe('mouseover', this._ClientOnMouseOver.bindAsEventListener(this), true);					
		this._client.observe('mouseout', this._ClientOnMouseOut.bindAsEventListener(this), true);
		this._tooltip.observe('mouseover', this._TooltipOnMouseOver.bindAsEventListener(this), true);					
		this._tooltip.observe('mouseout', this._TooltipOnMouseOut.bindAsEventListener(this), true);
	},
	
	_ClientOnMouseOver : function(e)
	{
		SfKernel.Util.SetCursor(this._client, SfKernel.CursorType.Hand);

		Event.stop(e);

		window.clearTimeout(this._handleTooltip);
		window.clearTimeout(this._handleClient);
	
		var containerDimension = {Width:this._container.getWidth(), Height:this._container.getHeight()};
		var boxDimension = {Width:this._tooltip.getWidth(), Height:this._tooltip.getHeight()};

		var positionCalculator = new SfImage.Popup.PositionCalculator(containerDimension, boxDimension);

		var offset = this._GetOffsetFromContainer();
		
		var anchorInfo = {Top:offset.OffsetTop, Left:offset.OffsetLeft, Width:this._client.getWidth(), Height:this._client.getHeight()};
		
		var displayPos = positionCalculator.GetPopupPosition(anchorInfo);

		this._tooltip.setStyle({'top':displayPos.Top+'px', 'left':displayPos.Left+'px'});
		this._tooltip.show();
		
	},
	
	//! Refactor Up
	_GetOffsetFromContainer : function()
	{
		var containerOffset = Position.cumulativeOffset(this._container);
		var boxOffset = Position.cumulativeOffset(this._client);
		
		return {OffsetTop: boxOffset[1] - containerOffset[1], OffsetLeft: boxOffset[0] - containerOffset[0]};
	},
	
	_ClientOnMouseOut : function(e)
	{
		SfKernel.Util.SetCursor(this._client, SfKernel.CursorType.Default);

		this._handleClient = window.setTimeout(this._HideTooltip.bind(this), 300);
	},
	
	_TooltipOnMouseOver : function(e)
	{
		Event.stop(e);

		window.clearTimeout(this._handleClient);
		window.clearTimeout(this._handleTooltip);
		
	},
	
	_TooltipOnMouseOut : function(e)
	{
		this._handleTooltip = window.setTimeout(this._HideTooltip.bind(this), 300);
	},
	
	_HideTooltip : function()
	{
		this._tooltip.hide();
	}
	
}

SfUI.Checkbox = function(element, imageInfo, enabled)
{
	this._element = element;
	this._imageInfo = imageInfo;
	this._checked = false;
	this._enabled = enabled;

	if (this._enabled == true)
	{
		this._mouseOverListener = this._OnMouseOver.bind(this);
		this._mouseOutListener = this._OnMouseOut.bind(this);

		this._element.observe('mouseover', this._mouseOverListener);
		this._element.observe('mouseout', this._mouseOutListener);
	}
	else
	{
		this._element.style.backgroundImage = 'url(' + this._imageInfo.DisabledImage + ')';
	}
}
SfUI.Checkbox.prototype =
{
	SetChecked : function(value)
	{
		this._checked = value;
		this._UpdateImage();
	},
	
	GetChecked : function()
	{
		return this._checked;
	},

	Toggle : function()
	{
		this.SetChecked(!this.GetChecked());
	},
		
	SetOnClickMethod : function(onClickFunction)
	{
		this._element.observe('click', onClickFunction);
	},
	
	_OnMouseOver : function()
	{
		SfKernel.Util.SetCursor(this._element, SfKernel.CursorType.Hand);
		if (this._checked == false)
		{
			this._element.style.backgroundImage = 'url(' + this._imageInfo.OverImage + ')';
		}
		else
		{
			this._element.style.backgroundImage = 'url(' + this._imageInfo.CheckedOverImage + ')';
		}
	},
	
	_OnMouseOut : function()
	{
		this._UpdateImage();
		SfKernel.Util.SetCursor(this._element, SfKernel.CursorType.Default);
	},
	
	_UpdateImage : function()
	{
		if (this._enabled == false)
		{
			this._element.style.backgroundImage = 'url(' + this._imageInfo.DisabledImage + ')';
			return;
		}
		
		if (this._checked == true)
		{
			this._element.style.backgroundImage = 'url(' + this._imageInfo.CheckedImage + ')';
		}
		else
		{
			this._element.style.backgroundImage = 'url(' + this._imageInfo.NormalImage + ')';
		}
	}
}
SfUI.Checkbox.registerClass('SfUI.Checkbox', null);



SfUI.$create__imagePos = function SfUI__imagePos() { return {}; }

SfUI.Magnifier = function SfUI_Magnifier(imageDiv, magAreaDiv) {
    this._image = imageDiv;
    this._magArea = magAreaDiv;
    this._initialize();
}
SfUI.Magnifier.prototype = {
    _image: null,
    _magArea: null,
    _imagePos: null,
    _magWidth: 0,
    _magHeight: 0,
    _isEnabled: false,
    _mouseOutListener: null,
    _mouseMoveListener: null,
    
    IsEnabled: function SfUI_Magnifier$IsEnabled() {
        return this._isEnabled;
    },
    
    Enable: function SfUI_Magnifier$Enable() {
        if (this._isEnabled) {
            return;
        }
        this._bindEventListeners();
        this._isEnabled = true;
    },
    
    Disable: function SfUI_Magnifier$Disable() {
        if (!this._isEnabled) {
            return;
        }
        this._unbindEventListeners();
        this._onMouseOut(null);
        this._isEnabled = false;
    },
    
    _bindEventListeners: function SfUI_Magnifier$_bindEventListeners() {
        this._image.observe('mousemove', this._mouseMoveListener);
        this._magArea.observe('mousemove', this._mouseMoveListener);
        this._magArea.observe('mouseout', this._mouseOutListener);
        this._image.observe('mouseover', this._mouseOverListener);
    },
    
    _unbindEventListeners: function SfUI_Magnifier$_unbindEventListeners() {
        this._image.stopObserving('mousemove', this._mouseMoveListener);
        this._magArea.stopObserving('mousemove', this._mouseMoveListener);
        this._magArea.stopObserving('mouseout', this._mouseOutListener);
        this._image.stopObserving('mouseover', this._mouseOverListener);
    },
    
    _initialize: function SfUI_Magnifier$_initialize() {
        this._imagePos = SfUI.$create__imagePos();
        this._magWidth = this._magArea.getWidth() + 2;
        this._magHeight = this._magArea.getHeight() + 2;
        var myPos = Position.cumulativeOffset(this._image);
        this._imagePos.left = myPos[0];
        this._imagePos.right = this._imagePos.left + this._image.getWidth();
        this._imagePos.top = myPos[1];
        this._imagePos.bottom = this._imagePos.top + this._image.getHeight();                
        this._mouseOutListener = Function.createDelegate(this, this._onMouseOut);
        this._mouseMoveListener = Function.createDelegate(this, this._onMouseMove);
        this._mouseOverListener = Function.createDelegate(this, this._onMouseOver);
    },    
    
    _recalculatePositions: function SfUI_Magnifier$_recalculatePositions() {
        /* needs to be done somtime after the currentslide position is changed */
        this._imagePos = SfUI.$create__imagePos();
        var myPos = Position.cumulativeOffset(this._image);
        this._imagePos.left = myPos[0];
        this._imagePos.right = this._imagePos.left + this._image.getWidth();
        this._imagePos.top = myPos[1];
        this._imagePos.bottom = this._imagePos.top + this._image.getHeight();
    },
    
    _onMouseOut: function SfUI_Magnifier$_onMouseOut(e) {
        this._magArea.style.display = 'none';
    },
    
    _onMouseOver: function SfUI_Magnifier$_onMouseOver(e) {
        this._recalculatePositions();
    },
        
    _onMouseMove: function SfUI_Magnifier$_onMouseMove(e) {
        var ex = e.clientX;
        var ey = e.clientY;
        this._magArea.style.display = '';
  
        var fullSizeWidth = document.getElementById('currentSlideMagnifierImage').width;
        var fullSizeHeight = document.getElementById('currentSlideMagnifierImage').height;
                
        var leftOffset = (ex - this._imagePos.left) * (fullSizeWidth / this._image.width) - (this._magWidth/2);        
        
        if(leftOffset < 0 )
        {
            this._magArea.scrollLeft = 0;
        }
        else
        {
            this._magArea.scrollLeft = leftOffset;
        }
 
        var topOffset = (ey - this._imagePos.top) * (fullSizeHeight / this._image.height) - (this._magHeight/2);        
        if(topOffset < 0 )
        {
            this._magArea.scrollTop = 0;
        }
        else
        {
            this._magArea.scrollTop = topOffset;        
        }
       
        this._magArea.setStyle({ left: this._getMagLeftPosition(ex) + 'px', top: this._getMagTopPosition(ey) + 'px' });
    },
    
    _getMagLeftPosition: function SfUI_Magnifier$_getMagLeftPosition(ex) {
        var leftPos = ex - this._magWidth / 2;
        if (leftPos > this._imagePos.right - this._magWidth) {
            leftPos = this._imagePos.right - this._magWidth;
        }
        else if (leftPos < this._imagePos.left) {
            leftPos = this._imagePos.left;
        }
        return leftPos;
    },
    
    _getMagTopPosition: function SfUI_Magnifier$_getMagTopPosition(ey) {
        var topPos = ey - this._magHeight / 2;
        if (topPos > this._imagePos.bottom - this._magHeight) {
            topPos = this._imagePos.bottom - this._magHeight;
        }
        else if (topPos < this._imagePos.top) {
            topPos = this._imagePos.top;
        }
        return topPos;
    }
}


SfUI.Magnifier.registerClass('SfUI.Magnifier');
Type.registerNamespace('SfUI');

SfUI.SfSlider = function(settings)
{
	this._settings = settings;
	
	this._enabled = true;
	this._thumbLength = -1;
	this._rangeMin = 0;
	this._rangeMax = 100;
	this._physicalMin = -1;
	this._physicalMax = -1;
	this._elementThumb = null;
	this._elementThumbImage = null;
	this._elementGuide = null;
	this._isPositionInitialized = false;
	this._events = null;
	this._onMouseMoveDelegate = null;
	this._onMouseUpDelegate = null;
	
	this._Initialize();
}

SfUI.SfSlider.DragEventType = 
{
	BeginDrag : "BeginDrag",
	EndDrag : "EndDrag",
	DragMove : "DragMove"
}

SfUI.SfSlider.Orientation =
{
	Horizontal : "Horizontal",
	Vertical : "Vertical"
}

SfUI.SfSlider.prototype =
{
	SetEnabled : function(enable)
	{
		this._enabled = enable;
	},
	
	SetRange : function(min, max)
	{
		this._rangeMin = min;
		this._rangeMax = max;
	},
	
	SetPosition : function(position)
	{
		this._SetLogicalPosition(position);
	},
	
	IsPositionInitialized : function()
	{
		return this._isPositionInitialized;
	},
	
	InitializePosition : function()
	{
		this._elementThumb = $(this._settings.NamePrefix + "_thumb");
		this._elementGuide =  $(this._settings.NamePrefix + "_positionGuide");
		
		this._thumbLength = this._GetThumbLength();
		this._physicalMin = this._GetPhysicalMin();
		this._physicalMax = this._physicalMin + this._GetPhysicalLength();
		
		if (typeof (this._physicalLeft) == 'undefined' || this._physicalMax == 0)
		{
			this._isPositionInitialized = false;
		}
		else
		{
			this._isPositionInitialized = true;
		}
	},
	
	AddClickHandler : function(handler)
	{
		this._events.addHandler('Click', handler);
	},
	
	RemoveClickHandler : function(handler)
	{
		this._events.removeHandler('Click', handler);
	},
	
	AddDragHandler : function(handler)
	{
		this._events.addHandler('Drag', handler);
	},
	
	RemoveDragHandler : function(handler)
	{
 		this._events.removeHandler('Drag', handler);
	},
	
	_Initialize : function()
	{
		this.InitializePosition();
		if (this._enabled == true)
		{
			Event.observe(this._elementThumb, 'mousedown', this._BeginDrag.bindAsEventListener(this), true);
			Event.observe(this._elementGuide, 'click', this._GuideOnClick.bindAsEventListener(this), true);
			this._onMouseMoveDelegate = this._OnMove.bindAsEventListener(this);
			this._onMouseUpDelegate = this._OnUp.bindAsEventListener(this);
		}
		
		this._InitializeThumbOver();
		this._events = new Sys.EventHandlerList();
	},
	
	_InitializeThumbOver : function()
	{
		if (this._settings.ImageInfo.ThumbOverImage != null)
		{
			Event.observe(this._elementThumb, 'mouseover', this._ThumbImageOver.bind(this));
			Event.observe(this._elementThumb, 'mouseout', this._ThumbImageOut.bind(this));
		}
	},
	
	_ThumbImageOver : function()
	{
		this.InitializePosition();
		this._elementThumb.style.backgroundImage = 'url(' + this._settings.ImageInfo.ThumbOverImage +')';
	},
	
	_ThumbImageOut : function()
	{
		this._elementThumb.style.backgroundImage = 'url(' + this._settings.ImageInfo.ThumbImage + ')';
	},
	
	_GetThumbLength : function()
	{
		if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
		{
			return parseInt(this._elementThumb.getStyle('width'));
		}
		else
		{
			return parseInt(this._elementThumb.getStyle('height'));
		}
	},
	
	_GetPhysicalMin : function()
	{
		if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
		{
			return this._GetPhysicalLeft();
		}
		else
		{
			return this._GetPhysicalTop();
		}
	},
	
	_GetPhysicalLength : function()
	{
		if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
		{
			return parseInt(this._elementGuide.getStyle('width'));
		}
		else
		{
			//! bug in IE
			return parseInt(this._elementGuide.getStyle('height'));
		}
	},
	
	_ParsePx : function(arg)
	{
		var retVal;
		var re = /\d+px/i;
		if (arg.match(re))
		{
			retVal = arg.substr(0, arg.length-2);
		}
		else
		{
			retVal = arg;
		}
		return Number(retVal);
	},

	_GetPhysicalLeft : function()
	{
		var physicalLeft = this._elementGuide.offsetLeft;
		var par = this._elementGuide.offsetParent;
		while (par)
		{
			physicalLeft += par.offsetLeft;
			par = par.offsetParent;
		}
		return physicalLeft;
	},
	
	_GetPhysicalTop : function()
	{
		var physicalTop = this._elementGuide.offsetTop;
		var par = this._elementGuide.offsetParent;
		while (par)
		{
			physicalTop += par.offsetTop;
			par = par.offsetParent;
		}
		return physicalTop;
	},

	_LogicalToPhysical : function(logicalLength)
	{
		var physicalLength, totalLogicalLength, totalPhysicalLength;
		
		totalLogicalLength = this._rangeMax-this._rangeMin;
		totalPhysicalLength = this._physicalMax-this._physicalMin;
		
		if (totalLogicalLength==0)
		{
			physicalLength = 0;
		}
		else
		{
			physicalLength = (totalPhysicalLength) * logicalLength;
			physicalLength = physicalLength/(totalLogicalLength);
		}

		var physicalPosition;
		if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
		{
			physicalPosition = this._physicalMin + physicalLength;
		}
		else
		{
			physicalPosition = this._physicalMax - physicalLength;
		}
		
		return physicalPosition;
	},
	
	_PhysicalToLogical : function(physicalPosition)
	{
		var logicalLength, totalLogicalLength, totalPhysicalLength;
		
		totalLogicalLength = this._rangeMax-this._rangeMin;
		totalPhysicalLength = this._physicalMax-this._physicalMin;
		
		if (totalLogicalLength==0 || totalPhysicalLength==0)
		{
			logicalLength=0;
		}
		else if (physicalPosition < this._physicalMin)
		{
			if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
			{
				logicalLength = 0;
			}
			else
			{
				logicalLength = totalLogicalLength;
			}
		}
		else if (physicalPosition > this._physicalMax)
		{
			if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
			{
				logicalLength = totalLogicalLength;
			}
			else
			{
				logicalLength = 0;
			}
		}
		else
		{
			var physicalLength;
			if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
			{
			    physicalLength = physicalPosition - this._physicalMin;
			}
			else
			{
				physicalLength = this._physicalMax - physicalPosition;
			}
			
			logicalLength = (totalLogicalLength) * physicalLength;
			logicalLength = logicalLength/(totalPhysicalLength);
		}
		
		return logicalLength;
	},
	
	_SetPhysicalPosition : function(position)
	{
	    if (position < this._physicalMin)
	    {
			position = this._physicalMin;
		}
	    if (position > this._physicalMax)
	    {
			position = this._physicalMax;
		}
		
		if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
		{
			this._elementThumb.style.left = '' + (position - this._physicalMin - this._thumbLength/2) + 'px';
		}
		else
		{
			this._elementThumb.style.top = '' + (position - this._physicalMin - this._thumbLength/2) + 'px';
		}
	},
	
	_SetLogicalPosition : function(position)
	{
		if (position < this._rangeMin)
		{
			position = this._rangeMin;
		}
		if (position > this._rangeMax)
		{
			position = this._rangeMax;
		}
		
		this._SetPhysicalPosition(this._LogicalToPhysical(position));
	},
	
	_GuideOnClick : function(evt)
	{
		this.InitializePosition();
		this._PostClickEvent(this._GetLogicalPositionFromEvent(evt));
	},
	
	_GetPhysicalPositionFromEvent : function(evt)
	{
		if (this._settings.Orientation == SfUI.SfSlider.Orientation.Horizontal)
		{
			return evt.pageX;
		}
		else
		{
			return evt.pageY;
		}
	},
	
	_GetLogicalPositionFromEvent : function(evt)
	{
		var physicalPos = this._GetPhysicalPositionFromEvent(evt);
		return this._PhysicalToLogical(physicalPos);
	},
	
	_PostClickEvent : function(logicalPosition)
	{
		var args = new Object();
 		args.Position = logicalPosition;
		var handler = this._events.getHandler('Click');
		if (handler == null)
		{
			return;
		}
		handler(this, args);
	},
	
	_PostDragEvent : function(type, logicalPosition)
	{
		var args = new Object();
		args.DragEventType = type;
 		args.Position = logicalPosition;
		var handler = this._events.getHandler('Drag');
		if (handler == null)
		{
			return;
		}
		handler(this, args);
	},
	
	_BeginDrag : function(evt)
	{
		Event.observe(document, 'mousemove', this._onMouseMoveDelegate, true);
		Event.observe(document, 'mouseup', this._onMouseUpDelegate, true);
		Event.stop(evt);

		this._PostDragEvent(SfUI.SfSlider.DragEventType.BeginDrag, this._GetLogicalPositionFromEvent(evt));
	},

	_OnUp : function (evt)
	{
		var logicalPosition = this._GetLogicalPositionFromEvent(evt);

		Event.stopObserving(document, 'mousemove', this._onMouseMoveDelegate, true);
		Event.stopObserving(document, 'mouseup', this._onMouseUpDelegate, true);
		Event.stop(evt);
		
		this._PostDragEvent(SfUI.SfSlider.DragEventType.EndDrag, logicalPosition);
	},
		
	_OnMove : function(evt)
	{
		var logicalPosition = this._GetLogicalPositionFromEvent(evt);
		
		Event.stop(evt);
		
		if (logicalPosition < this._rangeMin || logicalPosition > this._rangeMax)
		{
			return;
		}

		this._PostDragEvent(SfUI.SfSlider.DragEventType.DragMove, logicalPosition);
	}

}
SfUI.SfSlider.registerClass('SfUI.SfSlider');

SfUI.SfDiscreteSlider = function(settings)
{
	this._settings = settings;
	
	SfUI.SfDiscreteSlider.initializeBase(this, [this._settings]);
	
	this._points = null;
	
	this._DivideIntoPoints();
}

SfUI.SfDiscreteSlider.prototype =
{	
	SetPointNumber : function(pointNumber)
	{
		this.SetPosition(this._points[pointNumber]);
	},
	
	FindClosestPointNumber : function(pos)
	{
		var closestPoint = 0;
		var minDistance = Math.abs(this._points[0] - pos);
		for (var i=1; i<this._points.length; ++i)
		{
			var distance = Math.abs(this._points[i] - pos);
			if (distance < minDistance)
			{
				minDistance = distance;
				closestPoint = i;
			}
		}
		
		return closestPoint;
	},

	_DivideIntoPoints : function()
	{
		var min = this._rangeMin;
		var max = this._rangeMax;
		
		var length = max - min;
		var numSegments = this._settings.NumPoints - 1;
		var segmentLength = length / numSegments;
		
		this._points = new Array(this._settings.NumPoints);
		
		this._points[0] = min;
		for (var i=1; i<=numSegments; ++i)
		{
			this._points[i] = min + i*segmentLength;
		}
	}
}
SfUI.SfDiscreteSlider.registerClass('SfUI.SfDiscreteSlider', SfUI.SfSlider);



MediaPlayerArea = function(container, containingWindow, id) {
    this.ID = id;
    this.Container = container;

    this.ScriptParser = new SfMediaPlayer.ScriptParser();
    this.Volume = null;
    this.timerManager = null;
    this.partitionManager = null;
    this.embeddedPlayer = null;
    this.pci = null;

    this.ScheduledForLiveCheckInterval = 15000;
    this.OpenForLiveCheckInterval = 5000;
    this.LiveEventPollInterval = 5000;
    this.SkipAmount = 3000;
    this.StopTime = null;
    this.currentMediaState = -1;
    this.currentMediaDuration = 0;
    this.LastSeekPosition = 0;
    this.LastMediaError = null;

    this.OnLoad = MediaPlayerArea.prototype.OnLoad = function() {
        this.partitionManager = new SfMediaPlayer.PartitionManager(Manifest.Slides);
        this.CheckPresentationStatus();
    }

    this.AddEventHandlers = function() {
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.Script, this.ScriptEventHandler.bind(this));
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.SliderNotify, this.SliderNotifyEventHandler.bind(this));

        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.Play, this.PlayEventHandler.bind(this));
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.Pause, this.PauseEventHandler.bind(this));
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.Stop, this.StopEventHandler.bind(this));
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.Mute, this.MuteEventHandler.bind(this));
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.SetVolume, this.SetVolumeEventHandler.bind(this));
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.NavigateToSlide, this.NavigateToSlideEventHandler.bind(this));
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.NavigateToTime, this.NavigateToTimeEventHandler.bind(this));
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.NavigateToChapter, this.NavigateToChapterEventHandler.bind(this));
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.SkipBack, this.SkipBackEventHandler.bind(this));
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.SkipForward, this.SkipForwardEventHandler.bind(this));
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.FullScreen, this.FullScreenEventHandler.bind(this));
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.ChangePlaybackSpeed, this.ChangePlaybackSpeedEventHandler.bind(this));
    }

    this.CheckPresentationStatus = function() {
        var status = Manifest.PlayStatus;

        switch (status) {
            case SfKernel.PresentationPlayStatus.Live:
            case SfKernel.PresentationPlayStatus.LivePaused:
                this.StartLivePlayback(Manifest.Slides.length);
                return;
            case SfKernel.PresentationPlayStatus.OnDemand:
                this.StartPlaying();
                return;
            case SfKernel.PresentationPlayStatus.LiveEnded:
                return;
            case SfKernel.PresentationPlayStatus.ScheduledForLive:
            case SfKernel.PresentationPlayStatus.OpenForLive:
                this.DoNotReadyStuff();
                return;
            default:
                Sys.Debug.trace('Unknown Presentation Status: ' + status);
                return;
        }
    }

    this.DoNotReadyStuff = function() {
        this.HideMediaPlayerDiv();

        var status = Manifest.PlayStatus;
        if (status == SfKernel.PresentationPlayStatus.ScheduledForLive) {
            window.setTimeout(this.Container + ".CheckPresentationStatusFromDB()", this.ScheduledForLiveCheckInterval);
        }
        else if (status == SfKernel.PresentationPlayStatus.OpenForLive) {
            window.setTimeout(this.Container + ".CheckPresentationStatusFromDB()", this.OpenForLiveCheckInterval);
        }
        else {
            Sys.Debug.trace('Invalid status for a live presentation: ' + status);
        }
    }

    this.CheckPresentationStatusFromDB = function() {
        SonicFoundry.Mediasite.Player.DataAccess.PlayerService.GetLiveStatus
		(
			Manifest.PresentationId,
			Function.createDelegate(this, this.GetPresentationStatusInformationOnSuccess),
			Function.createDelegate(this, this.GetPresentationStatusInformationOnFailure),
			'GetLiveStatus'
		);
    }

    this.GetPresentationStatusInformationOnSuccess = function(result, context) {
        if (result.PlayStatus == SfKernel.PresentationPlayStatus.ScheduledForLive) {
            window.setTimeout(this.Container + ".CheckPresentationStatusFromDB()", this.ScheduledForLiveCheckInterval);
        }
        else if (result.PlayStatus == SfKernel.PresentationPlayStatus.OpenForLive) {
            window.setTimeout(this.Container + ".CheckPresentationStatusFromDB()", this.OpenForLiveCheckInterval);
        }
        else if (result.PlayStatus == SfKernel.PresentationPlayStatus.Live || result.PlayStatus == SfKernel.PresentationPlayStatus.LivePaused) {
            Manifest.PlayStatus = result.PlayStatus;
            this.StartLivePlayback(result.CurrentSlide);
        }
    }

    this.GetPresentationStatusInformationOnFailure = function(error, context) {
        Sys.Debug.trace("GetPresentationStatusInformationOnFailure(): " + error.Message);
        window.setTimeout(this.Container + ".CheckPresentationStatusFromDB()", this.ScheduledForLiveCheckInterval);
    }

    this.StartLivePlayback = function(currentSlideNumber) {
        this.AddSlideTimingsIfRequired(currentSlideNumber);
        this.HandleLiveStatusDisplay(Manifest.PlayStatus);
        mPlayer.EventManager.PostEvent(SfKernel.EventType.LivePlaybackStarted, this, null);
        this.StartPlaying();
    }

    this.HandleMediaPlayerError = function(errorMsg) {
        if (mPlayer.PresentationEnded) {
            return;
        }

        if (Manifest.PlayStatus == SfKernel.PresentationPlayStatus.Live || Manifest.PlayStatus == SfKernel.PresentationPlayStatus.LivePaused) {
            this.LastMediaError = errorMsg;

            SonicFoundry.Mediasite.Player.DataAccess.PlayerService.GetLiveStatus
		    (
			    Manifest.PresentationId,
			    Function.createDelegate(this, this.CheckLiveErrorOnSuccess),
			    Function.createDelegate(this, this.GetPresentationStatusInformationOnFailure),
			    'GetLiveStatus'
		    );
        }
        else {
            this.ShowMediaErrorDialog(errorMsg);
        }
    }

    this.CheckLiveErrorOnSuccess = function(result, context) {
        if (result.PlayStatus != SfKernel.PresentationPlayStatus.Live && result.PlayStatus != SfKernel.PresentationPlayStatus.LivePaused) {
            mPlayer.EventManager.PostEvent(SfKernel.EventType.Script, this, { Command: SfKernel.ScriptCmdType.EndPresentation });
        }
        else {
            this.ShowMediaErrorDialog(this.LastMediaError);
        }
    }

    this.ShowMediaErrorDialog = function(errorMsg) {
        var presentationFailureErrorDialog = new DialogBox('mediaErrorDialog');
        presentationFailureErrorDialog.Message = errorMsg;
        presentationFailureErrorDialog.Title = 'Mediasite Player Error';
        presentationFailureErrorDialog.Id = 'mediaErrorDialog';
        presentationFailureErrorDialog.okButton = true;
        presentationFailureErrorDialog.OnLoad();
        return false;
    }

    this.ShowMediaPlayerDiv = function() {
        var playerElement = $('PlayerVideo');
        if (playerElement) {
            playerElement.style.display = '';
        }

        var notReady = $('PlayerNotStarted');
        if (notReady) {
            notReady.style.display = 'none';
        }
    }

    this.HideMediaPlayerDiv = function() {
        var playerElement = $('PlayerVideo');
        if (playerElement) {
            playerElement.style.height = '1px';
        }

        var notReady = $('PlayerNotStarted');
        if (notReady) {
            notReady.style.display = '';
        }
    }

    //	this.HideVideo = function()
    //	{
    //	    var playerElement = $('PlayerVideo');
    //	    if(playerElement)
    //	    {
    //	        
    //	    }
    //	}

    this.HandleAudioOnly = function() {
        if (!Manifest.HasVideo) {
            var fullScreenButton = $('btnFullScreen');
            if (fullScreenButton) {
                fullScreenButton.style.display = 'none';
            }

            var embeddedPlayer = $('EmbeddedPlayer');
            embeddedPlayer.style.height = '0px';
            var audioOnlyImage = $('PlayerAudioOnly');
            if (!this.IsCompact()) {
                var videoContainer = $('VideoContainer');
                var playerElement = $('PlayerVideo');
                var presentationCard = $('PresentationCardArea');
                var presentationCardScrollDiv = $('PresentationCardAreaScrollDiv');
                var playerContainer = $('PlayerContainer');
                var chapterPointsDialog = $('ChapterPointsPanelDialog');
                var chapterPointsDialogMessage = $('ChapterPointsPanelDialogMessage');
                if (audioOnlyImage) {
                    audioOnlyImage.style.display = 'none';
                }
                videoContainer.style.height = '0px';
                playerElement.style.height = '0px';
                var currentPCHeight = presentationCard.offsetHeight;
                var currentPCTop = presentationCard.offsetTop;
                var currentMediaTop = playerContainer.offsetTop;
                var videoContainerLeft = videoContainer.offsetLeft;

                var titleBannerHeight = $('TitleBanner').offsetHeight;
                var mediaPlayerHeight = $('CommandBar').offsetHeight + $('StatusBar').offsetHeight + $('PlayerControls').offsetHeight;
                var newPCHeight = (LayoutOptions.PlayerHeight - mediaPlayerHeight - titleBannerHeight - 10);
                presentationCard.style.height = (newPCHeight) + "px";
                presentationCardScrollDiv.style.height = ((newPCHeight) - 12) + "px";
                if ($('ChapterPointsPanelDialog')) {
                    chapterPointsDialog.style.height = (newPCHeight) + "px";
                    chapterPointsDialogMessage.style.height = (newPCHeight - 25) + "px";
                }

                if (LayoutOptions.SlideHeight == 0 || LayoutOptions.SlideWidth == 0) {
                    presentationCard.style.left = (videoContainerLeft + 3) + 'px';
                    presentationCard.style.width = (LayoutOptions.PlayerWidth - 8) + 'px';
                    if ($('ChapterPointsPanelDialog')) {
                        chapterPointsDialog.style.width = (LayoutOptions.PlayerWidth - 8) + 'px';
                        chapterPointsDialogMessage.style.width = (LayoutOptions.PlayerWidth - 8) + 'px';
                    }
                }

                if (LayoutOptions.DefaultPosition == '1' || LayoutOptions.DefaultPosition == '2') {
                    presentationCard.style.top = (titleBannerHeight + mediaPlayerHeight + 6) + "px";
                }
                if (LayoutOptions.DefaultPosition == '3' || LayoutOptions.DefaultPosition == '4') {
                    playerContainer.style.top = (titleBannerHeight + newPCHeight + 35) + "px";
                }
            }
            else {
                if (audioOnlyImage) {
                    audioOnlyImage.style.display = 'block';
                }
            }
        }
    }

    this.IsCompact = function() {
        var isCompact = (LayoutOptions.VideoWidth == '400' && LayoutOptions.SlideWidth == '360') ? true : false;
        return isCompact;
    }

    this.HandleLiveStatusDisplay = function(status) {
        var liveIndicator = $('LiveIndicatorAreaImg');
        if (!liveIndicator || Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand) {
            return;
        }

        switch (status) {
            case SfKernel.PresentationPlayStatus.Live:
                liveIndicator.style.display = '';
                liveIndicator.setAttribute('title', Localization.LiveIndicatorResource.LiveTooltip);
                liveIndicator.setAttribute('alt', Localization.LiveIndicatorResource.LiveTooltip);
                liveIndicator.src = LayoutOptions.ThemeImageBase + '/liveIndicator.gif';
                break;
            case SfKernel.PresentationPlayStatus.LivePaused:
                liveIndicator.style.display = '';
                liveIndicator.setAttribute('title', Localization.LiveIndicatorResource.PausedTooltip);
                liveIndicator.setAttribute('alt', Localization.LiveIndicatorResource.PausedTooltip);
                liveIndicator.src = LayoutOptions.ThemeImageBase + '/liveIndicator_paused.gif';
                break;
            default:
                liveIndicator.style.display = 'none';
                break;
        }
    }

    this.AddSlideTimingsIfRequired = function(currentSlideNumber) {
        if (currentSlideNumber == -1) {
            return;
        }
        mPlayer.KeepAddingToSlideTimings(currentSlideNumber);
    }

    this.StartPlaying = function() {
        this.SetupPlayer();
        this.ShowMediaPlayerDiv();
    }

    this.CheckIfLiveEnded = function(playState) {
        if (Manifest.PlayStatus != SfKernel.PresentationPlayStatus.Live && Manifest.PlayStatus != SfKernel.PresentationPlayStatus.LivePaused) {
            return;
        }

        if (playState == SfKernel.MediaState.Stopped || playState == SfKernel.MediaState.Paused) {
            SonicFoundry.Mediasite.Player.DataAccess.PlayerService.GetLiveStatus
		    (
			    Manifest.PresentationId,
			    Function.createDelegate(this, this.LiveStatusCheckStopOnSuccess),
			    Function.createDelegate(this, this.GetPresentationStatusInformationOnFailure),
			    'GetLiveStatus'
		    );
        }

    }

    this.LiveStatusCheckStopOnSuccess = function(result, context) {
        if (result.PlayStatus != SfKernel.PresentationPlayStatus.Live && result.PlayStatus != SfKernel.PresentationPlayStatus.LivePaused) {
            mPlayer.EventManager.PostEvent(SfKernel.EventType.Script, this, { Command: SfKernel.ScriptCmdType.EndPresentation });
        }
    }

    this.LiveStatusCheckStartOnSuccess = function(result, context) {
        if (result.PlayStatus != SfKernel.PresentationPlayStatus.Live && result.PlayStatus != SfKernel.PresentationPlayStatus.LivePaused) {
            mPlayer.EventManager.PostEvent(SfKernel.EventType.Script, this, { Command: SfKernel.ScriptCmdType.EndPresentation });
        }
        else {
            if (result.CurrentSlide > 0 && result.CurrentSlide > mPlayer.CurrentSlideNumber) {
                for (var i = mPlayer.CurrentSlideNumber; i < result.CurrentSlide; i++) {
                    this.ScriptParser.HE('S', i + 1);
                }
            }
            if (Manifest.PlayStatus != result.PlayStatus) {
                Manifest.PlayStatus = result.PlayStatus;
                this.HandleLiveStatusDisplay(Manifest.PlayStatus);
            }
        }
    }

    this.AdjustSize = function() {
        $('PlayerVideo').style.width = LayoutOptions.VideoWidth + 'px';
        $('PlayerVideo').style.height = LayoutOptions.VideoHeight + 'px';
        $('VideoContainer').style.width = LayoutOptions.VideoWidth + 'px';
        $('VideoContainer').style.height = LayoutOptions.VideoHeight + 'px';

        if ($('EmbeddedPlayer')) {
            $('EmbeddedPlayer').style.width = LayoutOptions.VideoWidth + 'px';
            $('EmbeddedPlayer').style.height = LayoutOptions.VideoHeight + 'px';
        }
    }

    this.InitVolume = function() {
        var initVolume = new MediasitePlayerCookie().GetValue("Volume");
        if (initVolume == undefined) {
            initVolume = 50;
        }
        this.Volume.SetVolume(initVolume);
        this.Volume.InitializeVolume(initVolume);
    }

    this.CheckStartStopTimes = function() {
        if (Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand) {
            var playFrom = SfKernel.GetQueryStringValue("playfrom");
            var duration = SfKernel.GetQueryStringValue("duration");
            if (playFrom != null) {
                this.SetStartTime(Number(playFrom));
                if (duration != null) {
                    this.StopTime = Number(playFrom) + Number(duration);
                }
            }
            else if (duration != null) {
                this.StopTime = Number(duration);
            }

            var autoStart = SfKernel.GetQueryStringValue("autostart");

            if (autoStart != null && autoStart.toLowerCase() == "false") {
                this.Pause();
            }

        }
    }

    this.PostMediaLengthObtainedEvent = function() {
        this.currentMediaDuration = this.pci.GetMediaDuration();
        mPlayer.EventManager.PostEvent(SfKernel.EventType.MediaLengthObtained, this, { Left: 0, Right: this.currentMediaDuration });
    }

    this.PlayEventHandler = function(sender, args) {
        this.Play();
    }

    this.PauseEventHandler = function(sender, args) {
        this.Pause();
    }

    this.StopEventHandler = function(sender, args) {
        this.Stop();
    }

    this.SkipBackEventHandler = function(sender, args) {
        this.SkipInVideo(this.SkipAmount * -1);
    }
    this.SkipForwardEventHandler = function(sender, args) {
        this.SkipInVideo(this.SkipAmount);
    }

    this.SkipInVideo = function(SkipInMS) {
        var position = this.pci.GetPosition();

        if (position < this.LastSeekPosition) {
            position = this.LastSeekPosition;
        }

        var newPosition = position += SkipInMS;

        if (newPosition < 0) {
            newPosition = 0;
        }
        else if (newPosition > this.pci.GetMediaDuration()) {
            return;
        }

        this.SetStartTime(newPosition);
    }

    this.MuteEventHandler = function(sender, args) {
        this.Mute();
    }

    this.SetVolumeEventHandler = function(sender, args) {
        this.SetVolume(args.Volume);
    }

    this.NavigateToSlideEventHandler = function(sender, args) {
        this._NavigateToSlide(args.SlideNumber);
    }

    this.NavigateToTimeEventHandler = function(sender, args) {
        this._NavigateToTime(args.Time);
    }

    this.NavigateToChapterEventHandler = function(sender, args) {
        this._NavigateToChapter(args.Number, args.Time);
    }

    this.FullScreenEventHandler = function(sender, args) {
        this.FullScreen();
    }

    this.ChangePlaybackSpeedEventHandler = function(sender, args) {
        this.pci.SetPlaybackSpeed(args["PlaybackSpeed"]);
    }

    this.ScriptEventHandler = function(sender, args) {
        switch (args.Command) {
            case SfKernel.ScriptCmdType.Pause:
                this.HandleLiveStatusDisplay(SfKernel.PresentationPlayStatus.LivePaused);
                break;
            case SfKernel.ScriptCmdType.Resume:
                this.HandleLiveStatusDisplay(SfKernel.PresentationPlayStatus.Live);
                break;
            case SfKernel.ScriptCmdType.EndPresentation:
                if (Manifest.PlayStatus == SfKernel.PresentationPlayStatus.Live || Manifest.PlayStatus == SfKernel.PresentationPlayStatus.LivePaused) {
                    Manifest.PlayStatus = SfKernel.PresentationPlayStatus.LiveEnded
                    this.HandleLiveStatusDisplay(Manifest.PlayStatus);
                }
                mPlayer.PresentationEnded = true;
                mPlayer.CurrentSlideNumber = -1;
                this.Stop();
                break;
        }
    }

    this.SliderNotifyEventHandler = function(sender, objNotify) {
        switch (objNotify.NotifyType) {
            case SfKernel.SliderNotifyType.NewPosition:
                this.SetStartTime(objNotify.Position);
                this.StopTime = null;
                var state = this.pci.GetPlayState();
                if (state != SfKernel.MediaState.Playing && state != SfKernel.MediaState.Paused) {
                    mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.Play, this, null);
                }
                break;
        }
    }

    this.Play = function() {
        var currentPos = this.pci.GetPosition();
        if (currentPos == 0 && Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand) {
            mPlayer.CurrentSlideNumber = -1;
            mPlayer.EventManager.PostEvent(SfKernel.EventType.PlayingFromBeginning, this, null);
        }

        if (Manifest.PlayStatus == SfKernel.PresentationPlayStatus.Live || Manifest.PlayStatus == SfKernel.PresentationPlayStatus.LivePaused) {
            SonicFoundry.Mediasite.Player.DataAccess.PlayerService.GetLiveStatus
		    (
			    Manifest.PresentationId,
			    Function.createDelegate(this, this.LiveStatusCheckStartOnSuccess),
			    Function.createDelegate(this, this.GetPresentationStatusInformationOnFailure),
			    'GetLiveStatus'
		    );

            this.SetMediaSource();
        }

        this.pci.Play();
        this.timerManager.Start();
        mPlayer.PresentationEnded = false;
    }

    this.Pause = function() {
        this.pci.Pause();
        this.timerManager.Stop();
    }

    this.Stop = function() {
        this.pci.Stop();
        this.timerManager.Stop();
        this.StopTime = null;
        mPlayer.SamiDropDownPanelInstance.Reset();
        this.LastSeekPosition = 0;
    }

    this.Mute = function() {
        if (this.Volume) {
            this.Volume.ToggleMute();
        }
    }

    this.SetVolume = function(vol) {
        this.Volume.SetVolume(vol);
    }

    this.FullScreen = function() {
        if (this.pci.GetPlayState() != SfKernel.MediaState.Stopped) {
            this.pci.SetFullScreen(true);
        }
    }

    this.SetAudioLanguageIndex = function(index) {
        this.pci.SetAudioLanguageIndex(index);
    }

    this._NavigateToTime = function(timeInMS) {
        this.SetStartTime(timeInMS);
        mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.Play, this, null);
    }

    this.SetStartTime = function(timeInMS) {
        this.pci.SetPosition(timeInMS);
        this.timerManager.PostTimerUpdatedEvent(timeInMS);
        mPlayer.SamiDropDownPanelInstance.Seek(timeInMS);
        this.LastSeekPosition = timeInMS;
        mPlayer.PresentationEnded = false;

        if (mPlayer.CurrentSlidePanelInstance) {
            this.HandleSlideChangeWhenPositionChanges(timeInMS);
        }
    }

    this.SetMediaSource = function() {
        this.pci.SetMedia(Manifest.VideoUrl);
    }

    this._NavigateToSlide = function(slideNumber) {
        if (Manifest.PlayStatus != SfKernel.PresentationPlayStatus.OnDemand) {
            return;
        }
        if (slideNumber < 0) {
            return;
        }
        if (Manifest.Slides.length < slideNumber) {
            return;
        }

        var timeCode = (slideNumber == 0) ? 0.00 : Manifest.Slides[slideNumber - 1].Time;

        this._NavigateToTime(timeCode);
    }

    this._NavigateToChapter = function(number, timeInMilliSeconds) {
        this._NavigateToTime(timeInMilliSeconds);
    }

    this.HandleSlideChangeWhenPositionChanges = function(pos) {
        if (mPlayer.PresentationEnded) {
            return;
        }

        var slideNumber = this.partitionManager.GetSlideNumberToShow(pos);

        if (slideNumber < 1) {
            mPlayer.CurrentSlideNumber = -1;
            mPlayer.EventManager.PostEvent(SfKernel.EventType.PlayingFromBeginning, this, null);
            return;
        }

        if (slideNumber != mPlayer.CurrentSlideNumber) {
            var args = mPlayer.CreateShowSlideEventArgs(slideNumber);
            mPlayer.CurrentSlideNumber = slideNumber;
            mPlayer.EventManager.PostEvent(SfKernel.EventType.Script, this, args);
        }

    }

}
MediaPlayerArea.registerClass('MediaPlayerArea');


Type.registerNamespace('SfMediaPlayer');

SfMediaPlayer.ScriptParser = function()
{
	this.ParseScriptFromStream = function(sType, sParam)
	{
	    if(sType == "MS5")
	    {
	        eval("this." + sParam);
	    }	
	}
		
	this.HE = function()
	{
		if (arguments.length < 1)
		{
			return;
		}
		
		var command = arguments[0];
		switch (command)
		{
			case "S":
			    if(!mPlayer.CurrentSlidePanelInstance)
			    {
			        return;
			    }
				if (arguments.length < 2)
				{
					return;
				}

				var slideNumber = Number(arguments[1]);

				if (slideNumber <= mPlayer.CurrentSlideNumber)
				{
				    return;
				}

				if (Manifest.Slides.length < slideNumber)
				{
					mPlayer.KeepAddingToSlideTimings(slideNumber);
					mPlayer.DynamicAdd = true;
				}
				else
				{
					mPlayer.DynamicAdd = false;
				}
				
				mPlayer.CurrentSlideNumber = slideNumber;
				var args = mPlayer.CreateShowSlideEventArgs(slideNumber);
				this.NotifyScriptEvent(args);
				break;
			case "E":
				this.NotifyScriptEvent({Command: SfKernel.ScriptCmdType.EndPresentation});
				break;
			case "P":                        
				this.NotifyScriptEvent({Command: SfKernel.ScriptCmdType.Pause});
				break;
			case "R":
				this.NotifyScriptEvent({Command: SfKernel.ScriptCmdType.Resume});
				break;
		}
	} 

	this.NotifyScriptEvent = function(oArgs)
	{
		mPlayer.EventManager.PostEvent(SfKernel.EventType.Script, this, oArgs);
	}
		
}

SfMediaPlayer.Partition = function(left, right)
{
	this.MinIndex = left;
	this.MaxIndex = right;
	this.Left = null;
	this.Right = null;
}
SfMediaPlayer.Partition.prototype = 
{
	GetCount : function()
	{
		return this.MaxIndex - this.MinIndex + 1;
	},
	
	CreateSubPartitions : function()
	{
		var middle = Math.floor( (this.MinIndex + this.MaxIndex) / 2 );
		this.Left = new SfMediaPlayer.Partition(this.MinIndex, middle);
		this.Right = new SfMediaPlayer.Partition(middle+1, this.MaxIndex);
		return {Left:this.Left, Right:this.Right};
	}
}
SfMediaPlayer.Partition.registerClass('SfMediaPlayer.Partition', null);

SfMediaPlayer.PartitionManager = function(timings)
{
	this._timings = timings;
	this._timeCode = null;
}
SfMediaPlayer.PartitionManager.prototype = 
{
	GetSlideNumberToShow : function(timeCode)
	{
		if (this._timings.length == 0)
		{
			return 0;
		}
		
		this._timeCode = timeCode;
	
		return this._FindInPartition(new SfMediaPlayer.Partition(0, this._timings.length-1));	
	},
	
	_FindInPartition : function(partition)
	{
		var count = partition.GetCount();
		if (count == 1)
		{
			return this._FindIn1Partition(partition);
		}
		else if (count == 2)
		{
			return this._FindIn2Partition(partition);
		}
		
		partition.CreateSubPartitions();

		if (this._timeCode < this._timings[partition.Left.MinIndex].Time)
		{
			return partition.Left.MinIndex;
		}
		else if (this._IsPresentInPartition(partition.Left) == true)
		{
			return this._FindInPartition(partition.Left);			
		}
		else if (this._timeCode < this._timings[partition.Right.MinIndex].Time)
		{
			return partition.Right.MinIndex;
		}
		else if (this._IsPresentInPartition(partition.Right) == true)
		{
			return this._FindInPartition(partition.Right);
		}
		else
		{
			return partition.Right.MaxIndex+1;
		}
	},
	
	_FindIn1Partition : function(partition)
	{
		var partitionTime = this._timings[partition.MinIndex].Time;
		
		if (this._timeCode < partitionTime)
		{
			return partition.MinIndex;
		}
		else
		{
			return partition.MinIndex+1;			
		}
	},
	
	_FindIn2Partition : function(partition)
	{
		var time1 = this._timings[partition.MinIndex].Time;
		var time2 = this._timings[partition.MaxIndex].Time

		if (this._timeCode < time1)
		{
			return partition.MinIndex;
		}
		else if (this._timeCode >= time1 && this._timeCode < time2)
		{
			return partition.MinIndex+1;
		}
		else
		{
			return partition.MaxIndex+1;
		}
	},
	
	_IsPresentInPartition : function(partition)
	{
		return (this._timeCode >= this._timings[partition.MinIndex].Time && this._timeCode <= this._timings[partition.MaxIndex].Time);
	}
}


/// MediaPlayer Volume Helper Class
SfMediaPlayer.Volume = function(pci)
{
	this.IsMuted = false;
	this.PreviousVolume = null;
	this.pci = pci;
	
	this.InitializeVolume = function(vol)
	{
		this.PostVolumeInitializedEvent(vol);
	}
		
	this._GetVolumeFromPlayer = function()
	{
	    if (this.pci == null)
	    {
	        return 0;
	    }
	     
	        
	    return this.pci.GetVolume();
	}
	
	this.ToggleMute = function()
	{
	    if (this.IsMuted)
	    {
	    	this.pci.SetMute(false);
	    	
	    	if (this.PreviousVolume != null)
			{
				this.pci.SetVolume(this.PreviousVolume);
	        }
	        
	        this.IsMuted = false;
	        this.PostMuteCommand(false);
	    }
	    else
	    {
			this.PreviousVolume = this.pci.GetVolume();
	    	this.pci.SetMute(true);
	        
	        this.IsMuted = true;
	        this.PostMuteCommand(true);
	    }
	}
	
	this.SetVolume = function(val)
	{
		if (this.IsMuted)
		{
			if (val > 0)
			{
				this.ToggleMute();
			}
		}
		else
		{
			if (val == 0)
			{
				this.ToggleMute();
			}
		}
		
		this.pci.SetVolume(val);
		
		new MediasitePlayerCookie().SetValue("Volume", Math.round(val));

	}
	
	this.PostVolumeInitializedEvent = function(val)
	{
		mPlayer.EventManager.PostEvent(SfKernel.EventType.VolumeInitialized, this, {Volume:val});
	}
	
	this.PostMuteCommand = function(mute)
	{
		mPlayer.EventManager.PostEvent(SfKernel.EventType.MuteToggled, this, mute);
	}
}

SfMediaPlayer.TimerManager = function(mediaPlayer) {

    this.player = mediaPlayer;

    this.updateTimer = null;
    this.updateTimerInterval = 200;

    this.pollLiveEventsTimer = null;
    this.pollLiveEvents = false;


    this.Start = function() {
        clearTimeout(this.updateTimer);
        this.TimedUpdate();

        if (this.pollLiveEvents) {
            clearTimeout(this.pollLiveEventsTimer);
            this.PollForLiveEvents();
        }
    }

    this.Stop = function() {
        this.PostTimerUpdatedEvent(this.player.pci.GetPosition());
        clearTimeout(this.updateTimer);
        clearTimeout(this.pollLiveEventsTimer);
    }

    this.PostTimerUpdatedEvent = function(pos) {
        mPlayer.EventManager.PostEvent(SfKernel.EventType.TimerLoop, this, { "Position": pos });
    }

    this.TimedUpdate = function() {
        if (!mPlayer.PlayerSliderInstance.IsCurrentlyDragging && this.player.pci.GetPlayState() == SfKernel.MediaState.Playing) {
            var currentPosition = this.player.pci.GetPosition();

            if (this.player.LastSeekPosition > currentPosition) {
                this.updateTimer = setTimeout(this.TimedUpdate.bind(this), this.updateTimerInterval);
                return;
            }

            this.PostTimerUpdatedEvent(currentPosition);

            if (this.player.StopTime && this.player.StopTime < currentPosition) {
                this.player.Pause();
                this.player.StopTime = null;
                mPlayer.PlayerPositionPanelInstance.SetDisplayText(Localization.MediaPlayer.ClipEnded);
                return;
            }

            if ((this.player.currentMediaDuration > 0) && ((currentPosition + 250) > this.player.currentMediaDuration)) {
                mPlayer.EventManager.PostEvent(SfKernel.EventType.Script, this, { Command: SfKernel.ScriptCmdType.EndPresentation });
                return;
            }
        }

        this.updateTimer = setTimeout(this.TimedUpdate.bind(this), this.updateTimerInterval);
    }

    this.PollForLiveEvents = function() {
        SonicFoundry.Mediasite.Player.DataAccess.PlayerService.GetLiveStatus
		(
			Manifest.PresentationId,
			Function.createDelegate(this, this.GetPresentationStatusInformationOnSuccess),
			Function.createDelegate(this, this.GetPresentationStatusInformationOnFailure),
			'GetLiveStatus'
		);
    }

    this.GetPresentationStatusInformationOnSuccess = function(result, context) {
        if (result.PlayStatus != SfKernel.PresentationPlayStatus.Live && result.PlayStatus != SfKernel.PresentationPlayStatus.LivePaused) {
            mPlayer.EventManager.PostEvent(SfKernel.EventType.Script, this, { Command: SfKernel.ScriptCmdType.EndPresentation });
        }
        else {
            if (result.CurrentSlide > 0 && result.CurrentSlide > mPlayer.CurrentSlideNumber) {
                for (var i = mPlayer.CurrentSlideNumber; i < result.CurrentSlide; i++) {
                    this.player.ScriptParser.HE('S', i + 1);
                }
            }
            if (Manifest.PlayStatus != result.PlayStatus) {
                Manifest.PlayStatus = result.PlayStatus;
                this.player.HandleLiveStatusDisplay(Manifest.PlayStatus);    
            }
            
            this.pollLiveEventsTimer = setTimeout(this.PollForLiveEvents.bind(this), this.player.LiveEventPollInterval);
        }
    }

    this.GetPresentationStatusInformationOnFailure = function(error, context) {
        Sys.Debug.trace("GetPresentationStatusInformationOnFailure(): " + error.Message);
        this.pollLiveEventsTimer = setTimeout(this.PollForLiveEvents.bind(this), this.player.LiveEventPollInterval);
    }
}


/// MediaPlayer Status Display
PlayerStatusPanel = function(container, containingWindow, id)
{
	this.ID = id;
	
	this.OnLoad = function()
	{
		this.AddEventHandlers();
	}
	
	this.AddEventHandlers = function()
	{
		mPlayer.EventManager.Events.addHandler(SfKernel.EventType.PlayStateChanged, this.PlayStateChangedEventHandler.bind(this));
	}
	
	this.PlayStateChangedEventHandler = function(sender, state)
	{
		this.UpdateStatus(state);
	}
	
	this.UpdateStatus = function(status)
	{
		var name = SfKernel.GetPlayStateName(status);
		$(this.ID).innerHTML = name;
	}
}

/// MediaPlayer Language Selector
LanguageDropDownArea = function(container, containingWindow, id)
{
    this.ID = id;
    this.Container = container;
}
LanguageDropDownArea.prototype =
{
    LoadLanguages : function(Languages, CurrentIndex)
    {
  		this.Show();

		var template = new SfUI.Menu.MenuTemplate();
		template.CssPrefix = "LanguageSelectionMenu";
		template.LocationInfo = new SfUI.Menu.LocationInfo(0, 0, 40, 18);
		template.SubMenuSizeInfo = new SfUI.Menu.SizeInfo(150, 20);
		template.BaseBorderWidth = 0;
		template.BaseRightDivWidth = 16;
		template.LeftDivWidth = 19;
		var group = new SfUI.Menu.LeafGroup();
	    this.BaseMenuItem = new SfUI.Menu.BaseMenuItem(this.Container + ".BaseMenuItem", '', template, Localization.Common.Language);
	    //this.BaseMenuItem.SetToolTip(Localization.Common.Language);
		
		for (var i=0; i<Languages.length; ++i)
		{
			var func = new Function("", "mPlayer.PlayerAreaInstance.SetAudioLanguageIndex(" + Languages[i].Index + ");");
			var leaf = this.BaseMenuItem.AddLeaf(Languages[i].DisplayName, func);
			group.Add(leaf);
			if (i== (CurrentIndex-1))
			{
				group.Select(leaf);
			}
		}

		this.BaseMenuItem.CollapseChildrenNow();
		$(this.ID).appendChild(this.BaseMenuItem.RootDiv);

    },
    
	OnLoad : function()
	{
	    this.Hide();		
	},
	
	Show : function() 
	{
        $(this.ID).style.display = '';
    },
    
    Hide : function() 
    {
        $(this.ID).style.display = 'none';
    }
}

/// Media Player Position Display
PlayerPositionPanel=function(container,containingWindow,id){this.ID = id;}
PlayerPositionPanel.prototype={
    isDragging: false,    
    duration: 0,
       
    OnLoad:function()
    {    
        this.AddHandlers();
    },
        
    AddHandlers:function()
    {
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.MediaLengthObtained,Function.createDelegate(this,this.SetDuration));
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.SliderNotify,Function.createDelegate(this,this.SliderNotifyHandler));
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.TimerLoop,Function.createDelegate(this,this.TimerLoopHandler));
        
    },
    
    SetDuration:function(sender,args)
    {        
        this.duration=args['Right'];
    },
    
    SliderNotifyHandler:function(sender,args)
    {
        var notifyType=args['NotifyType'];
        switch(notifyType)
        {
            case SfKernel.SliderNotifyType.NewPosition:
                this.UpdatePosition(args['Position']);
            break;
            case SfKernel.SliderNotifyType.DragPosition:
                this.UpdatePosition(args['Position']);
            break;
            case SfKernel.SliderNotifyType.BeginDrag:
                this.isDragging=true;
            break;
            case SfKernel.SliderNotifyType.EndDrag:
                this.isDragging=false;
            break;
        }        
    },
    
    UpdatePosition:function(pos)
    {
        var display = SfKernel.GetDisplayDuration(pos);
        if(this.duration > 0)
        {
            display += '/'+SfKernel.GetDisplayDuration(this.duration);
        }
        $(this.ID).innerHTML= display;
    },
    
    SetDisplayText:function(text)
    {
        $(this.ID).innerHTML=text;
    },
    
    TimerLoopHandler:function(sender,args)
    {
        if(this.isDragging){return;}this.UpdatePosition(args['Position']);
    }
 }

/// MediaPlayer Captioning Display
 SamiDropDownPanel = function(container, containingWindow, id) {
     this.ID = id;
     this.Container = container;

     this.IsClosedCaptioningVisible = false;
     this.ShowCaptioningText = Localization.PlayerLayoutResource.ShowCaptioning;
     this.HideCaptioningText = Localization.PlayerLayoutResource.HideCaptioning;
     this.CurrentIndex = -1;
     this.diplayArea = null;
     this.SelectedClass = 0;

     this.OnLoad = function() {
         if (Manifest.CaptionsFile.length < 1) {
             $(this.ID + 'Container').style.display = 'none';
             return;
         }

         this.Toggle = $('btnCC');
         this.displayArea = $(this.ID + 'Display');
         this.CaptioningContainer = $(this.ID + 'Container');

         this.CaptioningContainer.style.display = 'none';
         this.Toggle.style.display = '';

         this.Toggle.onclick = new Function("", this.Container + ".ToggleClosedCaptioning();");
         mPlayer.EventManager.Events.addHandler(SfKernel.EventType.TimerLoop, this.TimerLoopEventHandler.bind(this));
     }

     this.TimerLoopEventHandler = function(sender, args) {
         this.CheckAdvance(args["Position"]);
     }

     this.ToggleClosedCaptioning = function() {
         if (this.IsClosedCaptioningVisible) {
             $('PresentationCardAreaInnerPadding').style.display = 'block';
             this.CaptioningContainer.style.display = 'none';

             if (document.all) {
                 this.Toggle.title = this.ShowCaptioningText;
             }
             else {
                 this.Toggle.title = this.ShowCaptioningText;
             }
         }
         else {
             $('PresentationCardAreaInnerPadding').style.display = 'none';
             this.CaptioningContainer.style.display = 'block';
             //this.CaptioningContainer.style.height = '100%';

             if (document.all) {
                 this.Toggle.title = this.HideCaptioningText;
             }
             else {
                 this.Toggle.title = this.HideCaptioningText;
             }

         }

         this.IsClosedCaptioningVisible = !this.IsClosedCaptioningVisible;
     }

     this.Seek = function(currentPosition) {
         if (Manifest.CaptionsFile.length < 1) {
             return;
         }

         var currentTranscriptIndex = -1;

         while ((currentTranscriptIndex + 1) < Transcript.EventList[this.SelectedClass].length) {
             var time = Transcript.EventList[this.SelectedClass][currentTranscriptIndex + 1].Time;

             if (currentPosition >= time) {
                 currentTranscriptIndex++;
             }
             else {
                 break;
             }
         }

         this.SetTextIndex(currentTranscriptIndex);
     }

     this.Reset = function() {
         if (Manifest.CaptionsFile.length < 1) {
             return;
         }
         this.SetTextIndex(-1);
     }


     this.CheckAdvance = function(currentPosition) {
         if (Manifest.CaptionsFile.length < 1) {
             return;
         }

         var currentTranscriptIndex = this.CurrentIndex;

         if (currentTranscriptIndex < 0) {
             currentTranscriptIndex = -1;
         }

         while ((currentTranscriptIndex + 1) < Transcript.EventList[this.SelectedClass].length) {
             var time = Transcript.EventList[this.SelectedClass][currentTranscriptIndex + 1].Time;

             if (currentPosition >= time) {
                 currentTranscriptIndex++;
             }
             else {
                 break;
             }
         }

         if (currentTranscriptIndex > this.CurrentIndex) {
             this.SetTextIndex(currentTranscriptIndex);
         }
     }

     this.SetTextIndex = function(index) {
         this.CurrentIndex = index;

         if (index < 0) {
             this.SetText("");
         }
         else if (index < Transcript.EventList[this.SelectedClass].length) {
             var ccHeader = Transcript.EventList[this.SelectedClass][index].SourceText;
             var ccBody = Transcript.EventList[this.SelectedClass][index].Text;

             var ccText = "";

             if (ccHeader.length > 0) {
                ccText += "<b>" + ccHeader + "</b><br>";
             }
             ccText += ccBody;

             this.SetText(ccText);
         }
     }

     this.SetText = function(text) {
         if (this.displayArea) {
             this.displayArea.innerHTML = text;
         }
     }


 }


/// MediaPlayer Play/Pause Button
PlayPauseButton = function(id, container)
{
	this.id = id;
	this.IsEnabled = false;
	this.IsHilighted = false;
	this.Container =  container;
	
	this.PlayImageDetails = new SfUI.ButtonImage();
	this.PauseImageDetails = new SfUI.ButtonImage();
	this.StopImageDetails = new SfUI.ButtonImage();
	this.ToolTipPlay;
	this.ToolTipPause;
	this.ToolTipStop;
	
	var m_this = this;
	var m_link = null;
	var m_imageElement = null;
	var m_currentImageDetails = null;
	
	this.AllowPlay = true;
	
	this.Initialize = function()
	{

		m_imageElement = GetImage();
		m_link = GetLink();
		
		m_link.onmouseover = new Function("", this.Container + ".button.OnMouseOver();");
		m_link.onmouseout = new Function("", this.Container + ".button.OnMouseOut();");
		m_link.onclick = new Function("", this.Container + ".OnClick();");

		this._PreLoadImages();
				
		this.SetPlayImage();		
	}
	
	this._PreLoadImages = function()
	{
	    
	    try
	    {
		    var img = new Image();
		    img.src = this.StopImageDetails.Over;
		    img.src = this.StopImageDetails.Normal;
		    img.src = this.StopImageDetails.Disabled;		
		    img.src = this.PauseImageDetails.Over;
		    img.src = this.PauseImageDetails.Normal;
		    img.src = this.PauseImageDetails.Disabled;
		    img.src = this.PlayImageDetails.Over;
		    img.src = this.PlayImageDetails.Normal;
		    img.src = this.PlayImageDetails.Disabled;
		}
		catch (e) {
		    //BUG27639 for IE8 on redirects
		}
	}
	
	this.SetPlayImage = function()
	{
		m_currentImageDetails = m_this.PlayImageDetails;
		this.AllowPlay = true;
		this.Paint();
		this.SetToolTip(this.ToolTipPlay);
	}
	
	this.SetPauseImage = function()
	{
		m_currentImageDetails = m_this.PauseImageDetails;
		this.AllowPlay = false;
		this.Paint();
		this.SetToolTip(this.ToolTipPause);
	}
	
	this.SetStopImage = function()
	{
		m_currentImageDetails = m_this.StopImageDetails;
		this.AllowPlay = false;
		this.Paint();
		this.SetToolTip(this.ToolTipStop);
	}

	var GetImage = function()
	{
		var image = document.getElementById(m_this.id + "Img");
					
		return image;
	}
	
	var GetLink = function()
	{
		var link = document.getElementById(m_this.id + "Link");
				
		return link;
	}
	
	this.SetToolTip = function(strToolTip)
	{
		m_imageElement.alt = strToolTip;
		m_link.title = strToolTip;
	}
	
	this.Enable = function(enabled)
	{
		this.IsEnabled = enabled;
		
		this.Paint();
	}
	
	this.OnMouseOver = function()
	{
		this.IsHilighted = true;
		this.Paint();
	}
	
	this.OnMouseOut = function()
	{
		this.IsHilighted = false;
		this.Paint();
	}
	
	this.OnClick = function()
	{		
		if (this.IsEnabled)
		{
			this.ClickHandler();
		}
			
		this.Paint();
	}
	
	this.Paint = function()
	{
	
		var imgToSet;
		
		if (!this.IsEnabled)
		{
			imgToSet = m_currentImageDetails.Disabled;
		}
		else
		{
			if (this.IsHilighted)
			{
				imgToSet = m_currentImageDetails.Over;
			}
			else
			{
				imgToSet = m_currentImageDetails.Normal;
			}
		}
			
		m_imageElement.src = imgToSet;
	}
	
	this.ClickHandler = function()
	{
		Sys.Debug.trace("Unimplimented Button ClickHandler id: " + this.id);
	}
}

PlayPauseButtonArea = function(container, containingWindow, id)
{
	this.OnLoad = function()
	{
		this.button.Initialize();
	}
	
	this.OnDataLoad = function()
	{
		this.AddEventHandlers();
		this.button.ClickHandler = new Function("", this.Container + ".OnClick();");
	}
	
	this.AddEventHandlers = function()
	{
		mPlayer.EventManager.Events.addHandler(SfKernel.EventType.MediaOpened, this.MediaOpenedEventHandler.bind(this));		
		mPlayer.EventManager.Events.addHandler(SfKernel.EventType.PlayStateChanged, this.PlayStateChangedEventHandler.bind(this));
	}
	
	this.MediaOpenedEventHandler = function(sender, args)
	{
    	this.button.Enable(true);
	}
	
	this.PlayStateChangedEventHandler = function(sender, state)
	{	    
	    if(Manifest.PlayStatus == SfKernel.PresentationPlayStatus.LiveEnded)
	    {
	        this.button.Enable(false);
	    }
		else
		{
		    this.OnPlayerStateChanged(state);
		}
	}

	this.OnPlayerStateChanged = function(state)
	{
		var playIsEnabled = true;		
		switch(state)
		{
			case SfKernel.MediaState.Stopped:
			case SfKernel.MediaState.Ready:
			case SfKernel.MediaState.Paused:
				playIsEnabled = true;				
				break;
			case SfKernel.MediaState.Playing:
			case SfKernel.MediaState.ScanForward:
			case SfKernel.MediaState.ScanReverse:
				playIsEnabled = false;
				break;
			default:
				return;
		}
		
		if (playIsEnabled)
		{
			this.button.SetPlayImage();
		}
		else
		{
		    if(Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand)
		    {
		        this.button.SetPauseImage();    
		    }
		    else
		    {
		        this.button.SetStopImage();
		    }			
		}
	}

	this.OnClick = function()
	{
	    if(!this.button.IsEnabled)
	    {
	        return;
	    }
	    
		if (this.button.AllowPlay == true)
		{
			mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.Play, this, null);
		}
		else
		{
			if(Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand)
		    {
		        mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.Pause, this, null);
		    }
		    else
		    {
		        mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.Stop, this, null);
		    }	
			
		}			
	}
	
}

/// MediaPlayer Skip Back Button
SkipbackButtonArea = function(container, containingWindow, id)
{	
	this.OnLoad = function()
	{
		this.button.Initialize();
		this.button.SetTooltip(Localization.Buttons.Skipback);
	}
	
	this.OnDataLoad = function()
	{
        if(Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand)
	    {
	    	this.button.SetClickHandler(this.OnClick.bind(this));
		    this.AddEventHandlers();
		}
	}
	
	this.AddEventHandlers = function()
	{
		mPlayer.EventManager.Events.addHandler(SfKernel.EventType.PlayStateChanged, this.PlayStateChangedEventHandler.bind(this));
	}
		
	this.PlayStateChangedEventHandler = function(sender, state)
	{
		switch(state)
		{
			case SfKernel.MediaState.Playing:
			case SfKernel.MediaState.Paused:	
    			this.button.Enable(true);
				break;
			default:
			    this.button.Enable(false);			
				break;
		}	
	}

	this.OnClick = function()
	{
		mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.SkipBack, this, null);
	}
}

///MediaPlayer Speed Control
PlayerSpeedControlPanel = function(container, containingWindow, id) {
    this.ID = id;
    this._availableSpeeds$1 = [ 0.5, 0.66, 0.75, 0.8, 1, 1.2, 1.4, 1.6, 1.8, 2];
    this._availableSpeedsDisplay$1 = [ '1/2x', '2/3x', '3/4x', '4/5x', '1x', '1.2x', '1.4x', '1.6x', '1.8x', '2x']; 
    
}

PlayerSpeedControlPanel.prototype = {
    _leftDiv$1: null,
    _middleDiv$1: null,
    _rightDiv$1: null,
    _leftDivMouseOverHandler$1: null,
    _leftDivMouseOutHandler$1: null,
    _leftDivClickHandler$1: null,
    _rightDivMouseOverHandler$1: null,
    _rightDivMouseOutHandler$1: null,
    _rightDivClickHandler$1: null,
    _indexOfNormal$1: 3,
    _currentSpeedIndex$1: 3,
    _isLeftDivEnabled$1: true,
    _isRightDivEnabled$1: true,
    
    OnLoad: function() 
    {
        if (Manifest.PlayStatus != SfKernel.PresentationPlayStatus.OnDemand) {
            this.Hide();
            return;
        }
        this._initialize$1();
    },
        
    _initialize$1: function() {
        this._leftDiv$1 = $(this.ID + 'Left');
        this._middleDiv$1 = $(this.ID + 'Middle');
        this._rightDiv$1 = $(this.ID + 'Right');
        SfKernel.Util.SetToolTip(this._leftDiv$1, Localization.Buttons.PlaySlower);
        SfKernel.Util.SetToolTip(this._rightDiv$1, Localization.Buttons.PlayFaster);
        this._leftDivMouseOverHandler$1 = Function.createDelegate(this, this._leftDivOnMouseOver$1);
        this._leftDivMouseOutHandler$1 = Function.createDelegate(this, this._leftDivOnMouseOut$1);
        this._leftDivClickHandler$1 = Function.createDelegate(this, this._leftDivOnClick$1);
        this._rightDivMouseOverHandler$1 = Function.createDelegate(this, this._rightDivOnMouseOver$1);
        this._rightDivMouseOutHandler$1 = Function.createDelegate(this, this._rightDivOnMouseOut$1);
        this._rightDivClickHandler$1 = Function.createDelegate(this, this._rightDivOnClick$1);
        this._leftDiv$1.observe('mouseover', this._leftDivMouseOverHandler$1);
        this._leftDiv$1.observe('mouseout', this._leftDivMouseOutHandler$1);
        this._leftDiv$1.observe('click', this._leftDivClickHandler$1);
        this._rightDiv$1.observe('mouseover', this._rightDivMouseOverHandler$1);
        this._rightDiv$1.observe('mouseout', this._rightDivMouseOutHandler$1);
        this._rightDiv$1.observe('click', this._rightDivClickHandler$1);
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.Play, Function.createDelegate(this, this._onPlay$1));
    },
    
    _onPlay$1: function PlayerSpeedControl$_onPlay$1(sender, args) {
        if (this._currentSpeedIndex$1 !== this._indexOfNormal$1) {
            this._changePlayerSpeed$1();
        }
    },
    
    _changePlayerSpeed$1: function PlayerSpeedControl$_changePlayerSpeed$1() {
        var param = {};
        param['PlaybackSpeed'] = this._availableSpeeds$1[this._currentSpeedIndex$1];
        mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.ChangePlaybackSpeed, this, param);
    },
    
    _leftDivOnMouseOver$1: function PlayerSpeedControl$_leftDivOnMouseOver$1(sender, args) {
        this._leftDiv$1.className = this.ID + 'LeftOver';
    },
    
    _leftDivOnMouseOut$1: function PlayerSpeedControl$_leftDivOnMouseOut$1(sender, args) {
        this._leftDiv$1.className = this.ID + 'LeftNormal';
    },
    
    _leftDivOnClick$1: function PlayerSpeedControl$_leftDivOnClick$1(sender, args) {
    
        if(!this._isLeftDivEnabled$1)
        {
            return;
        }
        --this._currentSpeedIndex$1;
        if (!this._currentSpeedIndex$1) {
            this._disableLeftDiv$1();
        }
        if (!this._isRightDivEnabled$1) {
            this._enableRightDiv$1();
        }
        this._changePlayerSpeed$1();
        this._displayCurrentSpeed$1();
    },
    
    _displayCurrentSpeed$1: function PlayerSpeedControl$_displayCurrentSpeed$1() {
        SfKernel.Util.SetText(this._middleDiv$1, this._availableSpeedsDisplay$1[this._currentSpeedIndex$1]);
    },
    
    _disableLeftDiv$1: function PlayerSpeedControl$_disableLeftDiv$1() {
        this._leftDiv$1.className = this.ID + 'LeftDisabled';
        this._leftDiv$1.stopObserving('mouseover', this._leftDivMouseOverHandler$1);
        this._leftDiv$1.stopObserving('mouseout', this._leftDivMouseOutHandler$1);
        this._leftDiv$1.stopObserving('click', this._leftDivClickHandler$1);
        this._isLeftDivEnabled$1 = false;
    },
    
    _enableLeftDiv$1: function PlayerSpeedControl$_enableLeftDiv$1() {
        this._leftDiv$1.className = this.ID + 'LeftNormal';
        this._leftDiv$1.observe('mouseover', this._leftDivMouseOverHandler$1);
        this._leftDiv$1.observe('mouseout', this._leftDivMouseOutHandler$1);
        this._leftDiv$1.observe('click', this._leftDivClickHandler$1);
        this._isLeftDivEnabled$1 = true;
    },
    
    _disableRightDiv$1: function PlayerSpeedControl$_disableRightDiv$1() {
        this._rightDiv$1.className = this.ID + 'RightDisabled';
        this._rightDiv$1.stopObserving('mouseover', this._rightDivMouseOverHandler$1);
        this._rightDiv$1.stopObserving('mouseout', this._rightDivMouseOutHandler$1);
        this._rightDiv$1.stopObserving('click', this._rightDivClickHandler$1);
        this._isRightDivEnabled$1 = false;
    },
    
    _enableRightDiv$1: function PlayerSpeedControl$_enableRightDiv$1() {
        this._rightDiv$1.className = this.ID + 'RightNormal';
        this._rightDiv$1.observe('mouseover', this._rightDivMouseOverHandler$1);
        this._rightDiv$1.observe('mouseout', this._rightDivMouseOutHandler$1);
        this._rightDiv$1.observe('click', this._rightDivClickHandler$1);
        this._isRightDivEnabled$1 = true;
    },
    
    _rightDivOnMouseOver$1: function PlayerSpeedControl$_rightDivOnMouseOver$1(sender, args) {
        this._rightDiv$1.className = this.ID + 'RightOver';
    },
    
    _rightDivOnMouseOut$1: function PlayerSpeedControl$_rightDivOnMouseOut$1(sender, args) {
        this._rightDiv$1.className = this.ID + 'RightNormal';
    },
    
    _rightDivOnClick$1: function PlayerSpeedControl$_rightDivOnClick$1(sender, args) {
    
        if(!this._isRightDivEnabled$1)
        {
            return;
        }
        ++this._currentSpeedIndex$1;
        if (this._currentSpeedIndex$1 === this._availableSpeeds$1.length - 1) {
            this._disableRightDiv$1();
        }
        if (!this._isLeftDivEnabled$1) {
            this._enableLeftDiv$1();
        }
        this._changePlayerSpeed$1();
        this._displayCurrentSpeed$1();
    },
    
   	Show: function() 
	{
        $(this.ID).style.display = 'block';
    },
    
    Hide: function() 
    {
        $(this.ID).style.display = 'none';
    }
}

/// MediaPlayer Mute Button

MuteButtonArea = function(container, containingWindow, id)
{
	this.OnLoad = function()
	{
		this.button.SetTooltip(Localization.Buttons.Mute);
		this.button.Initialize();
	}
	
	this.OnDataLoad = function()
	{	
		this.button.SetClickHandler(this.OnClick.bind(this));
		this.AddEventHandlers();
	}
	
	this.AddEventHandlers = function()
	{		
		mPlayer.EventManager.Events.addHandler(SfKernel.EventType.MediaOpened, this.PlayerSetupCompleteEventHandler.bind(this));		
		mPlayer.EventManager.Events.addHandler(SfKernel.EventType.MuteToggled, this.MuteToggledEventHandler.bind(this));
	}
	
	this.PlayerSetupCompleteEventHandler = function(sender, args)
	{
		this.button.Enable(true);
	}
	
	this.MuteToggledEventHandler = function(sender, mute)
	{
		if (mute == true)
		{
			this.button.SetChecked(true);
			this.button.SetTooltip(Localization.Buttons.UnMute);
		}
		else
		{
			this.button.SetChecked(false);
			this.button.SetTooltip(Localization.Buttons.Mute);
		}
	}

	this.OnClick = function()
	{
		mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.Mute, this, null);
	}
}

/// MediaPlayer Volume Slider
VolumeSliderArea = function(container, containingWindow, id)
{
    this.ID = id;
	this.Slider = null;	
	this.VolumeInitializedEventHandler = null;	
	this.IsCurrentlyDragging = false;	
	this.Orientation = SfUI.SfSlider.Orientation.Vertical;
	
	this.OnLoad = function()
	{
		this.Initialize();
	}
	
	this.Initialize = function()
	{
		var imageInfo = {SliderBackroundImage:this.SliderBackgroundImage, ThumbImage:this.ThumbImage, ThumbOverImage:this.ThumbOverImage};
		this.Slider = new SfUI.SfSlider({NamePrefix:this.ID, Orientation:this.Orientation, ImageInfo:imageInfo});
	    this.AddEventHandlers();
	}
	
	this.AddEventHandlers = function()
	{
		this.Slider.AddClickHandler(Function.createDelegate(this, this.OnSliderClick));
		this.Slider.AddDragHandler(Function.createDelegate(this, this.OnSliderDrag));		
		mPlayer.EventManager.Events.addHandler(SfKernel.EventType.VolumeInitialized, this.VolumeInitializedEventHandler.bind(this));
	}
	
	this.VolumeInitializedEventHandler = function(sender, args)
	{
		this.Slider.SetPosition(args.Volume);
	}

	this.OnSliderClick = function(sender, args)
	{
		this.Slider.SetPosition(args.Position);
		this.PostSetVolumeCommand(args.Position);
	}
	
	this.OnSliderDrag = function(sender, dragArgs)
	{
		if (dragArgs.DragEventType == SfUI.SfSlider.DragEventType.DragMove)
		{
			this.Slider.SetPosition(dragArgs.Position);
			this.PostSetVolumeCommand(dragArgs.Position);
		}
		else if (dragArgs.DragEventType == SfUI.SfSlider.DragEventType.BeginDrag)
		{
			this.IsCurrentlyDragging = true;
		}
		else if (dragArgs.DragEventType == SfUI.SfSlider.DragEventType.EndDrag)
		{
			this.IsCurrentlyDragging = false;
		}
	}
	
	this.PostSetVolumeCommand = function(vol)
	{
		mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.SetVolume, this, {Volume:vol});
	}
}

CCButtonArea = function(container, containingWindow, id)
{
	this.OnLoad = function()
	{
		this.button.Initialize();
	}
	
	this.OnDataLoad = function()
	{	
		this.button.SetClickHandler(this.OnClick.bind(this));
		this.AddEventHandlers();
	}
	
	this.AddEventHandlers = function()
	{		
		mPlayer.EventManager.Events.addHandler(SfKernel.EventType.MediaOpened, this.PlayerSetupCompleteEventHandler.bind(this));	
	}
	
	this.PlayerSetupCompleteEventHandler = function(sender, args)
	{
		this.button.Enable(true);
	}

	this.OnClick = function()
	{
	}
}

/// MediaPlayer Full Screen Button
FullScreenButtonArea = function(container, containingWindow, id)
{
	this.OnLoad = function()
	{
		this.button.Initialize();
		this.button.SetTooltip(Localization.Buttons.FullScreen);
	}
	
	this.OnDataLoad = function()
	{
		this.button.SetClickHandler(this.OnClick.bind(this));
		this.AddEventHandlers();
	}
	
	this.EnableDisableButton = function()
	{
		if (Manifest.HasVideo == false)
		{
			this.button.Enable(false);
		}
		else
		{
			this.button.Enable(true);
		}
	}
	
	
	this.AddEventHandlers = function()
	{
		mPlayer.EventManager.Events.addHandler(SfKernel.EventType.MediaOpened, this.PlayerSetupCompleteEventHandler.bind(this));
		mPlayer.EventManager.Events.addHandler(SfKernel.EventType.PlayStateChanged, this.PlayStateChangedEventHandler.bind(this));
	}
	
	this.PlayerSetupCompleteEventHandler = function(sender, args)
	{
		this.EnableDisableButton();
	}
	
	this.PlayStateChangedEventHandler = function(sender,state)
	{
		switch(state)
		{
			case SfKernel.MediaState.Playing:
			case SfKernel.MediaState.Paused:	
    			this.button.Enable(true);
				break;
			default:
			    this.button.Enable(false);			
				break;
		}	
	}
	
	this.OnClick = function()
	{
		mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.FullScreen, this, null);
	}
	
}

// 2.0.30603.0
if(!window.Silverlight)window.Silverlight={};Silverlight._silverlightCount=0;Silverlight.__onSilverlightInstalledCalled=false;Silverlight.fwlinkRoot="http://go2.microsoft.com/fwlink/?LinkID=";Silverlight.__installationEventFired=false;Silverlight.onGetSilverlight=null;Silverlight.onSilverlightInstalled=function(){window.location.reload(false)};Silverlight.isInstalled=function(b){if(b==undefined)b=null;var a=false,m=null;try{var i=null,j=false;if(window.ActiveXObject)try{i=new ActiveXObject("AgControl.AgControl");if(b===null)a=true;else if(i.IsVersionSupported(b))a=true;i=null}catch(l){j=true}else j=true;if(j){var k=navigator.plugins["Silverlight Plug-In"];if(k)if(b===null)a=true;else{var h=k.description;if(h==="1.0.30226.2")h="2.0.30226.2";var c=h.split(".");while(c.length>3)c.pop();while(c.length<4)c.push(0);var e=b.split(".");while(e.length>4)e.pop();var d,g,f=0;do{d=parseInt(e[f]);g=parseInt(c[f]);f++}while(f<e.length&&d===g);if(d<=g&&!isNaN(d))a=true}}}catch(l){a=false}return a};Silverlight.WaitForInstallCompletion=function(){if(!Silverlight.isBrowserRestartRequired&&Silverlight.onSilverlightInstalled){try{navigator.plugins.refresh()}catch(a){}if(Silverlight.isInstalled(null)&&!Silverlight.__onSilverlightInstalledCalled){Silverlight.onSilverlightInstalled();Silverlight.__onSilverlightInstalledCalled=true}else setTimeout(Silverlight.WaitForInstallCompletion,3e3)}};Silverlight.__startup=function(){navigator.plugins.refresh();Silverlight.isBrowserRestartRequired=Silverlight.isInstalled(null);if(!Silverlight.isBrowserRestartRequired){Silverlight.WaitForInstallCompletion();if(!Silverlight.__installationEventFired){Silverlight.onInstallRequired();Silverlight.__installationEventFired=true}}else if(window.navigator.mimeTypes){var b=navigator.mimeTypes["application/x-silverlight-2"],c=navigator.mimeTypes["application/x-silverlight-2-b2"],d=navigator.mimeTypes["application/x-silverlight-2-b1"],a=d;if(c)a=c;if(!b&&(d||c)){if(!Silverlight.__installationEventFired){Silverlight.onUpgradeRequired();Silverlight.__installationEventFired=true}}else if(b&&a)if(b.enabledPlugin&&a.enabledPlugin)if(b.enabledPlugin.description!=a.enabledPlugin.description)if(!Silverlight.__installationEventFired){Silverlight.onRestartRequired();Silverlight.__installationEventFired=true}}if(!Silverlight.disableAutoStartup)if(window.removeEventListener)window.removeEventListener("load",Silverlight.__startup,false);else window.detachEvent("onload",Silverlight.__startup)};if(!Silverlight.disableAutoStartup)if(window.addEventListener)window.addEventListener("load",Silverlight.__startup,false);else window.attachEvent("onload",Silverlight.__startup);Silverlight.createObject=function(m,f,e,k,l,h,j){var d={},a=k,c=l;d.version=a.version;a.source=m;d.alt=a.alt;if(h)a.initParams=h;if(a.isWindowless&&!a.windowless)a.windowless=a.isWindowless;if(a.framerate&&!a.maxFramerate)a.maxFramerate=a.framerate;if(e&&!a.id)a.id=e;delete a.ignoreBrowserVer;delete a.inplaceInstallPrompt;delete a.version;delete a.isWindowless;delete a.framerate;delete a.data;delete a.src;delete a.alt;if(Silverlight.isInstalled(d.version)){for(var b in c)if(c[b]){if(b=="onLoad"&&typeof c[b]=="function"&&c[b].length!=1){var i=c[b];c[b]=function(a){return i(document.getElementById(e),j,a)}}var g=Silverlight.__getHandlerName(c[b]);if(g!=null){a[b]=g;c[b]=null}else throw"typeof events."+b+" must be 'function' or 'string'";}slPluginHTML=Silverlight.buildHTML(a)}else slPluginHTML=Silverlight.buildPromptHTML(d);if(f)f.innerHTML=slPluginHTML;else return slPluginHTML};Silverlight.buildHTML=function(a){var b=[];b.push('<object type="application/x-silverlight" data="data:application/x-silverlight,"');if(a.id!=null)b.push(' id="'+Silverlight.HtmlAttributeEncode(a.id)+'"');if(a.width!=null)b.push(' width="'+a.width+'"');if(a.height!=null)b.push(' height="'+a.height+'"');b.push(" >");delete a.id;delete a.width;delete a.height;for(var c in a)if(a[c])b.push('<param name="'+Silverlight.HtmlAttributeEncode(c)+'" value="'+Silverlight.HtmlAttributeEncode(a[c])+'" />');b.push("</object>");return b.join("")};Silverlight.createObjectEx=function(b){var a=b,c=Silverlight.createObject(a.source,a.parentElement,a.id,a.properties,a.events,a.initParams,a.context);if(a.parentElement==null)return c};Silverlight.buildPromptHTML=function(b){var a="",d=Silverlight.fwlinkRoot,c=b.version;if(b.alt)a=b.alt;else{if(!c)c="";a="<a href='javascript:Silverlight.getSilverlight(\"{1}\");' style='text-decoration: none;'><img src='{2}' alt='Get Microsoft Silverlight' style='border-style: none'/></a>";a=a.replace("{1}",c);a=a.replace("{2}",d+"108181")}return a};Silverlight.getSilverlight=function(e){if(Silverlight.onGetSilverlight)Silverlight.onGetSilverlight();var b="",a=String(e).split(".");if(a.length>1){var c=parseInt(a[0]);if(isNaN(c)||c<2)b="1.0";else b=a[0]+"."+a[1]}var d="";if(b.match(/^\d+\056\d+$/))d="&v="+b;Silverlight.followFWLink("149156"+d)};Silverlight.followFWLink=function(a){top.location=Silverlight.fwlinkRoot+String(a)};Silverlight.HtmlAttributeEncode=function(c){var a,b="";if(c==null)return null;for(var d=0;d<c.length;d++){a=c.charCodeAt(d);if(a>96&&a<123||a>64&&a<91||a>43&&a<58&&a!=47||a==95)b=b+String.fromCharCode(a);else b=b+"&#"+a+";"}return b};Silverlight.default_error_handler=function(e,b){var d,c=b.ErrorType;d=b.ErrorCode;var a="\nSilverlight error message     \n";a+="ErrorCode: "+d+"\n";a+="ErrorType: "+c+"       \n";a+="Message: "+b.ErrorMessage+"     \n";if(c=="ParserError"){a+="XamlFile: "+b.xamlFile+"     \n";a+="Line: "+b.lineNumber+"     \n";a+="Position: "+b.charPosition+"     \n"}else if(c=="RuntimeError"){if(b.lineNumber!=0){a+="Line: "+b.lineNumber+"     \n";a+="Position: "+b.charPosition+"     \n"}a+="MethodName: "+b.methodName+"     \n"}alert(a)};Silverlight.__cleanup=function(){for(var a=Silverlight._silverlightCount-1;a>=0;a--)window["__slEvent"+a]=null;Silverlight._silverlightCount=0;if(window.removeEventListener)window.removeEventListener("unload",Silverlight.__cleanup,false);else window.detachEvent("onunload",Silverlight.__cleanup)};Silverlight.__getHandlerName=function(b){var a="";if(typeof b=="string")a=b;else if(typeof b=="function"){if(Silverlight._silverlightCount==0)if(window.addEventListener)window.addEventListener("unload",Silverlight.__cleanup,false);else window.attachEvent("onunload",Silverlight.__cleanup);var c=Silverlight._silverlightCount++;a="__slEvent"+c;window[a]=b}else a=null;return a};Silverlight.onRequiredVersionAvailable=function(){};Silverlight.onRestartRequired=function(){};Silverlight.onUpgradeRequired=function(){};Silverlight.onInstallRequired=function(){};Silverlight.IsVersionAvailableOnError=function(d,a){var b=false;try{if(a.ErrorCode==8001&&!Silverlight.__installationEventFired){Silverlight.onUpgradeRequired();Silverlight.__installationEventFired=true}else if(a.ErrorCode==8002&&!Silverlight.__installationEventFired){Silverlight.onRestartRequired();Silverlight.__installationEventFired=true}else if(a.ErrorCode==5014||a.ErrorCode==2106){if(Silverlight.__verifySilverlight2UpgradeSuccess(a.getHost()))b=true}else b=true}catch(c){}return b};Silverlight.IsVersionAvailableOnLoad=function(b){var a=false;try{if(Silverlight.__verifySilverlight2UpgradeSuccess(b.getHost()))a=true}catch(c){}return a};Silverlight.__verifySilverlight2UpgradeSuccess=function(d){var c=false,b="3.0.40624",a=null;try{if(d.IsVersionSupported(b+".99")){a=Silverlight.onRequiredVersionAvailable;c=true}else if(d.IsVersionSupported(b+".0"))a=Silverlight.onRestartRequired;else a=Silverlight.onUpgradeRequired;if(a&&!Silverlight.__installationEventFired){a();Silverlight.__installationEventFired=true}}catch(e){}return c}/// SL1 MediaPlayer Area
SL1PlayerArea = function(container, containingWindow, id) {
    SL1PlayerArea.initializeBase(this, [container, containingWindow, id]);

    this.media = null;

    this.SetupPlayer = function() {
        var playerVideoArea = $('PlayerVideo');
        playerVideoArea.setAttribute('align', 'center');

        this.CreateObject();
        this.AdjustSize();
    }

    this.CreateObject = function() {

        var versionRequired = '1.0';

        if (Silverlight.isInstalled("3.0.40624")) {
            versionRequired = "3.0.40723";  //force SL3 GDR 1 if RTM is found
        }

        Silverlight.createObjectEx({
            source: this.GetXamlLocation(),
            parentElement: $('PlayerVideo'),
            id: 'EmbeddedPlayer',
            properties:
 				{ width: LayoutOptions.VideoWidth,
 				    height: LayoutOptions.VideoHeight,
 				    background: 'black',
 				    isWindowless: 'false',
 				    framerate: '24',
 				    version: versionRequired
 				},
            events:
 				{ onError: this.OnMediaError.bind(this), onLoad: this.OnMediaLoad.bind(this) },
            context: null
        });
    }

    this.GetXamlLocation = function() {
        var mainStylesheetLink = document.getElementById("mainStylesheet").href;
        return mainStylesheetLink.replace(/main.css/i, "SL1.xaml");
    }

    this.OnMediaError = function(sender, args) {
        if (args['errorCode'] == 1001 && Manifest.VideoUrl.toLowerCase().substr(0, 4) == 'http') {
            return;
        }

        this.HandleMediaPlayerError(this.FormatErrorMessage(args));
    }

    this.OnMediaLoad = function() {
        this.embeddedPlayer = $('EmbeddedPlayer');
        mss.OnLoad(this.embeddedPlayer);

        this.media = mss.FindName('media');
        this.media.width = LayoutOptions.VideoWidth;
        this.media.height = LayoutOptions.VideoHeight;

        this.AttachMediaEvents();

        this.pci = new SfMediaPlayer.SL1.PlayerControl(this.media);

        this.AddEventHandlers();

        this.SetMediaSource();

        this.Volume = new SfMediaPlayer.Volume(this.pci);
        this.timerManager = new SfMediaPlayer.TimerManager(this);

        if (mPlayer.CurrentSlidePanelInstance && Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand) {
            mPlayer.EventManager.Events.addHandler(SfKernel.EventType.TimerLoop, this.TimerLoopEventHandler.bind(this));
        }
    }

    this.SetMediaSource = function() {
        if (Manifest.UnicastVideoUrl && Manifest.UnicastVideoUrl.length > 0) {
            this.pci.SetMedia(Manifest.UnicastVideoUrl);
        }
        else {
            this.pci.SetMedia(Manifest.VideoUrl);
        }
    }

    this.fullScreenChange = function(sender, args) {
        var embeddedSLMedia = mss.FindName('media');
        embeddedSLMedia.Width = mss.content.ActualWidth;
        embeddedSLMedia.Height = mss.content.ActualHeight;
        this.hideFullScreenPrompt();
    }

    this.hideFullScreenPrompt = function() {
        mss.SetVisible("fsText", false);
        mss.SetVisible("fsTextBackground", false);
    }

    this.MouseEnter = function(sender, args) {
        if (this.embeddedPlayer.content.fullScreen) {
            return;
        }

        var playState = this.pci.GetPlayState();

        if (playState != SfKernel.MediaState.Playing && playState != SfKernel.MediaState.Paused) {
            return;
        }

        mss.SetVisible("fsTextBackground", true);
        mss.SetVisible("fsText", true);

        var fsText = mss.FindName("fsText");
        var fsTextBackground = mss.FindName("fsTextBackground");
        fsText.Text = Localization.MediaPlayer.SilverlightFullScreenPrompt;
        fsText.width = LayoutOptions.VideoWidth;
        fsTextBackground.width = LayoutOptions.VideoWidth;
        mss.AlignText(mss.FindName("fsText"), TextAlign.CenterVertical | TextAlign.CenterHorizontal);

    }

    this.MouseLeave = function(sender, args) {
        this.hideFullScreenPrompt();
    }

    this.MouseLeftButtonUp = function(sender, args) {
        var playState = this.pci.GetPlayState();

        if (playState != SfKernel.MediaState.Playing && playState != SfKernel.MediaState.Paused) {
            return;
        }

        if (!this.embeddedPlayer.content.fullScreen) {
            this.embeddedPlayer.content.fullScreen = true;
            return;
        }

        if (Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand) {
            if (playState == SfKernel.MediaState.Paused) {
                this.Play();
            }
            else if (playState == SfKernel.MediaState.Playing) {
                this.Pause();
            }
        }
    }

    this.AttachMediaEvents = function() {
        this.embeddedPlayer.content.onFullScreenChange = SfEvent.createDelegate(this, this.fullScreenChange);

        var videoArea = mss.FindName("videoArea");
        {
            videoArea.addEventListener("MouseEnter", SfEvent.createDelegate(this, this.MouseEnter));
            videoArea.addEventListener("MouseLeave", SfEvent.createDelegate(this, this.MouseLeave));
            videoArea.addEventListener("MouseLeftButtonUp", SfEvent.createDelegate(this, this.MouseLeftButtonUp));
        }

        this.media.addEventListener('mediaOpened', this.OnMediaOpened.bind(this));
        this.media.addEventListener('mediaFailed', this.OnMediaFailed.bind(this));
        this.media.addEventListener('currentStateChanged', this.OnMediaCurrentStateChanged.bind(this));

        if (!GlobalOptions.UseLiveEventPolling) {
            this.media.addEventListener('markerReached', this.OnMediaMarkerReached.bind(this));
        }
    }

    this.OnMediaOpened = function() {
        mPlayer.VolumeSliderInstance.OnLoad();
        mPlayer.PlayerSliderInstance.OnLoad();
        mPlayer.ReportViewerPageOpened();

        if (this.media.NaturalVideoHeight == 0) {
            Manifest.HasVideo = false;
        }
        else {
            Manifest.HasVideo = true;
        }

        mPlayer.EventManager.PostEvent(SfKernel.EventType.MediaOpened, this, null);

        this.InitVolume();
        this.HandleAudioOnly();
        this.LoadAudioLanguages();

        switch (Manifest.PlayStatus) {
            case SfKernel.PresentationPlayStatus.Live:
            case SfKernel.PresentationPlayStatus.LivePaused:
                if (GlobalOptions.UseLiveEventPolling || mPlayer.PlayerDetect.IsMacPPC()) {
                    this.timerManager.pollLiveEvents = true;
                }
                break;
        }

        this.PostMediaLengthObtainedEvent();
        this.CheckStartStopTimes();

        this.timerManager.Start();
    }

    this.LoadAudioLanguages = function() {
        var languageCount = this.pci.GetAudioLanguageCount();
        if (languageCount > 1) {
            var AudioLanguages = new Array(languageCount);
            for (var i = 0; i < languageCount; ++i) {
                //Silverlight currently does not provide locale info
                AudioLanguages[i] = new SfKernel.AudioLanguageEntry(i, 0, Localization.Common.AudioTrack + ' ' + (i + 1));
            }

            mPlayer.LoadAudioLanguages(AudioLanguages, 1);
        }
    }

    this.OnMediaFailed = function(sender, args) {
        this.HandleMediaPlayerError(this.FormatErrorMessage(args));
    }

    this.OnMediaLoaded = function(sender, args) {
    }

    this.OnMediaCurrentStateChanged = function(sender, args) {
        var playState = this.pci.GetPlayState();

        if (this.currentMediaState != playState) {
            this.currentMediaState = playState;
            mPlayer.EventManager.PostEvent(SfKernel.EventType.PlayStateChanged, this, playState);
            this.CheckIfLiveEnded(playState);
        }
    }

    this.OnMediaMarkerReached = function(sender, args) {
        var scriptType = args['marker']['type'];
        var scriptParam = args['marker']['text'];
        this.ScriptParser.ParseScriptFromStream(scriptType, scriptParam);
    }

    this.TimerLoopEventHandler = function(sender, args) {
        this.HandleSlideChangeWhenPositionChanges(args["Position"]);
    }

    this.getFormattedTiming = function(posInMS) {
        var parsed = this.pci.ParseTime(posInMS);
        return parsed.HH + ":" + parsed.MM + ":" + parsed.SS + "." + parsed.FF;
    }

    this.FormatErrorMessage = function(args) {
        var errorDescription;

        switch (args['errorCode']) {
            case 4001:
                errorDescription = Localization.MediaPlayer.SilverlightNetworkError + "<br/> (" + args['errorMessage'] + ")";
                break;
            case 2203:
                errorDescription = Localization.MediaPlayer.SilverlightSetValueError + args['methodName'] + "<br/><br/>";
                break;
            default:
                errorDescription = Localization.MediaPlayer.GeneralError + "<br/> (" + args['errorCode'] + " - " + args['errorMessage'] + ")";
                break;
        }

        return errorDescription;
    }

    this.HideMediaPlayerDiv = function() {
        var playerElement = $('PlayerVideo');
        var notReady = $('PlayerNotStarted');

        var validSLVersion = Silverlight.isInstalled('1.0');
        if (validSLVersion) {
            if (Silverlight.isInstalled('3.0') && !Silverlight.isInstalled('3.0.40723')) {
                validSLVersion = false;
            }
        }

        if (validSLVersion) {
            if (playerElement) {
                playerElement.style.display = 'none';
            }
            if (notReady) {
                notReady.style.display = '';
            }
        }
        else {
            if (playerElement) {
                playerElement.setAttribute("align", "center");
                playerElement.style.display = '';
                var slPluginHelper = new Object();
                slPluginHelper.version = '1.0';
                playerElement.innerHTML = Silverlight.buildPromptHTML(slPluginHelper);
            }
            if (notReady) {
                notReady.style.display = 'none';
            }
        }

    }
}
SL1PlayerArea.registerClass('SL1PlayerArea', MediaPlayerArea);


/// SL1 MediaPlayer Control

Type.registerNamespace('SfMediaPlayer.SL1');
SfMediaPlayer.SL1.PlayerControl = function(embeddedMedia)
{
	this.media = embeddedMedia;
	
	this.Play = function()
	{
		this.media.play();
	}
	
	this.Stop = function()
	{
		this.media.stop();		
	}
	
	this.Pause = function()
	{
		this.media.pause();
	}

	this.GetPlayState = function()
	{
		var state = this.media.currentState;
		return this.convertSL1StateToPlayState(state);
	}
	
	this.SetMedia = function(loc)
	{
		this.media.source = loc;
	}
	
	this.GetPosition = function()
	{
		return this.media.position.seconds * 1000;
	}
	
	this.ParseTime = function(timeInMS)
	{
		var hh = Math.floor(timeInMS/3600000);
		
		var remainingMS = timeInMS - hh*3600000;
		var mm = Math.floor(remainingMS/60000);
		
		remainingMS = remainingMS - mm*60000;
		var ss = Math.floor(remainingMS/1000);
		
		remainingMS = remainingMS = ss*1000;
		var ff = Math.floor(remainingMS);

		return {HH:hh, MM:mm, SS:ss, FF:ff};		
	}
	
	this.SetPosition = function(posInMS)
	{	
		var parsed = this.ParseTime(posInMS);		
		var strPos = String.format('{0}:{1}:{2}.{3}', parsed.HH, parsed.MM, parsed.SS, parsed.FF);
		
		try
		{
	        if(this.GetPlayState() == SfKernel.MediaState.Playing)
		    {
		        //prevent SL video freeze bug
		        this.Pause();
		        this.media.position = strPos;		    
		        this.Play();
		    }
		    else
		    {
		        this.media.position = strPos;		    
		    }

		}
		catch(e)
		{		
		}		
	}
	
	this.GetMediaDuration = function()
	{
		return this.media.naturalDuration.seconds * 1000;
	}

	this.SetVolume = function(val)
	{   
		this.media.volume = val/100;
	}
	
	this.GetVolume = function()
	{
		return this.media.volume * 100;
	}
	
	this.SetMute = function(val)
	{
		this.media.isMuted = val;
	}
			
	this.convertSL1StateToPlayState = function(state)
	{
		switch (state.toLowerCase())
		{
			case 'buffering':
				return SfKernel.MediaState.Buffering;
			case 'closed':
				return SfKernel.MediaState.Closed;
			case 'error':
				return SfKernel.MediaState.Error;
			case 'opening':
				return SfKernel.MediaState.Opening;
			case 'paused':
				return SfKernel.MediaState.Paused;
			case 'playing':
				return SfKernel.MediaState.Playing;
			case 'stopped':
				return SfKernel.MediaState.Stopped;
			default:
				return SfKernel.MediaState.Undefined;
		}
	}

	this.SetPlaybackSpeed = function(speed)
	{
		throw Error.notImplemented();
	}
	
    this.SetFullScreen = function(fs)
	{
		throw Error.notImplemented();
	}

    this.GetAudioLanguageCount = function()
    {
        return this.media.AudioStreamCount;
    }
    
	this.SetAudioLanguageIndex = function(index)
	{
		this.media.AudioStreamIndex  = index;
    }

}


////////////////////////////////////////////

function SfEvent(name)
{
    this.Name=name;
    this.delegateList=new Array(0);
}

SfEvent.createDelegate = function(instance, method) 
{
	return function() {
        return method.apply(instance, arguments);
    }
}

SfEvent.prototype=
{

    Invoke:function(objParameters)
	{
	    for (var i=0;i<this.delegateList.length;i++)
	    {
	        if (this.delegateList[i])
	        {
	            this.delegateList[i](objParameters);
	        }
	    }

    },
    
    addListener:function(delegate)
    {
    
        for(var i=0;i<this.delegateList.length;i++)
        {
            if (this.delegateList[i]==null)
            {
                this.delegateList[i]=delegate;
                return i;
            }
        }
        
        var newList = new Array(this.delegateList.length+1);
        
        for(var i=0;i<this.delegateList.length;i++)
        {
            newList[i]=this.delegateList[i];
        }
        
        newList[this.delegateList.length]=delegate;
        
        this.delegateList=newList;
        
        return (this.delegateList.length-1);
    },
    
    removeListener:function(token)
    {
        if (this.delegateList.length>token)
        {
            this.delegateList[token]=null;
        }
    }
}

function EventList() 
{
    this.namedEvents=new Array(arguments.length);
    
    for(var i=0;i<arguments.length;i++)
    {
        this.namedEvents[i]=new Event(arguments[i]);
    }
}

EventList.prototype=
{

    Invoke:function(name,objParameters)
	{
	    var event = this.findEvent(name);
	    
	    if (event)
	    {
	        event.Invoke(objParameters);
	    }

    },
    
    addListener:function(name,delegate)
    {
        var event = this.findEvent(name);
	    
	    if (event)
	    {
	        return event.addListener(delegate);
	    }
	    
	    return null;
    },
    removeListener:function(name,token)
    {
        var event = this.findEvent(name);
	    
	    if (event)
	    {
	        event.removeListener(token);
	    }
    },
    findEvent:function(name)
    {
        for(var i=0;i<this.namedEvents.length;i++)
        {
            if (this.namedEvents[i].Name==name)
            {
                return this.namedEvents[i];
            }
        }
        
        return null;
    }
}

function mss(){}

mss.control=null;
mss.content=null;

mss.OnLoad=function(silverlightControl)
{
    mss.control=silverlightControl;
    mss.content=mss.control.content;
}
    
mss.Animate=function(animationName) 
{
    var animation = mss.FindName(animationName);
	
    if (animation!=null)
    {
        animation.begin();
        return true;
    }
    return false;
}

mss.FindName=function(name) 
{
    return mss.content.findName(name);
}

mss.SetVisible = function(canvasName,show) 
{
    var panel = mss.FindName(canvasName);
    
    if (panel!=null)
    {
        if (show)
        {
           panel.SetValue("Visibility","Visible");
        }
        else
        {
           panel.SetValue("Visibility","Collapsed");
        }
    }
}
function TextAlign(){}
TextAlign.CenterVertical=1;
TextAlign.CenterHorizontal=2;

mss.AlignText=function(textBlock,textAlign)
{

        if ((textAlign & TextAlign.CenterHorizontal)==TextAlign.CenterHorizontal)
        {
            textBlock.SetValue("Canvas.Left", 0);
            var newLeft = ((textBlock.Width - textBlock.ActualWidth) / 2)+ textBlock.GetValue("Canvas.Left"); 
            
            textBlock.SetValue("Canvas.Left", newLeft); 
        }
 

        if ((textAlign & TextAlign.CenterVertical)==TextAlign.CenterVertical)
        {
            textBlock.SetValue("Canvas.Top", 0);
            var newTop = ((textBlock.Height - textBlock.ActualHeight) / 2) + textBlock.GetValue("Canvas.Top");
                 
            textBlock.SetValue("Canvas.Top", newTop);
        }
}

function Rectangle(left,top,width,height)
{
    this.Left=left;
    this.Top=top;
    this.Width=width;
    this.Height=height;
}

Rectangle.prototype =
{
    SetCanvasRect:function(canvas)
	{
	    canvas.SetValue("Canvas.Left",this.Left);
        canvas.SetValue("Canvas.Top",this.Top);
	    canvas.width=this.Width;
        canvas.height=this.Height;

    },
    
    SetCanvasSize:function(canvas)
	{
	    canvas.width=this.Width;
        canvas.height=this.Height;
    },
    
    GetCanvasRect:function(canvas)
	{
	    this.Width=canvas.width;
        this.Height=canvas.height;
        this.Left=canvas.GetValue("Canvas.Left");
        this.Top=canvas.GetValue("Canvas.Top");
    },
    
    SetClipRect:function(rectangleGeometry)
	{
        var rectDimensions=this.Left+","+this.Top+","+this.Width+","+this.Height;
        rectangleGeometry["Rect"]=rectDimensions;
    },
    
    Clone:function()
    {
        return new Rectangle(this.Left,this.Top,this.Width,this.Height);
    },
    
    ToString:function()
    {
        return this.Left+","+this.Top+","+this.Width+","+this.Height;
    }
}


// WM7 MediaPlayer Area

WM7PlayerArea = function(container, containingWindow, id) {
    WM7PlayerArea.initializeBase(this, [container, containingWindow, id]);

    this.SetupPlayer = function() {
        var initDelay = 100;

        if (mPlayer.PlayerDetect.GetPlayerType() == SfKernel.MediaPlayerType.WM7) {
            var wm7Player = document.createElement("OBJECT");
            wm7Player.setAttribute("id", "EmbeddedPlayer");
            wm7Player.setAttribute("classid", "clsid:6BF52A52-394A-11d3-B153-00C04F79FAA6");
            var wm7PlayerUI = document.createElement("PARAM");
            wm7PlayerUI.setAttribute("name", "uiMode");
            wm7PlayerUI.setAttribute("value", "none");
            wm7Player.appendChild(wm7PlayerUI);
            $('PlayerVideo').appendChild(wm7Player);
            $('EmbeddedPlayer').uiMode = "none";
        }
        else if (mPlayer.PlayerDetect.GetPlayerType() == SfKernel.MediaPlayerType.Port25) {
            var port25Player = document.createElement("OBJECT");
            port25Player.setAttribute("id", "EmbeddedPlayer");
            port25Player.setAttribute("data", "");
            port25Player.setAttribute("type", "application/x-ms-wmp");
            var styleFormat = String.format("width:{0}px;height:{1}px", LayoutOptions.VideoWidth, LayoutOptions.VideoHeight);
            port25Player.setAttribute("style", styleFormat);
            var port25PlayerUI = document.createElement("PARAM");
            port25PlayerUI.setAttribute("name", "uiMode");
            port25PlayerUI.setAttribute("value", "none");
            port25Player.appendChild(port25PlayerUI);
            $('PlayerVideo').appendChild(port25Player);

            initDelay = 750;
        }

        this.embeddedPlayer = $('EmbeddedPlayer');
        this.pci = new SfMediaPlayer.WM7.PlayerControl(this.embeddedPlayer);
        this.AdjustSize();

        window.setTimeout(this.WaitForPlayerInit.bind(this), initDelay);
    }

    this.WaitForPlayerInit = function() {
        if (!this.embeddedPlayer.settings) {
            window.setTimeout(this.WaitForPlayerInit.bind(this), 200);
            return;
        }
        this.LoadPlayer();
    }

    this.LoadPlayer = function() {
        this.embeddedPlayer.enableContextMenu = GlobalOptions.EnableContextMenuForPlayer;
        this.embeddedPlayer.windowlessVideo = true;
        this.embeddedPlayer.settings.invokeURLs = false;
        this.embeddedPlayer.stretchToFit = true;


        this.AttachMediaEvents();
        this.AddEventHandlers();

        this.SetMediaSource();

        this.Volume = new SfMediaPlayer.Volume(this.pci);
        this.timerManager = new SfMediaPlayer.TimerManager(this);

        if (mPlayer.CurrentSlidePanelInstance && Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand) {
            mPlayer.EventManager.Events.addHandler(SfKernel.EventType.TimerLoop, this.TimerLoopEventHandler.bind(this));
        }
    }

    this.AttachMediaEvents = function() {
        if (document.attachEvent) {
            this.embeddedPlayer.attachEvent("OpenStateChange", this.OnMediaOpenStateChange.bind(this));
            this.embeddedPlayer.attachEvent("MediaError", this.OnMediaError.bind(this));
            this.embeddedPlayer.attachEvent("PlayStateChange", this.OnMediaPlayStateChange.bind(this));

            if (!GlobalOptions.UseLiveEventPolling) {
                this.embeddedPlayer.attachEvent("ScriptCommand", this.OnScriptCommand.bind(this));
            }
        }
    }

    this.TimerLoopEventHandler = function(sender, args) {
        this.HandleSlideChangeWhenPositionChanges(args["Position"]);
    }

    this.OnMediaOpenStateChange = function(openState) {
        if (openState != 13) {
            return;
        }

        mPlayer.VolumeSliderInstance.OnLoad();
        mPlayer.PlayerSliderInstance.OnLoad();
        mPlayer.ReportViewerPageOpened();

        if (this.embeddedPlayer.currentMedia.getItemInfo("MediaType") == 'audio') {
            Manifest.HasVideo = false;
        }
        else {
            Manifest.HasVideo = true;
        }

        mPlayer.EventManager.PostEvent(SfKernel.EventType.MediaOpened, this, null);

        this.InitVolume();
        this.HandleAudioOnly();
        this.LoadAudioLanguages();

        if ((Manifest.PlayStatus == SfKernel.PresentationPlayStatus.Live || Manifest.PlayStatus == SfKernel.PresentationPlayStatus.LivePaused) && GlobalOptions.UseLiveEventPolling) {
            this.timerManager.pollLiveEvents = true;
        }

        this.PostMediaLengthObtainedEvent();
        this.CheckStartStopTimes();

        this.timerManager.Start();
    }

    this.LoadAudioLanguages = function() {
        var languageCount = this.pci.GetAudioLanguageCount();
        if (languageCount > 1) {
            var currentIndex = this.pci.GetCurrentAudioLanguageIndex();
            var AudioLanguages = new Array(languageCount);

            for (var i = 0; i < languageCount; ++i) {
                var lcid = this.pci.GetAudioLanguageID(i + 1);
                AudioLanguages[i] = new SfKernel.AudioLanguageEntry(i + 1, lcid, this.pci.GetAudioLanguageName(lcid));
            }

            mPlayer.LoadAudioLanguages(AudioLanguages, currentIndex);
        }
    }

    this.OnMediaError = function() {
        this.HandleMediaPlayerError(this.FormatErrorMessage(this.embeddedPlayer.currentMedia.error));
    }

    this.OnMediaPlayStateChange = function(playState) {
        if (this.currentMediaState != playState) {
            this.currentMediaState = playState;
            mPlayer.EventManager.PostEvent(SfKernel.EventType.PlayStateChanged, this, playState);
            this.CheckIfLiveEnded(playState);
        }
    }

    this.OnScriptCommand = function(sType, sParam) {
        this.ScriptParser.ParseScriptFromStream(sType, sParam);
    }

    this.FormatErrorMessage = function(error) {
        if (!error.errorCode) {
            return Localization.MediaPlayer.GeneralError;
        }

        var errorDescription;

        switch (error.errorCode) {
            case -1072885294: //C00D11D2
            case -1072885353: //C00D1197			
                errorDescription = Localization.MediaPlayer.FileNotFoundError;
                break;
            case -1072885352: //C00D1198
                errorDescription = Localization.MediaPlayer.ServerConnectionError;
                break;
            case -1072885328: //C00D11B0 
                errorDescription = Localization.MediaPlayer.ServerNotAvailable;
                break;
            default:
                errorDescription = error.errorDescription + " (" + error.errorCode + ")";
                break;
        }

        return errorDescription;
    }

}
WM7PlayerArea.registerClass('WM7PlayerArea', MediaPlayerArea);

Type.registerNamespace('SfMediaPlayer.WM7');
SfMediaPlayer.WM7.PlayerControl = function(objEmbeddedPlayer)
{
	this.objEmbedded = objEmbeddedPlayer;
	
	this.GetVersionInfo = function()
	{
		return this.objEmbedded.versionInfo;
	}

	this.Play = function()
	{
		this.objEmbedded.controls.play();
	}
	
	this.Stop = function()
	{
		this.objEmbedded.controls.stop();
	}
	
	this.Pause = function()
	{
		this.objEmbedded.controls.pause();
	}

    this.GetCurrentAudioLanguageIndex = function()
    {
		try
		{
		    return this.objEmbedded.controls.currentAudioLanguageIndex;
		}
		catch(ex)
		{
		    return 0;
		}        
    
    }
    
    this.GetAudioLanguageCount = function()
    {
		try
		{
		    return this.objEmbedded.controls.audioLanguageCount;
		}
		catch(ex)
		{
		    return 1;
		}        
    
    }
    this.GetAudioLanguageID = function(index)
    {
		try
		{
		    return this.objEmbedded.controls.getAudioLanguageID(index);
		}
		catch(ex)
		{
		    return 0;
		}            
    }

    this.GetAudioLanguageName = function(lcid)
    {
		try
		{
		    return this.objEmbedded.controls.getLanguageName(lcid);
		}
		catch(ex)
		{
		}        
    }
        
	this.SetAudioLanguageIndex = function(index)
	{
		try
		{
			this.objEmbedded.controls.currentAudioLanguageIndex = index;
		}
		catch(ex)
		{
		}
	}
	
	this.GetPlayState = function()
	{
		return this.objEmbedded.playState;
	}
	
	this.SetFullScreen = function(f)
	{
		this.objEmbedded.fullScreen = f;
	}
	
	this.SetPosition = function(positionInMS)
	{	    
		this.objEmbedded.controls.currentPosition=positionInMS/1000;	
	}

	this.GetPosition = function()
	{
		return this.objEmbedded.controls.currentPosition * 1000;
	}
	
	this.GetMediaDuration = function()
	{
		if (this.objEmbedded.currentMedia)
		{
			return this.objEmbedded.currentMedia.duration * 1000;
		}
		
		return 0;
	}

	this.SetMedia = function(sMedia)
	{
		this.objEmbedded.URL=sMedia;
	}
	
	this.GetCurrentMarker = function()
	{
		return this.objEmbedded.controls.currentMarker;
	}
	
	this.GetMediaMarkerCount = function()
	{
		if (this.objEmbedded.currentMedia)
		{
			return this.objEmbedded.currentMedia.markerCount;
		}
		
		return 0;
	}
	
	this.GetMediaMarkerName = function(nIndex)
	{
		if (this.objEmbedded.currentMedia)
		{
			return this.objEmbedded.currentMedia.getMarkerName(nIndex);
		}
		
		return null;
	}
	
	this.GetMediaMarkerTime = function(nIndex)
	{
		if (this.objEmbedded.currentMedia)
		{
			return this.objEmbedded.currentMedia.getMarkerTime(nIndex);
		}
		
		return 0;
	}
	
	this.GetVolume = function()
	{
		return this.objEmbedded.settings.volume;
	}
	
	this.SetVolume = function(nVolume)
	{
		this.objEmbedded.settings.volume = Math.round(nVolume);
	}
	
	this.SetMute = function(fMute)
	{
		this.objEmbedded.settings.mute = fMute;
	}
	
	this.SetPlaybackSpeed = function(speed)
	{
		this.objEmbedded.settings.rate = speed;
	}
}

/// Port25 Media Event Handlers
function OnDSPlayStateChangeEvt(newState)
{
    mPlayer.PlayerAreaInstance.OnMediaPlayStateChange(newState);
}
function OnDSOpenStateChangeEvt(newState)
{
    mPlayer.PlayerAreaInstance.OnMediaOpenStateChange(newState);
}
function OnDSScriptCommandEvt(scriptType, scriptParam)
{
   mPlayer.PlayerAreaInstance.OnScriptCommand(scriptType, scriptParam);
}
function OnDSMediaErrorEvt()
{
   mPlayer.PlayerAreaInstance.OnMediaError();
}



CurrentSlidePanel = function(container, containingWindow, id) {
    this.ID = id;
    this._imageCache$1 = new SfImage.ImageCache(container + '._imageCache$1');
}
CurrentSlidePanel.prototype = {
    _slideImageDiv$1: null,
    _slideImageLinkDiv$1: null,
    
    get_slideImageDiv: function CurrentSlidePanel$get_slideImageDiv() {
        return this._slideImageDiv$1;
    },
    set_slideImageDiv: function CurrentSlidePanel$set_slideImageDiv(value) {
        this._slideImageDiv$1 = value;
        return value;
    },
    
    _slideDescriptionDiv$1: null,
    _showNoImage$1: false,
    _imageCache$1: null,
    _toolbuttonController$1: null,
    _viewportManager$1: null,
    
    OnLoad: function CurrentSlidePanel$OnLoad() {
        this._slideImageDiv$1 = $(this.ID + 'SlideImage');
        this._slideDescriptionDiv$1 = $(this.ID + 'SlideDescription');      
        this._slideImageLinkDiv$1 = $(this.ID + 'ImageLink');
        
        if(LayoutOptions.Images['SlideDefault'])
        {
            this._setSlideImage$1(LayoutOptions.Images['SlideDefault'].ImageFilename);
            this._setSlideLink$1(LayoutOptions.Images['SlideDefault'].ImageUrl);
            this._setSlideDescription$1(Localization.CurrentSlideResource.SlideImage);          
        }
    },
    
    OnDataLoad: function()
    {
        this._registerEvents$1();
        this._toolbuttonController$1 = new CurrentSlide.CurrentSlideToolbuttonController(this);
        this._viewportManager$1 = new CurrentSlide.ViewportManager(this);    
        this._loadDefaultImage$1();  
    },
    
    GetDiv : function()
	{
		if (this._div == null)
		{
			this._div = $(this.ID);
		}
		return this._div;
	},
    
    turnOnSlideDescription: function CurrentSlidePanel$turnOnSlideDescription() {
        this._slideImageDiv$1.style.visibility = 'hidden';
        this._slideDescriptionDiv$1.style.visibility = 'visible';
    },
    
    turnOffSlideDescription: function CurrentSlidePanel$turnOffSlideDescription() {
        this._slideImageDiv$1.style.visibility = 'visible';
        this._slideDescriptionDiv$1.style.visibility = 'hidden';
    },
    
    showMagnifier: function CurrentSlidePanel$showMagnifier() {
        this._viewportManager$1.set_isShowing(true);
    },
    
    hideMagnifier: function CurrentSlidePanel$hideMagnifier() {
        this._viewportManager$1.set_isShowing(false);
    },
    
    _loadDefaultImage$1: function CurrentSlidePanel$_loadDefaultImage$1() {
        var status = Manifest.PlayStatus;
        switch (status) {
            case SfKernel.PresentationPlayStatus.Live:
            case SfKernel.PresentationPlayStatus.LivePaused:
                this._setCurrentCaptureImage$1();
                break;
            case SfKernel.PresentationPlayStatus.OnDemand:
                if(LayoutOptions.Images['SlideDefault'])
                {
                    this._setSlideImage$1(LayoutOptions.Images['SlideDefault'].ImageFilename);
                    this._setSlideLink$1(LayoutOptions.Images['SlideDefault'].ImageUrl);
                    this._setSlideDescription$1(Localization.CurrentSlideResource.SlideImage);
                }
                break;
            case SfKernel.PresentationPlayStatus.LiveEnded:
                if(!LayoutOptions.DoNotShowEndSlide && LayoutOptions.Images['SlideEnded'])
                {
                    this._setSlideImage$1(LayoutOptions.Images['SlideEnded'].ImageFilename);
                    this._setSlideLink$1(LayoutOptions.Images['SlideEnded'].ImageUrl);
                }
                break;
            case SfKernel.PresentationPlayStatus.ScheduledForLive:
            case SfKernel.PresentationPlayStatus.OpenForLive:
                if(LayoutOptions.Images['SlideNotStarted'])
                {
                    this._setSlideImage$1(LayoutOptions.Images['SlideNotStarted'].ImageFilename);
                    this._setSlideLink$1(LayoutOptions.Images['SlideNotStarted'].ImageUrl);
                }
                break;
            default:
                throw Error.invalidOperation('Unknown presentation status');
        }
    },
    
    _registerEvents$1: function CurrentSlidePanel$_registerEvents$1() {
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.Script, Function.createDelegate(this, this._onScriptEvent$1));
        mPlayer.EventManager.CommandEvents.addHandler(SfKernel.CommandEventId.Play, Function.createDelegate(this, this._onPlay$1));
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.LivePlaybackStarted, Function.createDelegate(this, this._onDataAvailable$1));
    },
    
    _setCurrentCaptureImage$1: function CurrentSlidePanel$_setCurrentCaptureImage$1() {
        var max = Manifest.Slides.length;
        if (max < 1) {
            if(LayoutOptions.Images['SlideDefault'])
            {
                this._setSlideImage$1(LayoutOptions.Images['SlideDefault'].ImageFilename);
                this._setSlideLink$1(LayoutOptions.Images['SlideDefault'].ImageUrl);
            }
            return;
        }
        mPlayer.CurrentFullSizeImage = mPlayer.GetImageLocation(max, SfKernel.SlideType.FullSize);
        mPlayer.CurrentSlideNumber = max;
        this._setSlideImage$1(mPlayer.GetImageLocation(max, SfKernel.SlideType.Normal));       
        this._setSlideLink$1(null);
        this._toolbuttonController$1.ensureClickIsInitialized();
    },
    
    _setSlideImage$1: function CurrentSlidePanel$_setSlideImage$1(src) {
        this._slideImageDiv$1.setAttribute('src', src);
        this._slideImageDiv$1.show();
    },
    
   _setSlideLink$1: function CurrentSlidePanel$_setSlideLink$1(href) {
   
        if(!href || href.length < 1)
        {
            this._slideImageLinkDiv$1.removeAttribute('href');           
        }
        else
        {
            this._slideImageLinkDiv$1.setAttribute('href', href);    
        }    
    },

    _onScriptEvent$1: function CurrentSlidePanel$_onScriptEvent$1(sender, args) {
        var commandType = args['Command'];
        switch (commandType) {
            case SfKernel.ScriptCmdType.ShowSlide:
                this._showSlide$1(args);
                break;
            case SfKernel.ScriptCmdType.EndPresentation:
                this._doEndPresentation$1();
                break;
        }
    },
    
    _onPlay$1: function CurrentSlidePanel$_onPlay$1(sender, args) {
        if (mPlayer.PresentationEnded) {
            this._doEndPresentation$1();
        }
    },
    
    _onDataAvailable$1: function CurrentSlidePanel$_onDataAvailable$1(sender, args) {
        this._setCurrentCaptureImage$1();
    },
            
    _showSlide$1: function CurrentSlidePanel$_showSlide$1(args) {
        var slideNumber = args['Index'];
        var currentImage = args['Image'];
        mPlayer.CurrentFullSizeImage = args['FullSizeImage'];
        if (this._showNoImage$1) {
            this._setSlideImage$1('');
            this._setSlideLink$1(null);
        }
        else {
            this._setSlideImage$1(currentImage);
            this._setSlideLink$1(null);
        }
        this._doSlideDescriptionStuff$1(slideNumber);
        if ((Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand) && (slideNumber < Manifest.Slides.length)) {
            this._imageCache$1.AddImage(mPlayer.GetImageLocation(mPlayer.CurrentSlideNumber + 1, SfKernel.SlideType.Normal), true);
        }
        this._updateFullSizeWindow$1(currentImage);
        this._toolbuttonController$1.ensureClickIsInitialized();
    },
    
    _updateFullSizeWindow$1: function CurrentSlidePanel$_updateFullSizeWindow$1(currentImage) {
        if (!WindowHelper.IsOpen(mPlayer.PopupWindows.FullSize)) {
            return;
        }
        var fullSize = mPlayer.PopupWindows.FullSize.SlidePlayer;
        if (SfKernel.Util.IsNullOrUndefined(fullSize)) {
            return;
        }
        fullSize.UpdateIfNeeded(mPlayer.CurrentFullSizeImage, mPlayer.CurrentSlideNumber);
    },
    
    _doSlideDescriptionStuff$1: function CurrentSlidePanel$_doSlideDescriptionStuff$1(slideNumber) {
        if (Manifest.PlayStatus != SfKernel.PresentationPlayStatus.OnDemand) {
            this._setDefaultAltText$1(slideNumber);
            this._setDefaultSlideDescription$1(slideNumber);
        }
        else
        {            
            var slideTitle = Manifest.GetSlideTitle(slideNumber);
     
            if(slideTitle != null && slideTitle.length > 0)            
            {
                this._setAltText$1(slideTitle);
            }                          
            else
            {
                this._setDefaultAltText$1(slideNumber);
            }
            
            var slideDescription = Manifest.GetSlideDescription(slideNumber);
            
     
            if((slideDescription != null && slideDescription.length > 0) || (slideTitle != null && slideTitle.length > 0))
            {
                var slideDescriptionContent;
                if(slideTitle != null && slideTitle.length > 0)
                {
                    slideDescriptionContent = "<b>" + slideTitle + "</b><br/>";
                }
                if(slideDescription != null && slideDescription.length > 0)
                {
                    slideDescriptionContent += slideDescription;
                }
                this._setSlideDescription$1(slideDescriptionContent);
            }
            else
            {         
                this._setDefaultSlideDescription$1(slideNumber);
            }
      }
    },
    
    _doEndPresentation$1: function CurrentSlidePanel$_doEndPresentation$1() {
    if (!LayoutOptions.DoNotShowEndSlide && LayoutOptions.Images['SlideEnded'])
        {
            this._setSlideImage$1(LayoutOptions.Images['SlideEnded'].ImageFilename);
            this._setSlideLink$1(LayoutOptions.Images['SlideEnded'].ImageUrl);
            this._setAltText$1(Localization.CurrentSlideResource.PresentationHasEnded);
            this._setSlideDescription$1(Localization.CurrentSlideResource.PresentationHasEnded);
            this._toolbuttonController$1.resetClick();
        }
    },
    
    _setDefaultSlideDescription$1: function CurrentSlidePanel$_setDefaultSlideDescription$1(slideNumber) {
        this._setSlideDescription$1(String.format('Slide {0}', slideNumber));
    },
    
    _setSlideDescription$1: function CurrentSlidePanel$_setSlideDescription$1(text) {
        $(this._slideDescriptionDiv$1).innerHTML = SfKernel.EncodeHTML(text);
    },
    
    _setDefaultAltText$1: function CurrentSlidePanel$_setDefaultAltText$1(slideNumber) {
        this._setAltText$1(String.format('Slide {0}', slideNumber));
    },
    
    _setAltText$1: function CurrentSlidePanel$_setAltText$1(text) {
        this._slideImageDiv$1.setAttribute('alt', text);
        this._slideImageDiv$1.setAttribute('title', text);
        this._slideDescriptionDiv$1.setAttribute('title', text);
    }
   
}


Type.registerNamespace('CurrentSlide');

CurrentSlide.IToolbuttonController = function() { };
CurrentSlide.IToolbuttonController.prototype = {
    selectButton : null
}
CurrentSlide.IToolbuttonController.registerInterface('CurrentSlide.IToolbuttonController');


CurrentSlide.$create_ToolbuttonClassInfo = function CurrentSlide_ToolbuttonClassInfo(normal, over, disabled, checkedClass) {
    var $o = { };
    $o.normal = normal;
    $o.over = over;
    $o.disabled = disabled;
    $o.checked = checkedClass;
    return $o;
}

CurrentSlide.CurrentSlideToolbuttonController = function CurrentSlide_CurrentSlideToolbuttonController(parentArea) {
    this._parentArea = parentArea;
    this._viewportToolbutton = new CurrentSlide.Toolbutton(this, $(this._parentArea.ID + 'ViewportToolbutton'), CurrentSlide.$create_ToolbuttonClassInfo('CurrentSlideAreaViewportToolbuttonNormal', 'CurrentSlideAreaViewportToolbuttonOver', 'CurrentSlideAreaViewportToolbuttonDisabled', 'CurrentSlideAreaViewportToolbuttonChecked'), Localization.CurrentSlideResource.ShowSlideMagnifier, true);
    this._fullSizeToolbutton = new CurrentSlide.Toolbutton(this, $(this._parentArea.ID + 'FullSizeToolbutton'), CurrentSlide.$create_ToolbuttonClassInfo('CurrentSlideAreaFullSizeToolbuttonNormal', 'CurrentSlideAreaFullSizeToolbuttonOver', 'CurrentSlideAreaFullSizeToolbuttonDisabled', 'CurrentSlideAreaFullSizeToolbuttonChecked'), Localization.CurrentSlideResource.ShowFullSize, true);
    this._slideDescriptionsShowing = new MediasitePlayerCookie().GetBoolValue("ShowSlideDescriptions");
    
    if(this._slideDescriptionsShowing)
    {
            this._parentArea.turnOnSlideDescription();
            this._viewportToolbutton.set_isDisabled(true);
            this._fullSizeToolbutton.set_isDisabled(true);    
    }
}
CurrentSlide.CurrentSlideToolbuttonController.prototype = {
    _parentArea: null,
    _viewportToolbutton: null,
    _fullSizeToolbutton: null,
    _isClickInitialized: false,
    _slideDescriptionsShowing: false,
    
    selectButton: function CurrentSlide_CurrentSlideToolbuttonController$selectButton(button) {
        if (button === this._fullSizeToolbutton) {
            this._onFullSizeClicked();
        }
        else if (button === this._viewportToolbutton) {
            this._onViewportClicked();
        }
        else {
            Error.invalidOperation('Unknown button clicked');
        }
    },
    
    ensureClickIsInitialized: function CurrentSlide_CurrentSlideToolbuttonController$ensureClickIsInitialized() {
        if (this._isClickInitialized) {
            return;
        }
        if (this._fullSizeToolbutton) {
            this._fullSizeToolbutton.set_isDisabled(false);
            this._fullSizeToolbutton.set_tooltip(Localization.CurrentSlideResource.ShowFullSize);
        }
        if (this._viewportToolbutton) {
            this._viewportToolbutton.set_isDisabled(false);
            this._viewportToolbutton.set_tooltip(Localization.CurrentSlideResource.ShowSlideMagnifier);
        }
        this._isClickInitialized = true;
    },
    
    resetClick: function CurrentSlide_CurrentSlideToolbuttonController$resetClick() {
        if (this._fullSizeToolbutton) {
            this._fullSizeToolbutton.set_isDisabled(true);
        }
        if (this._viewportToolbutton) {
            if (this._viewportToolbutton.get_isChecked()) {
                this._hideMagnifier();
            }
            this._viewportToolbutton.set_isDisabled(true);
        }
        this._isClickInitialized = false;
    },
    
    _onFullSizeClicked: function CurrentSlide_CurrentSlideToolbuttonController$_onFullSizeClicked() {
        this._openFullSizeWindow();
    },
        
    ToggleSlideDescriptions: function(){
        
        if(this._slideDescriptionsShowing)
        {
            this._parentArea.turnOffSlideDescription();
            if (mPlayer.CurrentSlideNumber > 0 && !mPlayer.PresentationEnded) 
            {
                this._viewportToolbutton.set_isDisabled(false);
                this._fullSizeToolbutton.set_isDisabled(false);
                this._slideDescriptionsShowing = false;
            }
        }    
        else
        {
            this._parentArea.turnOnSlideDescription();
            this._viewportToolbutton.set_isDisabled(true);
            this._fullSizeToolbutton.set_isDisabled(true);
            this._slideDescriptionsShowing = true;
        }
        
        new MediasitePlayerCookie().SetValue("ShowSlideDescriptions", this._slideDescriptionsShowing);
    },
    
    _onViewportClicked: function CurrentSlide_CurrentSlideToolbuttonController$_onViewportClicked() {
        if (this._viewportToolbutton.get_isChecked()) {
            this._hideMagnifier();
        }
        else {
            this._showMagnifier();
        }
    },
    
    _showMagnifier: function CurrentSlide_CurrentSlideToolbuttonController$_showMagnifier() {
        this._viewportToolbutton.set_tooltip(Localization.CurrentSlideResource.HideSlideMagnifier);
        this._parentArea.showMagnifier();
        this._viewportToolbutton.set_isChecked(true);
    },
    
    _hideMagnifier: function CurrentSlide_CurrentSlideToolbuttonController$_hideMagnifier() {
        this._viewportToolbutton.set_tooltip(Localization.CurrentSlideResource.ShowSlideMagnifier);
        this._parentArea.hideMagnifier();
        this._viewportToolbutton.set_isChecked(false);
    },
    
    _openFullSizeWindow: function CurrentSlide_CurrentSlideToolbuttonController$_openFullSizeWindow() {
        if (WindowHelper.IsOpen(mPlayer.PopupWindows.FullSize)) {
            return;
        }
        mPlayer.PopupWindows.FullSize = WindowHelper.CreateNamedPopup(WindowHelper.PopupNames.FullSize, 'FullSizeWindow', mPlayer.DefaultPopupWindowWidth, mPlayer.DefaultPopupWindowHeight, true, true);
    }
}

CurrentSlide.Toolbutton = function CurrentSlide_Toolbutton(controller, element, classInfo, tooltip, isDisabled) {
    this._controller = controller;
    this._element = element;
    this._classInfo = classInfo;
    this.set_tooltip(tooltip);
    this.set_isDisabled(isDisabled);
}
CurrentSlide.Toolbutton.prototype = {
    _controller: null,
    _element: null,
    _isChecked: false,
    _isDisabled: false,
    _classInfo: null,
    _tooltip: null,
    
    get_tooltip: function CurrentSlide_Toolbutton$get_tooltip() {
        return this._tooltip;
    },
    set_tooltip: function CurrentSlide_Toolbutton$set_tooltip(value) {
        this._tooltip = value;
        SfKernel.Util.SetToolTip(this._element, this._tooltip);
        return value;
    },
    
    get_isChecked: function CurrentSlide_Toolbutton$get_isChecked() {
        return this._isChecked;
    },
    set_isChecked: function CurrentSlide_Toolbutton$set_isChecked(value) {
        this._isChecked = value;
        this._updateImage();
        return value;
    },
    
    get_isDisabled: function CurrentSlide_Toolbutton$get_isDisabled() {
        return this._isDisabled;
    },
    set_isDisabled: function CurrentSlide_Toolbutton$set_isDisabled(value) {
        this._isDisabled = value;
        if (this._isDisabled) {
            this._element.stopObserving();
        }
        else {
            this._element.observe('mouseover', Function.createDelegate(this, this._onMouseOver));
            this._element.observe('mouseout', Function.createDelegate(this, this._onMouseOut));
            this._element.observe('click', Function.createDelegate(this, this._onClick));
        }
        this._updateImage();
        return value;
    },
    
    _onClick: function CurrentSlide_Toolbutton$_onClick(sender, args) {
        this._controller.selectButton(this);
    },
    
    _onMouseOver: function CurrentSlide_Toolbutton$_onMouseOver(sender, args) {
        if (this._isDisabled) {
            return;
        }
        SfKernel.Util.SetCursor(this._element, SfKernel.CursorType.Hand);
        if (!this.get_isChecked()) {
            this._element.className = this._classInfo.over;
        }
    },
    
    _onMouseOut: function CurrentSlide_Toolbutton$_onMouseOut(sender, args) {
        this._updateImage();
        SfKernel.Util.SetCursor(this._element, SfKernel.CursorType.Default);
    },
    
    _updateImage: function CurrentSlide_Toolbutton$_updateImage() {
        if (this._isDisabled) {
            this._element.className = this._classInfo.disabled;
            return;
        }
        if (this._isChecked) {
            this._element.className = this._classInfo.checked;
        }
        else {
            this._element.className = this._classInfo.normal;
        }
    }
}

CurrentSlide.ViewportManager = function CurrentSlide_ViewportManager(parentArea) {
    this._parentArea = parentArea;
    this._initialize();
}
CurrentSlide.ViewportManager.prototype = {
    _parentArea: null,
    _viewportElement: null,
    _viewportImage: null,
    _magnifier: null,
    _isShowing: false,
    
    get_isShowing: function CurrentSlide_ViewportManager$get_isShowing() {
        return this._isShowing;
    },
    set_isShowing: function CurrentSlide_ViewportManager$set_isShowing(value) {
        this._isShowing = value;
        if (value) {
            this._viewportImage.setAttribute('src', mPlayer.CurrentFullSizeImage);
            this._magnifier.Enable();
        }
        else {
            this._magnifier.Disable();
        }
        return value;
    },
    
    _initialize: function CurrentSlide_ViewportManager$_initialize() {
        this._createViewportElement();
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.Script, Function.createDelegate(this, this._onScriptEvent));
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.PlayingFromBeginning, Function.createDelegate(this, this._onPlayingFromBeginning));
        this._magnifier = new SfUI.Magnifier(this._parentArea.get_slideImageDiv(), this._viewportElement);
    },
    
    _createViewportElement: function CurrentSlide_ViewportManager$_createViewportElement() {
        this._viewportElement = $(document.createElement('div'));
        this._viewportElement.setStyle({ overflow: 'hidden', position: 'absolute', display: 'none', border: '1px solid #666', zIndex: '4', cursor: 'crosshair',
                                         width: this._parentArea.ViewportWidth + 'px', 
                                         height: this._parentArea.ViewportHeight + 'px'});
        this._viewportElement.setAttribute('id','currentSlideMagnifierDiv');
        this._viewportImage = $(document.createElement('img'));
        this._viewportImage.setAttribute('id','currentSlideMagnifierImage');
        this._viewportElement.appendChild(this._viewportImage);

        this._parentArea.GetDiv().parentNode.appendChild(this._viewportElement); 
        //this._parentArea.GetDiv().appendChild(this._viewportElement); 
    },
    
    _onScriptEvent: function CurrentSlide_ViewportManager$_onScriptEvent(sender, args) {
        var command = args['Command'];
        switch (command) {
            case SfKernel.ScriptCmdType.ShowSlide:
                this._onShowSlide(args);
                break;
            case SfKernel.ScriptCmdType.EndPresentation:
                this._onEndPresentation(args);
                break;
        }
    },
    
    _onShowSlide: function CurrentSlide_ViewportManager$_onShowSlide(args) {
        if (!this._isShowing) {
            return;
        }
        this._viewportImage.setAttribute('src', args['FullSizeImage']);
    },
    
    _onEndPresentation: function CurrentSlide_ViewportManager$_onEndPresentation(args) {
        this.set_isShowing(false);
    },
    
    _onPlayingFromBeginning: function CurrentSlide_ViewportManager$_onPlayingFromBeginning(sender, args) {
        this.set_isShowing(false);
        if(LayoutOptions.Images['SlideDefault'])
        {
            this._parentArea._setSlideImage$1(LayoutOptions.Images['SlideDefault'].ImageFilename);
            this._parentArea._setSlideLink$1(LayoutOptions.Images['SlideDefault'].ImageUrl);
        }
    }
}

CurrentSlide.CurrentSlideToolbuttonController.registerClass('CurrentSlide.CurrentSlideToolbuttonController', null, CurrentSlide.IToolbuttonController);
CurrentSlide.Toolbutton.registerClass('CurrentSlide.Toolbutton');
CurrentSlide.ViewportManager.registerClass('CurrentSlide.ViewportManager');

ThumbnailsPanel = function(container, containingWindow, id) {
    this.ID = id;
    this.Container = container;
}
ThumbnailsPanel.prototype = {
    _originalThumbnailWidth: 0,
    _originalThumbnailHeight: 0,
    _numSlidesPerPage: 0,
    _slideGroupManager: null,
    _pageCalculator: null,
    _isInitialized: false,
    _thumbnailsDiv: null,
    _pagerContainer: null,
    _slidesContainer: null,
    _textListContainer: null,
    _chaptersContainer: null,
    _pageLinkManager: null,
    _slides: null,
    _zoomHelper: null,
    _lastHilitedSingleSlide: null,
    _currentPageNumber: 0,
    _currentPointNumber: 0,

    _widthOfSurroundingElements: 8,
    _heightOfSurroundingElements: 29,
    _rowsOfThumbnails: 3,
    _columnsOfThumbnails: 4,
    _aspectRation: .75,
    _ratio: 1,
    _defaultThumbSizePosition: 4,
    _minimumThumbnailWidth: 92,

    OnLoad: function ThumbnailsArea$OnLoad() {
        this._getViewCookie();
        this._setPresentationThumbnailDimensions();
        this._calculateNumSlidesPerPage();
        this._registerEvents();
        this._initializeSlideGroupManager();
        this._initializePageCalculator();
        this._drawPageIfShowing();
    },

    _getViewCookie: function ThumbnailsArea$_getViewCookie() {
        var viewCookieValue = new MediasitePlayerCookie().GetNumberValue("SlideDisplay", this._defaultThumbSizePosition);

        // override disables small thumbnails for very small players
        if (LayoutOptions.SlideWidth <= 360 && viewCookieValue == '4') {
            viewCookieValue = 5;
        }

        if (viewCookieValue == '9') {
            if (Manifest.Chapters.length > 0) {
                this._currentPointNumber = viewCookieValue;
                return viewCookieValue;
            }
            else {
                this._currentPointNumber = this._defaultThumbSizePosition;
                return this._defaultThumbSizePosition;
            }
        }
        else {
            this._currentPointNumber = viewCookieValue;
            this._ratio = this.getThumbnailSizeRatio(viewCookieValue);
            return viewCookieValue;
        }
    },

    _setViewCookie: function ThumbnailsArea$_setViewCookie(viewCookieValue) {
        new MediasitePlayerCookie().SetValue("SlideDisplay", viewCookieValue);
    },

    _setPresentationThumbnailDimensions: function ThumbnailsArea$_setPresentationThumbnailDimensions() {
        var thumbnailsarea = $(this.ID);
        var containerWidth = thumbnailsarea.offsetWidth - 6;  // 6, this._widthOfSurroundingElements
        var containerHeight = thumbnailsarea.offsetHeight - 29; // 29, this._heightOfSurroundingElements        
        var thumbnailMaxTotalWidth = Math.floor(containerWidth / this._columnsOfThumbnails);
        var thumbnailMaxImageWidth = thumbnailMaxTotalWidth - this._widthOfSurroundingElements;
        var thumbnailMaxTotalHeight = Math.floor(containerHeight / this._rowsOfThumbnails);
        var thumbnailMaxImageHeight = thumbnailMaxTotalHeight - this._heightOfSurroundingElements;
        var thumbnailAdjustedImageHeight = Math.floor(thumbnailMaxImageWidth * .75);
        if (thumbnailAdjustedImageHeight < thumbnailMaxImageHeight) {
            this._originalThumbnailHeight = thumbnailAdjustedImageHeight;
            this._originalThumbnailWidth = Math.floor(thumbnailAdjustedImageHeight / .75);
        }
        else {
            this._originalThumbnailHeight = thumbnailMaxImageWidth * .75;
            this._originalThumbnailWidth = thumbnailMaxImageWidth;
        }
        this.OriginalThumbnailHeight = this._originalThumbnailHeight;
        this.OriginalThumbnailWidth = this._originalThumbnailWidth;
        this.ThumbnailHeight = Math.floor(this._originalThumbnailHeight * this._ratio);
        this.ThumbnailWidth = Math.floor(this._originalThumbnailWidth * this._ratio);
        this._calculateNumSlidesPerPage();
        this.SlidesPerPage = this._numSlidesPerPage;
    },

    _calculateNumSlidesPerPage: function ThumbnailsArea$_calculateNumSlidesPerPage() {
        var heightOfListItem = 30;
        var thumbnailsarea = $(this.ID);
        if (this.ThumbnailWidth > 0 && this.ThumbnailHeight > 0) {
            this._columnsOfThumbnails = Math.floor((thumbnailsarea.offsetWidth - 6) / (this.ThumbnailWidth + this._widthOfSurroundingElements));
            this._rowsOfThumbnails = Math.floor((thumbnailsarea.offsetHeight - 29) / (this.ThumbnailHeight + this._heightOfSurroundingElements));
        }
        else {
            this._columnsOfThumbnails = 1;
            this._rowsOfThumbnails = Math.floor((thumbnailsarea.offsetHeight - 29) / heightOfListItem);
        }
        this._numSlidesPerPage = this._rowsOfThumbnails * this._columnsOfThumbnails;
    },

    _registerEvents: function ThumbnailsArea$_registerEvents() {
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.Script, Function.createDelegate(this, this._onScriptEvent));
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.PlayingFromBeginning, Function.createDelegate(this, this._onPlayingFromBeginningEvent));
    },

    _onScriptEvent: function ThumbnailsArea$_onScriptEvent(sender, args) {
        var commandType = args['Command'];
        if (commandType !== SfKernel.ScriptCmdType.ShowSlide) {
            return;
        }
        var index = args['Index'];
        if (index < 1) {
            if (this._lastHilitedSingleSlide) {
                this._lastHilitedSingleSlide.unHiliteSlide();
                this._lastHilitedSingleSlide = null;
            }
            return;
        }
        if (mPlayer.DynamicAdd) {
            this._pageCalculator.set_totalSlides(Manifest.Slides.length);
            this._pageCalculator.Calculate();
            var totalSlides = this._pageCalculator.get_totalSlides();
            var maxPage = Math.ceil(totalSlides / this._numSlidesPerPage);
            if (maxPage > this._currentPageNumber) {
                this._pageLinkManager.updatePageLinks(maxPage);
                this._currentPageNumber = maxPage;
            }
        }
        if ($(this.ID).style.display == 'none') {
            return;
        }
        var pageInfo = this._pageCalculator.GetPageInfoForSlide(index);

        if (this._currentPageNumber !== pageInfo.get_pageNumber()) {
            if (this._lastHilitedSingleSlide) {
                this._lastHilitedSingleSlide.unHiliteSlide();
            }
            return;
        }
        if (mPlayer.DynamicAdd) {
            this._drawPage(pageInfo);
        }
        this._hiliteSlideNumber(index);
    },

    _onPlayingFromBeginningEvent: function ThumbnailsArea$_onPlayingFromBeginningEvent(sender, args) {
        if (this._lastHilitedSingleSlide) {
            this._lastHilitedSingleSlide.unHiliteSlide();
            this._lastHilitedSingleSlide = null;
        }
        if ($('CurrentSlideAreaSlideDescription')) {
            $('CurrentSlideAreaSlideDescription').innerHTML = '&nbsp;';
        }
    },

    _initializeSlideGroupManager: function ThumbnailsArea$_initializeSlideGroupManager() {
        this._slideGroupManager = new Thumbnails.SlideGroupManager({ Timings: Manifest.Slides, Threshold: GlobalOptions.SlideGroupThreshold, MinSlidesToTrigger: GlobalOptions.SlideGroupMinToTrigger, MaxInGroup: GlobalOptions.SlideGroupMaxInGroup });
    },

    _initializePageCalculator: function ThumbnailsArea$_initializePageCalculator() {
        this._pageCalculator = new Thumbnails.PageCalculator(this._numSlidesPerPage, Manifest.Slides.length, this._slideGroupManager);
        this._pageCalculator.Calculate();
    },

    _drawPageIfShowing: function ThumbnailsArea$_drawPageIfShowing() {
        if ($(this.ID).style.display != 'none') {
            this._drawPage(this._calculateCurrentSlidePageInfo());
        }
    },

    _calculateCurrentSlidePageInfo: function ThumbnailsArea$_calculateCurrentSlidePageInfo() {
        return this._pageCalculator.GetPageInfoForSlide(mPlayer.CurrentSlideNumber);
    },

    _drawPage: function ThumbnailsArea$_drawPage(pageInfo) {
        if (!this._isInitialized) {
            this._initialize();
        }
        if (pageInfo.get_isDummy()) {
            return;
        }
        this._pageLinkManager.updatePageLinks(pageInfo.get_pageNumber());
        if (this._lastHilitedSingleSlide) {
            this._lastHilitedSingleSlide.unHiliteSlide();
        }
        var pageStartIndex = pageInfo.get_startIndex();
        var pageEndIndex = pageInfo.get_endIndex();
        var counter = 0;
        var currentSlideNumber = mPlayer.CurrentSlideNumber;
        for (var i = pageStartIndex; i <= pageEndIndex; ) {
            var currentSlideGroup = this._slideGroupManager.FindGroupForSlide(i + 1);
            if (!currentSlideGroup) {
                this._slides[counter].set_slideNumber(i + 1);
            }
            else {
                if (currentSlideGroup.get_isExpanded()) {
                    if (currentSlideGroup.get_min() === i + 1) {
                        this._slides[counter].set_group(currentSlideGroup);
                    }
                    else {
                        this._slides[counter].set_slideNumber(i + 1);
                    }
                }
                else {
                    this._slides[counter].set_group(currentSlideGroup);
                }
            }
            if (i + 1 === currentSlideNumber) {
                this._hiliteSlideNumber(i + 1);
            }
            if (currentSlideGroup && !currentSlideGroup.get_isExpanded()) {
                i += currentSlideGroup.GetCount();
            }
            else {
                i += 1;
            }
            this._slides[counter].set_visible(true);
            ++counter;
        }
        for (var i = counter; i < this._numSlidesPerPage && i < this._slides.length; ++i) {
            this._slides[i].set_visible(false);
        }
        this._currentPageNumber = pageInfo.get_pageNumber();
        this._thumbnailsDiv.scrollTop = 0;
    },

    _initialize: function ThumbnailsArea$_initialize() {
        this._initializeElements();
        this._drawBlankPage();
        this._isInitialized = true;
    },

    _initializeElements: function ThumbnailsArea$_initializeElements() {
        this._thumbnailsDiv = $('thumbNailsDiv');
        this._pagerContainer = $('pagerContainer');
        this._slidesContainer = $('thumbNailSlidesContainer');
        this._chaptersContainer = $('ChapterPointsArea');
    },

    _drawBlankPage: function ThumbnailsArea$_drawBlankPage() {
        this._pageLinkManager = new Thumbnails.PageLinkManager(this);
        this._addSlidesContainerElements();
        new Thumbnails.ViewButtonGroup(this);
    },

    _addSlidesContainerElements: function ThumbnailsArea$_addSlidesContainerElements() {
        this._addZoomHelper();
        this._slides = new Array(0);
        //this.updateSlidesPerPage();
        if (this._currentPointNumber == 0) {
            for (var i = 0; i < this._numSlidesPerPage; ++i) {
                this._slides[i] = new Thumbnails.SingleSlide(this, i + 1);
                this._slidesContainer.appendChild(this._slides[i].createListElement());
            }
        }
        else {
            for (var i = 0; i < this._numSlidesPerPage; ++i) {
                this._slides[i] = new Thumbnails.SingleSlide(this, i + 1);
                this._slidesContainer.appendChild(this._slides[i].createThumbnailElement());
            }
        }
    },

    _addZoomHelper: function ThumbnailsArea$_addZoomHelper() {
        this._zoomHelper = new Thumbnails.ZoomHelper(this);
        this._zoomHelper.ThumbnailHeight = this.ThumbnailHeight;
        this._zoomHelper.ThumbnailWidth = this.ThumbnailWidth;
        this._slidesContainer.appendChild(this._zoomHelper.GetZoomElement());
    },

    _hiliteSlideNumber: function ThumbnailsArea$_hiliteSlideNumber(slideNumber) {
        var singleSlide = this._getSingleSlide(slideNumber);
        singleSlide.hiliteSlide();
        if (this._lastHilitedSingleSlide && this._lastHilitedSingleSlide !== singleSlide) {
            this._lastHilitedSingleSlide.unHiliteSlide();
        }
        this._lastHilitedSingleSlide = singleSlide;
    },

    _getSingleSlide: function ThumbnailsArea$_getSingleSlide(slideNumber) {
        for (var i = 0; i < this._slides.length; ++i) {
            if (this._slides[i].containsSlide(slideNumber)) {
                return this._slides[i];
            }
        }
        throw Error.invalidOperation('Could not find slide object for slideNumber: ' + slideNumber);
    },

    _changeImageSize: function ThumbnailsArea$_changeImageSize() {
        for (var i = 0; i < this._slides.length; ++i) {
            this._slides[i].setSize(this.ThumbnailWidth, this.ThumbnailHeight);
        }
        this._zoomHelper.InitializeZoom();
    },

    _reDrawBlankPage: function ThumbnailsArea$_reDrawBlankPage() {
        this._pageLinkManager.updatePageLinks(this._currentPageNumber);
        var firstChild = this._slidesContainer.firstChild;
        while (!SfKernel.Util.IsNullOrUndefined(firstChild)) {
            this._slidesContainer.removeChild(firstChild);
            firstChild = this._slidesContainer.firstChild;
        }
        this._addSlidesContainerElements();
    },

    get_slidesContainer: function ThumbnailsArea$get_slidesContainer() {
        return this._slidesContainer;
    },

    get_pagerContainer: function ThumbnailsArea$get_pagerContainer() {
        return this._pagerContainer;
    },

    getTotalPages: function ThumbnailsArea$getTotalPages() {
        return this._pageCalculator.GetTotalPages();
    },

    drawPageNumber: function ThumbnailsArea$drawPageNumber(pageNumber) {
        this._drawPage(this._pageCalculator.GetPageInfo(pageNumber));
    },

    zoomSingleSlide: function ThumbnailsArea$zoomSingleSlide(slide) {
        this._zoomHelper.ZoomSingleSlide(slide);
    },

    updateSlidesPerPage: function ThumbnailsArea$updateSlidesPerPage(slidesPerPage) {
        this._calculateNumSlidesPerPage();
        var lastPage = Math.floor(Manifest.Slides.length / this._numSlidesPerPage) + 1;
        var targetPage = this._currentPageNumber;
        if (lastPage < this._currentPageNumber) {
            targetPage = lastPage;
        }
        this._pageCalculator = new Thumbnails.PageCalculator(this._numSlidesPerPage, Manifest.Slides.length, this._slideGroupManager);
        this._pageCalculator.Calculate();
        this._reDrawBlankPage();
        this._drawPage(this._pageCalculator.GetPageInfo(targetPage));
    },

    setSlideGroupsIsEnabled: function ThumbnailsArea$setSlideGroupsIsEnabled(isEnabled) {
        this._slideGroupManager.set_isEnabled(isEnabled);
        this._pageCalculator.Calculate();
        this._drawPage(this._calculateCurrentSlidePageInfo());
    },

    getCurrentActualThumbnailWidth: function ThumbnailsArea$getCurrentActualThumbnailWidth() {
        if (this._slides.length > 0) {
            return this._slides[0].getActualWidth();
        }
        return this.ThumbnailWidth;
    },

    getCurrentActualThumbnailHeight: function ThumbnailsArea$getCurrentActualThumbnailHeight() {
        if (this._slides.length > 0) {
            return this._slides[0].getActualHeight();
        }
        return this.ThumbnailHeight;
    },

    getThumbnailSizeRatio: function ThumbnailsArea$getThumbnailSizeRatio(point) {
        switch (point) {
            case 0:
                return 0; // list
                break;
            case 1:
                return 0.53; //6 across
                break;
            case 2:
                return 0.64; //5
                break;
            case 3:
                return 0.75; //? 
                break;
            case 4:
                return 1;    //4
                break;
            case 5:
                return 1.35; //3
                break;
            case 6:
                return 1.5;
                break;
            default:
                return 1;
                break;
        }
    },

    updateThumbnailSize: function ThumbnailsArea$updateThumbnailSize(ratio) {
        if (ratio > 0) {
            var thumbnailWidth = Math.floor(this._originalThumbnailWidth * ratio);
            if (thumbnailWidth >= this._minimumThumbnailWidth) {
                this.ThumbnailWidth = thumbnailWidth;
            }
            else {
                this.ThumbnailWidth = this._minimumThumbnailWidth;
            }
            this.ThumbnailHeight = Math.floor(this._originalThumbnailHeight * ratio);
            this._changeImageSize();
        }
        else {
            this.ThumbnailHeight = 0;
            this.ThumbnailWidth = 0;
        }
        this.updateSlidesPerPage();
    },

    showSlideList: function ThumbnailsArea$showSlideList() {
        var sizeKey = 0;
        this._setViewCookie(sizeKey);
        this.showThumbnailContainer();
        this._currentPointNumber = sizeKey;
        var ratio = this.getThumbnailSizeRatio(sizeKey);
        this.updateThumbnailSize(ratio);
    },

    showSmallThumbnails: function ThumbnailsArea$showSmallThumbnails() {
        var sizeKey = 4;
        this._setViewCookie(sizeKey);
        this.showThumbnailContainer();
        this._currentPointNumber = sizeKey;
        var ratio = this.getThumbnailSizeRatio(sizeKey);
        this.updateThumbnailSize(ratio);
    },

    showLargeThumbnails: function ThumbnailsArea$showLargeThumbnails() {
        var sizeKey = 5;
        this._setViewCookie(sizeKey);
        this.showThumbnailContainer();
        this._currentPointNumber = sizeKey;
        var ratio = this.getThumbnailSizeRatio(sizeKey);
        this.updateThumbnailSize(ratio);
    },

    showChapters: function ThumbnailsArea$showChapters() {
        var sizeKey = 9;
        this._setViewCookie(sizeKey);
        this.showChapterContainer();
    },

    showThumbnailContainer: function ThumbnailsArea$showThumbnailContainer() {
        this._slidesContainer.show();
        this._chaptersContainer.hide();
        this._pagerContainer.show();
    },

    showChapterContainer: function ThumbnailsArea$showChapterContainer() {
        this._slidesContainer.hide();
        this._chaptersContainer.show();
        this._pagerContainer.hide();
    },

    onGroupExpandCollapse: function ThumbnailsArea$onGroupExpandCollapse() {
        this._pageCalculator.Calculate();
        this._reDrawBlankPage();
        this._drawPage(this._pageCalculator.GetPageInfo(this._currentPageNumber));
    },

    showBigSlide: function ThumbnailsArea$showBigSlide(slideNumber) {
        mPlayer.CurrentPreviewImage = mPlayer.GetImageLocation(slideNumber, SfKernel.SlideType.FullSize);

        if (WindowHelper.IsOpen(mPlayer.PopupWindows.PreviewSlide)) {
            var previewSlide = mPlayer.PopupWindows.PreviewSlide.PreviewSlideAreaInstance;
            if (!SfKernel.Util.IsNullOrUndefined(previewSlide)) {
                previewSlide.ChangeImage(mPlayer.CurrentPreviewImage);
            }
        }
        else {
            mPlayer.PopupWindows.PreviewSlide = WindowHelper.CreateNamedPopup(WindowHelper.PopupNames.PreviewSlide, 'PreviewSlide', mPlayer.DefaultPopupWindowWidth, mPlayer.DefaultPopupWindowHeight, true, true);
        }
    }
}


Type.registerNamespace('Thumbnails');

////////////////////////////////////////////////////////////////////////////////
// Thumbnails.PageInfo

Thumbnails.PageInfo = function Thumbnails_PageInfo(startIndex, endIndex, pageNumber) {
    this._startIndex = startIndex;
    this._endIndex = endIndex;
    this._pageNumber = pageNumber;
}
Thumbnails.PageInfo.GetDummyPageInfo = function Thumbnails_PageInfo$GetDummyPageInfo() {
    var info = new Thumbnails.PageInfo(0, 0, 1);
    info._isDummy = true;
    return info;
}
Thumbnails.PageInfo.prototype = {
    _startIndex: 0,
    _endIndex: 0,
    _pageNumber: 0,
    _isDummy: false,

    get_startIndex: function Thumbnails_PageInfo$get_startIndex() {
        return this._startIndex;
    },

    get_endIndex: function Thumbnails_PageInfo$get_endIndex() {
        return this._endIndex;
    },

    get_pageNumber: function Thumbnails_PageInfo$get_pageNumber() {
        return this._pageNumber;
    },

    get_isDummy: function Thumbnails_PageInfo$get_isDummy() {
        return this._isDummy;
    },

    ContainsSlide: function Thumbnails_PageInfo$ContainsSlide(slideNumber) {
        return (slideNumber - 1 >= this._startIndex && slideNumber - 1 <= this._endIndex);
    }
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.PageCalculator

Thumbnails.PageCalculator = function Thumbnails_PageCalculator(slidesPerPage, totalSlides, slideGroupManager) {
    this._slidesPerPage = slidesPerPage;
    this._totalSlides = totalSlides;
    this._slideGroupManager = slideGroupManager;
    this._pagesInfo = null;
}
Thumbnails.PageCalculator.prototype = {
    _slidesPerPage: 0,
    _totalSlides: 0,
    _slideGroupManager: null,
    _pagesInfo: null,

    get_totalSlides: function Thumbnails_PageCalculator$get_totalSlides() {
        return this._totalSlides;
    },
    set_totalSlides: function Thumbnails_PageCalculator$set_totalSlides(value) {
        this._totalSlides = value;
        return value;
    },

    get_slidesPerPage: function Thumbnails_PageCalculator$get_slidesPerPage() {
        return this._slidesPerPage;
    },
    set_slidesPerPage: function Thumbnails_PageCalculator$set_slidesPerPage(value) {
        this._slidesPerPage = value;
        return value;
    },

    Calculate: function Thumbnails_PageCalculator$Calculate() {
        this._pagesInfo = new Array(0);
        var slidesCounter = 0;
        var pageStartIndex = 0;
        for (var i = 0; i < this._totalSlides; ) {
            var group = this._slideGroupManager.FindGroupForSlide(i + 1);
            if (group) {
                if (!group.get_isExpanded()) {
                    i += group.GetCount();
                }
                else {
                    i += 1;
                }
            }
            else {
                i += 1;
            }
            ++slidesCounter;
            if (slidesCounter === this._slidesPerPage) {
                var pageEndIndex = i - 1;
                if (pageEndIndex >= this._totalSlides) {
                    pageEndIndex = this._totalSlides - 1;
                }
                this._pagesInfo[this._pagesInfo.length] = new Thumbnails.PageInfo(pageStartIndex, pageEndIndex, this._pagesInfo.length + 1);
                slidesCounter = 0;
                pageStartIndex = i;
            }
        }
        this._collectRemainingSlides();
        return this._pagesInfo;
    },

    GetPageInfoForSlide: function Thumbnails_PageCalculator$GetPageInfoForSlide(slideNumber) {
        if (!this._pagesInfo.length) {
            return Thumbnails.PageInfo.GetDummyPageInfo();
        }
        if (slideNumber < 1) {
            return this._pagesInfo[0];
        }
        for (var i = 0; i < this._pagesInfo.length; ++i) {
            if (this._pagesInfo[i].ContainsSlide(slideNumber)) {
                return this._pagesInfo[i];
            }
        }
        return Thumbnails.PageInfo.GetDummyPageInfo();
        //throw Error.invalidOperation('could not find page for slideNumber: ' + slideNumber);
    },

    GetTotalPages: function Thumbnails_PageCalculator$GetTotalPages() {
        if (!this._pagesInfo.length) {
            return 1;
        }
        else {
            return this._pagesInfo.length;
        }
    },

    GetPageInfo: function Thumbnails_PageCalculator$GetPageInfo(pageNumber) {
        if (pageNumber > this._pagesInfo.length || pageNumber == 0) {
            pageNumber = this._pagesInfo.length;
        }
        return this._pagesInfo[pageNumber - 1];
    },

    _collectRemainingSlides: function Thumbnails_PageCalculator$_collectRemainingSlides() {
        var numPages = this._pagesInfo.length;
        if (!numPages) {
            if (this._totalSlides > 0) {
                this._pagesInfo[0] = new Thumbnails.PageInfo(0, this._totalSlides - 1, 1);
            }
            else {
                this._pagesInfo[0] = Thumbnails.PageInfo.GetDummyPageInfo();
            }
        }
        else {
            if (this._pagesInfo[numPages - 1].get_endIndex() < this._totalSlides - 1) {
                this._pagesInfo[numPages] = new Thumbnails.PageInfo(this._pagesInfo[numPages - 1].get_endIndex() + 1, this._totalSlides - 1, numPages + 1);
            }
        }
    }
}


Thumbnails.PageInfo.registerClass('Thumbnails.PageInfo');
Thumbnails.PageCalculator.registerClass('Thumbnails.PageCalculator');


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.SlideGroup

Thumbnails.SlideGroup = function Thumbnails_SlideGroup(min, max) {
    this._min = min;
    this._max = max;
}
Thumbnails.SlideGroup.prototype = {
    _min: 0,
    _max: 0,
    _isExpanded: false,

    get_max: function Thumbnails_SlideGroup$get_max() {
        return this._max;
    },
    set_max: function Thumbnails_SlideGroup$set_max(value) {
        this._max = value;
        return value;
    },

    get_isExpanded: function Thumbnails_SlideGroup$get_isExpanded() {
        return this._isExpanded;
    },
    set_isExpanded: function Thumbnails_SlideGroup$set_isExpanded(value) {
        this._isExpanded = value;
        return value;
    },

    get_min: function Thumbnails_SlideGroup$get_min() {
        return this._min;
    },
    set_min: function Thumbnails_SlideGroup$set_min(value) {
        this._min = value;
        return value;
    },

    GetCount: function Thumbnails_SlideGroup$GetCount() {
        return this._max - this._min + 1;
    },

    ContainsSlide: function Thumbnails_SlideGroup$ContainsSlide(slideNumber) {
        return (slideNumber >= this._min && slideNumber <= this._max);
    }
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.SlideGroupCalculator

Thumbnails.SlideGroupCalculator = function Thumbnails_SlideGroupCalculator(args) {
    this._groups = new Array(0);
    this._slideTimings = args['Timings'];
    this._threshold = args['Threshold'];
    this._minSlidesToTrigger = args['MinSlidesToTrigger'];
    this._maxInGroup = args['MaxInGroup'];
}
Thumbnails.SlideGroupCalculator.prototype = {
    _slideTimings: null,
    _threshold: 0,
    _minSlidesToTrigger: 0,
    _maxInGroup: 0,
    _currentGroup: null,

    GetGroups: function Thumbnails_SlideGroupCalculator$GetGroups() {
        return this._groups;
    },

    Calculate: function Thumbnails_SlideGroupCalculator$Calculate() {
        if (Manifest.PlayStatus != SfKernel.PresentationPlayStatus.OnDemand) {
            return;
        }
        if (Manifest.Slides.length < this._minSlidesToTrigger) {
            return;
        }
        var lastTiming = 0;
        for (var i = 0; i < this._slideTimings.length; ++i) {
            if (this._slideTimings[i].Time - lastTiming > this._threshold) {
                if (this._currentGroup) {
                    this._addCurrentGroup();
                }
                if (this._isNextBelowThreshold(i)) {
                    this._startNewGroup(i);
                }
                lastTiming = this._slideTimings[i].Time;
                continue;
            }
            if (!this._currentGroup) {
                if (this._isNextBelowThreshold(i)) {
                    this._startNewGroup(i);
                }
            }
            else {
                if (this._currentGroup.GetCount() < this._maxInGroup) {
                    this._addToExistingGroup(i);
                }
                else {
                    this._addCurrentGroup();
                    if (this._isNextBelowThreshold(i)) {
                        this._startNewGroup(i);
                    }
                }
            }
            lastTiming = this._slideTimings[i].Time;
        }
        if (this._currentGroup) {
            this._addCurrentGroup();
        }
    },

    _isNextBelowThreshold: function Thumbnails_SlideGroupCalculator$_isNextBelowThreshold(index) {
        if (index === this._slideTimings.length - 1) {
            return false;
        }
        return (this._slideTimings[index + 1].Time - this._slideTimings[index].Time <= this._threshold);
    },

    _addCurrentGroup: function Thumbnails_SlideGroupCalculator$_addCurrentGroup() {
        this._groups[this._groups.length] = this._currentGroup;
        this._currentGroup = null;
    },

    _startNewGroup: function Thumbnails_SlideGroupCalculator$_startNewGroup(index) {
        this._currentGroup = new Thumbnails.SlideGroup(index + 1, index + 1);
    },

    _addToExistingGroup: function Thumbnails_SlideGroupCalculator$_addToExistingGroup(index) {
        this._currentGroup.set_max(index + 1);
    }
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.SlideGroupManager

Thumbnails.SlideGroupManager = function Thumbnails_SlideGroupManager(args) {
    var calc = new Thumbnails.SlideGroupCalculator(args);
    calc.Calculate();
    this._slideGroups = calc.GetGroups();
}
Thumbnails.SlideGroupManager.prototype = {
    _slideGroups: null,
    _isEnabled: true,

    get_isEnabled: function Thumbnails_SlideGroupManager$get_isEnabled() {
        return this._isEnabled;
    },
    set_isEnabled: function Thumbnails_SlideGroupManager$set_isEnabled(value) {
        this._isEnabled = value;
        return value;
    },

    FindGroupForSlide: function Thumbnails_SlideGroupManager$FindGroupForSlide(slideNumber) {
        if (!this._isEnabled) {
            return null;
        }
        for (var i = 0; i < this._slideGroups.length; ++i) {
            if (slideNumber < this._slideGroups[i].get_min()) {
                return null;
            }
            if (this._slideGroups[i].ContainsSlide(slideNumber)) {
                return this._slideGroups[i];
            }
        }
        return null;
    }
}


Thumbnails.SlideGroup.registerClass('Thumbnails.SlideGroup');
Thumbnails.SlideGroupCalculator.registerClass('Thumbnails.SlideGroupCalculator');
Thumbnails.SlideGroupManager.registerClass('Thumbnails.SlideGroupManager');


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.OneLink

Thumbnails.OneLink = function Thumbnails_OneLink(parentArea) {
    this._parentArea = parentArea;
    this._createElement();
}
Thumbnails.OneLink.prototype = {
    _parentArea: null,
    _element: null,
    _pageNumber: 0,
    _onClickHandler: null,

    get_element: function Thumbnails_OneLink$get_element() {
        return this._element;
    },

    _createElement: function Thumbnails_OneLink$_createElement() {
        this._element = $(document.createElement('div'));
        this._element.className = 'thumbNailPageNormal';
    },

    _removeChildren: function Thumbnails_OneLink$_removeChildren() {
        while (this._element.hasChildNodes()) {
            this._element.removeChild(this._element.firstChild);
        }
    },

    setPrevious: function Thumbnails_OneLink$setPrevious(pageNumber) {
        this._pageNumber = pageNumber;
        this._element.className = 'thumbNailPagePrevious';
        this._removeChildren();
        SfKernel.Util.SetToolTip(this._element, Localization.ThumbnailsResource.Previous);
        this._addClickHandler();
        this.show();
    },

    setDotDotDot: function Thumbnails_OneLink$setDotDotDot() {
        this._makeText('...');
    },

    setPage: function Thumbnails_OneLink$setPage(pageNumber) {
        this._makePage(pageNumber);
    },

    setCurrentPage: function Thumbnails_OneLink$setCurrentPage(pageNumber) {
        this._makeText('' + pageNumber);
    },

    setOf: function Thumbnails_OneLink$setOf() {
        this._makeText(Localization.ThumbnailsResource.Of);
    },

    setTotal: function Thumbnails_OneLink$setTotal(totalPages) {
        this._makeText('' + totalPages);
    },

    setNext: function Thumbnails_OneLink$setNext(pageNumber) {
        this._pageNumber = pageNumber;
        this._element.className = 'thumbNailPageNext';
        this._removeChildren();
        SfKernel.Util.SetToolTip(this._element, Localization.ThumbnailsResource.Next);
        this._addClickHandler();
        this.show();
    },

    _makeText: function Thumbnails_OneLink$_makeText(text) {
        this._removeChildren();
        this._element.className = 'thumbNailPageCurrent';
        this._element.style.textDecoration = 'none';
        SfKernel.Util.SetText(this._element, text);
        SfKernel.Util.SetToolTip(this._element, '');
        this._removeClickHandler();
        this.show();
    },

    _removeClickHandler: function Thumbnails_OneLink$_removeClickHandler() {
        SfKernel.Util.SetCursor(this._element, SfKernel.CursorType.Default);
        this._element.stopObserving('click', this._onClickHandler);
    },

    _makePage: function Thumbnails_OneLink$_makePage(pageNumber) {
        this._pageNumber = pageNumber;
        this._element.className = 'thumbNailPageNormal';
        this._element.style.textDecoration = 'underline';
        this._removeChildren();
        SfKernel.Util.SetText(this._element, '' + pageNumber);
        SfKernel.Util.SetToolTip(this._element, '');
        this._addClickHandler();
        this.show();
    },

    _addClickHandler: function Thumbnails_OneLink$_addClickHandler() {
        SfKernel.Util.SetCursor(this._element, SfKernel.CursorType.Hand);
        this._element.stopObserving('click', this._onClickHandler);
        this._onClickHandler = Function.createDelegate(this, this._onClick);
        this._element.observe('click', this._onClickHandler);
    },

    show: function Thumbnails_OneLink$show() {
        this._element.show();
    },

    hide: function Thumbnails_OneLink$hide() {
        this._element.hide();
    },

    _onClick: function Thumbnails_OneLink$_onClick(sender, args) {
        this._parentArea.drawPageNumber(this._pageNumber);
    }
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.PageIndexCalculator

Thumbnails.PageIndexCalculator = function Thumbnails_PageIndexCalculator(pageNumber, totalPages, toEachSide) {
    this._pageNumber = pageNumber;
    this._totalPages = totalPages;
    this._toEachSide = toEachSide;
}
Thumbnails.PageIndexCalculator.prototype = {
    _pageNumber: 0,
    _totalPages: 0,
    _toEachSide: 0,

    get_startIndex: function Thumbnails_PageIndexCalculator$get_startIndex() {
        return Math.max(1, this._pageNumber - this._toEachSide - this._getLeftOverFromEnd());
    },

    get_endIndex: function Thumbnails_PageIndexCalculator$get_endIndex() {
        return Math.min(this._totalPages, this._pageNumber + this._toEachSide + this._getLeftOverFromStart());
    },

    _getLeftOverFromEnd: function Thumbnails_PageIndexCalculator$_getLeftOverFromEnd() {
        if ((this._totalPages - this._pageNumber) >= this._toEachSide) {
            return 0;
        }
        else {
            return this._toEachSide - (this._totalPages - this._pageNumber);
        }
    },

    _getLeftOverFromStart: function Thumbnails_PageIndexCalculator$_getLeftOverFromStart() {
        if (this._pageNumber > this._toEachSide) {
            return 0;
        }
        else {
            return this._toEachSide - this._pageNumber + 1;
        }
    }
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.PageLinkChain

Thumbnails.PageLinkChain = function Thumbnails_PageLinkChain(parentArea) {
    this._parentArea = parentArea;
    this._createPageTextSpan();
    this._createPageLinks();
}
Thumbnails.PageLinkChain.prototype = {
    _parentArea: null,
    _pageTextSpan: null,
    _pageLinks: null,

    selectPage: function Thumbnails_PageLinkChain$selectPage(pageNumber) {
        var totalPages = this._parentArea.getTotalPages();
        var toEachSide = (Thumbnails.PageLinkChain._numLinks - 1) / 2;
        var pageIndexCalculator = new Thumbnails.PageIndexCalculator(pageNumber, totalPages, toEachSide);
        var counter = 0;
        if (pageNumber > 1) {
            this._pageLinks[counter].setPrevious(pageNumber - 1);
            ++counter;
        }
        if (pageIndexCalculator.get_startIndex() > 1) {
            this._pageLinks[counter].setDotDotDot();
            ++counter;
        }
        for (var i = pageIndexCalculator.get_startIndex(); i <= pageIndexCalculator.get_endIndex(); ++i) {
            if (i === pageNumber) {
                this._pageLinks[counter].setCurrentPage(i);
            }
            else {
                this._pageLinks[counter].setPage(i);
            }
            ++counter;
        }
        if (pageIndexCalculator.get_endIndex() < totalPages) {
            this._pageLinks[counter].setDotDotDot();
            ++counter;
        }
        this._pageLinks[counter].setOf();
        ++counter;
        this._pageLinks[counter].setTotal(totalPages);
        ++counter;
        if (pageNumber < totalPages) {
            this._pageLinks[counter].setNext(pageNumber + 1);
            ++counter;
        }
        for (var i = counter; i < this._pageLinks.length; ++i) {
            this._pageLinks[i].hide();
        }
    },

    _createPageTextSpan: function Thumbnails_PageLinkChain$_createPageTextSpan() {
        this._pageTextSpan = $(document.createElement('div'));
        this._pageTextSpan.className = 'thumbNailPageLabel';
        SfKernel.Util.SetText(this._pageTextSpan, Localization.ThumbnailsResource.Page + ':');
        this._parentArea.get_pagerContainer().appendChild(this._pageTextSpan);
    },

    _createPageLinks: function Thumbnails_PageLinkChain$_createPageLinks() {
        var extraStuff = 6;
        this._pageLinks = new Array(Thumbnails.PageLinkChain._numLinks + extraStuff);
        for (var i = 0; i < Thumbnails.PageLinkChain._numLinks + extraStuff; ++i) {
            this._appendOneLink(i);
        }
    },

    _appendOneLink: function Thumbnails_PageLinkChain$_appendOneLink(index) {
        var link = new Thumbnails.OneLink(this._parentArea);
        this._parentArea.get_pagerContainer().appendChild(link.get_element());
        this._pageLinks[index] = link;
    }
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.PageLinkManager

Thumbnails.PageLinkManager = function Thumbnails_PageLinkManager(parentArea) {
    this._parentArea = parentArea;
    this._topPageLinks = new Thumbnails.PageLinkChain(this._parentArea);
}
Thumbnails.PageLinkManager.prototype = {
    _parentArea: null,
    _topPageLinks: null,

    updatePageLinks: function Thumbnails_PageLinkManager$updatePageLinks(pageNumber) {
        this._topPageLinks.selectPage(pageNumber);
    }
}

Thumbnails.OneLink.registerClass('Thumbnails.OneLink');
Thumbnails.PageIndexCalculator.registerClass('Thumbnails.PageIndexCalculator');
Thumbnails.PageLinkChain.registerClass('Thumbnails.PageLinkChain');
Thumbnails.PageLinkManager.registerClass('Thumbnails.PageLinkManager');
Thumbnails.PageLinkChain._numLinks = 9;


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.SingleSlide

Thumbnails.SingleSlide = function Thumbnails_SingleSlide(parentArea, position) {
    this._parentArea = parentArea;
    this._position = position;
    this._expandCollapse = new Thumbnails.SingleSlideExpandCollapse(this, this._parentArea);
}
Thumbnails.SingleSlide.prototype = {
    _parentArea: null,
    _position: 0,
    _group: null,
    _element: null,
    _imageElement: null,
    _imageContainer: null,
    _previewLinkElement: null,
    //    _playLinkElement: null,
    _slideNumberElement: null,
    _timingElement: null,
    _titleElement: null,
    _expandCollapse: null,
    _zoomHandle: 0,
    _slideNumber: 0,
    _visible: false,

    get_slideNumber: function Thumbnails_SingleSlide$get_slideNumber() {
        return this._slideNumber;
    },
    set_slideNumber: function Thumbnails_SingleSlide$set_slideNumber(value) {
        this._slideNumber = value;
        this._imageElement.setAttribute('src', mPlayer.GetImageLocationUsingWidthAndHeight(this._slideNumber, this._parentArea.ThumbnailWidth, this._parentArea.ThumbnailHeight));
        if (this._parentArea._currentPointNumber != 0) {
            SfKernel.Util.SetToolTip(this._imageElement, '' + SfKernel.EncodeClean(Manifest.Slides[this._slideNumber - 1].Text));
        }
        SfKernel.Util.SetText(this._timingElement, SfKernel.GetDisplayDuration(Manifest.Slides[this._slideNumber - 1].Time));
        SfKernel.Util.SetText(this._slideNumberElement, '' + this._slideNumber);
        if (this._titleElement) {
            SfKernel.Util.SetText(this._titleElement, '' + SfKernel.EncodeClean(Manifest.Slides[this._slideNumber - 1].Text));
            SfKernel.Util.SetToolTip(this._titleElement, SfKernel.EncodeClean(Manifest.Slides[this._slideNumber - 1].Description));
        }
        this._group = null;
        this._expandCollapse.unActivate();
        this._imageElement.setStyle({ display: 'block' })
        return value;
    },

    get_group: function Thumbnails_SingleSlide$get_group() {
        return this._group;
    },
    set_group: function Thumbnails_SingleSlide$set_group(value) {
        this._group = value;
        this._imageElement.setAttribute('src', mPlayer.GetImageLocationUsingWidthAndHeight(this._group.get_min(), this._parentArea.ThumbnailWidth, this._parentArea.ThumbnailHeight));
        if (this._parentArea._currentPointNumber != 0) {
            SfKernel.Util.SetToolTip(this._imageElement, '' + SfKernel.EncodeClean(Manifest.Slides[this._group.get_min() - 1].Text));
        }
        SfKernel.Util.SetText(this._timingElement, SfKernel.GetDisplayDuration(Manifest.Slides[this._group.get_min() - 1].Time));
        SfKernel.Util.SetText(this._slideNumberElement, '' + this._group.get_min());
        if (this._titleElement) {
            SfKernel.Util.SetText(this._titleElement, '' + SfKernel.EncodeClean(Manifest.Slides[this._group.get_min() - 1].Text));
            SfKernel.Util.SetToolTip(this._titleElement, SfKernel.EncodeClean(Manifest.Slides[this._group.get_min() - 1].Description));
        }
        this._slideNumber = this._group.get_min();
        this._expandCollapse.activate();
        return value;
    },

    get_visible: function Thumbnails_SingleSlide$get_visible() {
        return this._visible;
    },
    set_visible: function Thumbnails_SingleSlide$set_visible(value) {
        this._visible = value;
        if (this._visible) {
            this._element.style.visibility = 'visible';
        }
        else {
            this._element.style.visibility = 'hidden';
        }
        return value;
    },

    get_position: function Thumbnails_SingleSlide$get_position() {
        return Thumbnails.$create_Position(this._element.offsetLeft, this._element.offsetTop);
    },

    setSize: function Thumbnails_SingleSlide$setSize(width, height) {
        this._element.style.width = '' + width + 'px';
        this._imageElement.style.width = '' + width + 'px';
        this._imageElement.style.height = '' + height + 'px';
    },

    getActualWidth: function Thumbnails_SingleSlide$getActualWidth() {
        return this._imageElement.getWidth();
    },

    getActualHeight: function Thumbnails_SingleSlide$getActualHeight() {
        return this._imageElement.getHeight();
    },

    containsSlide: function Thumbnails_SingleSlide$containsSlide(slideNumber) {
        if (!this._group) {
            return (this._slideNumber === slideNumber);
        }
        if (this._group.get_isExpanded()) {
            return (this._slideNumber === slideNumber);
        }
        else {
            return this._group.ContainsSlide(slideNumber);
        }
    },

    hiliteSlide: function Thumbnails_SingleSlide$hiliteSlide() {
        //check if we're on list or thumb
        if (this._parentArea._currentPointNumber == 0) {
            this._element.className = 'textSlideListItemCurrent';
        }
        else {
            this._element.className = 'thumbnailItemCurrent';
        }
    },

    unHiliteSlide: function Thumbnails_SingleSlide$unHiliteSlide() {
        // check if we're on the currently running slide or not
        if (this._parentArea._currentPointNumber == 0) {
            this._element.className = 'textSlideListItem';
        }
        else {
            this._element.className = 'thumbNailSlide';
        }
    },


    createThumbnailElement: function Thumbnails_SingleSlide$createThumbnailElement() {

        this._element = $(document.createElement('div'));
        this._element.style.visibility = 'hidden';
        var width = this._parentArea.ThumbnailWidth + 'px';
        var height = this._parentArea.ThumbnailHeight + 'px';
        this._element.className = 'thumbNailSlide';
        var style = {};
        style['position'] = 'relative';
        style['float'] = 'left';
        style['width'] = width;
        this._element.setStyle(style);

        var shadowBottom = $(document.createElement('div'));
        shadowBottom.className = "thumbnailShadowBottom";
        var shadowRight = $(document.createElement('div'));
        shadowRight.className = "thumbnailShadowRight";
        var shadowCorner = $(document.createElement('div'));
        shadowCorner.className = "thumbnailShadowCorner";

        this._imageContainer = document.createElement('div');
        this._imageContainer.className = 'thumbNailImage';
        this._imageElement = $(document.createElement('img'));
        this._imageElement.setStyle({ width: width, height: height, left: '0px' });
        this._imageElement.setAttribute('src', LayoutOptions.ThemeImageBase + '/1x1.gif');
        this._bottomElement = $(document.createElement('div'));
        this._slideNumberElement = $(document.createElement('div'));
        this._slideNumberElement.className = 'thumbNailSlideNumber';
        this._timingElement = $(document.createElement('div'));
        this._timingElement.className = 'thumbNailTiming';

        this._imageContainer.appendChild(this._imageElement);
        this._element.appendChild(this._imageContainer);
        this._element.appendChild(this._bottomElement);
        this._element.appendChild(shadowRight);
        this._element.appendChild(shadowBottom);
        this._element.appendChild(shadowCorner);
        this._imageContainer.appendChild(this._slideNumberElement);
        this._element.appendChild(this._expandCollapse.createBlankElement());
        this._bottomElement.appendChild(this._timingElement);
        this._bottomElement.className = 'thumbnailHandle';
        this._bottomElement.style.cursor = 'url(' + LayoutOptions.ThemeImageBase + '/SlideSorter/magCursor.cur), url(' + LayoutOptions.ThemeImageBase + '/SlideSorter/magCursor.gif), pointer';

        this._element.style.visibility = 'hidden';
        this._bottomElement.observe('click', Function.createDelegate(this, this._NavOnly));
        this._bottomElement.observe('dblclick', Function.createDelegate(this, this._NavAndSwitch));
        this._bottomElement.observe('mouseover', Function.createDelegate(this, this._ThumbnailonMouseOver));

        // hack: this was supposed to be this._imageElement.observe 
        this._element.observe('click', Function.createDelegate(this, this._NavOnly));
        this._element.observe('dblclick', Function.createDelegate(this, this._NavAndSwitch));
        // end hack

        this._element.observe('mouseout', Function.createDelegate(this, this._ThumbnailonMouseOut));
        return this._element;
    },

    createListElement: function Thumbnails_SingleSlide$createListElement() {
        this._element = $(document.createElement('div'));
        var parentWidth = this._parentArea.get_slidesContainer().offsetWidth;
        this._element.setStyle({ width: (parentWidth - 20) + 'px' });
        this._parentArea.ThumbnailWidth = 28;
        this._parentArea.ThumbnailHeight = 21;
        var width = '28px';
        var height = '21px';
        this._element.className = 'textSlideListItem';

        this._slideNumberElement = $(document.createElement('div'));
        this._slideNumberElement.className = 'textSlideListNumber';
        this._element.appendChild(this._slideNumberElement);

        var imageContainer = document.createElement('div');
        this._imageElement = $(document.createElement('img'));
        this._imageElement.setAttribute('height', '21');
        this._imageElement.setAttribute('width', '28');
        imageContainer.appendChild(this._imageElement);
        this._element.appendChild(imageContainer);
        imageContainer.className = 'textSlideListZoomImage';
        imageContainer.style.cursor = 'url(' + LayoutOptions.ThemeImageBase + '/SlideSorter/magCursor.cur), url(' + LayoutOptions.ThemeImageBase + '/SlideSorter/magCursor.gif), pointer';


        this._addImageElementEvents();

        this._element.appendChild(this._expandCollapse.createBlankElement('slideListExpandCollapse'));

        this._timingElement = $(document.createElement('div'));
        this._timingElement.className = 'textSlideListTime';
        this._element.appendChild(this._timingElement);

        this._titleElement = $(document.createElement('div'));
        this._titleElement.className = 'textSlideListTitleNormal';
        this._titleElement.setStyle({ width: (parentWidth - 153) + 'px' });
        this._element.appendChild(this._titleElement);

        this._element.style.visibility = 'hidden';
        this._element.observe('click', Function.createDelegate(this, this._NavOnly));
        this._element.observe('dblclick', Function.createDelegate(this, this._NavAndSwitch));
        this._element.observe('mouseover', Function.createDelegate(this, this._ListonMouseOver));
        //this._imageElement.observe('mouseover', Function.createDelegate(this, this._ListImageonMouseOver));
        this._element.observe('mouseout', Function.createDelegate(this, this._ListonMouseOut));
        return this._element;
    },

    _addImageElementEvents: function Thumbnails_SingleSlide$_addImageElementEvents() {
        this._imageElement.observe('mouseover', Function.createDelegate(this, this._imageOnMouseOver));
    },

    _imageOnMouseOver: function Thumbnails_SingleSlide$_imageOnMouseOver() {
        this._delayedZoom();
    },

    _NavOnly: function Thumbnails_SingleSlide$_NavOnly(sender, args) {
        mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.NavigateToSlide, this, { SlideNumber: this._slideNumber });
    },

    _NavAndSwitch: function Thumbnails_SingleSlide$_NavAndSwitch() {
        mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.NavigateToSlide, this, { SlideNumber: this._slideNumber });
        mPlayer.btnSlideShowInstance.OnClick();
    },

    _ThumbnailonMouseOver: function Thumbnails_SingleSlide$_ThumbnailonMouseOver(sender, args) {
        this._element.className = 'thumbNailSlideX';
        this._previewLinkThumbnailOnMouseOver();
    },

    _ThumbnailonMouseOut: function Thumbnails_SingleSlide$_ThumbnailonMouseOut(sender, args) {
        this._element.className = 'thumbNailSlide';
        window.clearTimeout(this._zoomHandle);
    },

    //    _ListonClick: function Thumbnails_SingleSlide$_ListonClick(sender, args) {
    //        mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.NavigateToSlide, this, { SlideNumber: this._slideNumber });
    //    },

    _ListonMouseOver: function Thumbnails_SingleSlide$_ListonMouseOver(sender, args) {
        this._element.className = 'textSlideListItemOver';
        this._titleElement.className = 'textSlideListTitleOver';
    },

    _ListonMouseOut: function Thumbnails_SingleSlide$_ListonMouseOut(sender, args) {
        this._element.className = 'textSlideListItem';
        this._titleElement.className = 'textSlideListTitleNormal';
        window.clearTimeout(this._zoomHandle);
    },

    _delayedZoom: function Thumbnails_SingleSlide$_delayedZoom() {
        this._zoomHandle = window.setTimeout(Function.createDelegate(this, this._showZoom), 700);
    },

    _showZoom: function Thumbnails_SingleSlide$_showZoom() {
        this._parentArea.zoomSingleSlide(this);
    },

    _createPreviewLinkElement: function Thumbnails_SingleSlide$_createPreviewLinkElement() {
        this._previewLinkElement = $(document.createElement('div'));
        SfKernel.Util.SetToolTip(this._previewLinkElement, Localization.ThumbnailsResource.PreviewSlide);
        SfKernel.Util.SetCursor(this._previewLinkElement, SfKernel.CursorType.Hand);
    },

    _previewLinkThumbnailOnMouseOver: function Thumbnails_SingleSlide$_previewLinkThumbnailOnMouseOver(sender, args) {
        this._delayedZoom();
    },

    _playLinkOnMouseOver: function Thumbnails_SingleSlide$_playLinkOnMouseOver(sender, args) {
        this._playLinkElement.className = 'thumbNailZoomPlayLinkOver';
    },

    _playLinkOnMouseOut: function Thumbnails_SingleSlide$_playLinkOnMouseOut(sender, args) {
        this._playLinkElement.className = 'thumbNailZoomPlayLinkNormal';
    },

    _playLinkOnClick: function Thumbnails_SingleSlide$_playLinkOnClick(sender, args) {
        mPlayer.btnSlideShowInstance.OnClick();
    }
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.SingleSlideExpandCollapse

Thumbnails.SingleSlideExpandCollapse = function Thumbnails_SingleSlideExpandCollapse(singleSlide, parentArea) {
    this._singleSlide = singleSlide;
    this._parentArea = parentArea;
}
Thumbnails.SingleSlideExpandCollapse.prototype = {
    _singleSlide: null,
    _parentArea: null,
    _element: null,
    _isExpanded: false,
    _isShowing: false,

    get_isExpanded: function Thumbnails_SingleSlideExpandCollapse$get_isExpanded() {
        return this._isExpanded;
    },
    set_isExpanded: function Thumbnails_SingleSlideExpandCollapse$set_isExpanded(value) {
        this._isExpanded = value;
        if (this._isExpanded) {
            this._element.className = 'thumbNailExpandCollapseExpandedSmall';
            SfKernel.Util.SetToolTip(this._element, Localization.ThumbnailsResource.CollapseSlides);
        }
        else {
            this._element.className = 'thumbNailExpandCollapseCollapsedSmall';
            SfKernel.Util.SetToolTip(this._element, Localization.ThumbnailsResource.ExpandSlides);            
        }
        return value;
    },

    createBlankElement: function Thumbnails_SingleSlideExpandCollapse$createBlankElement() {
        var divDom = document.createElement('div');
        this._element = $(divDom);
        this._element.className = 'thumbNailExpandCollapseExpandedSmall';
        this._element.observe('click', Function.createDelegate(this, this._expandCollapseOnClick));
        SfKernel.Util.SetToolTip(this._element, Localization.ThumbnailsResource.ExpandSlides);
        return this._element;
    },

    _expandCollapseOnClick: function Thumbnails_SingleSlideExpandCollapse$_expandCollapseOnClick(sender, args) {
        if (this._isExpanded) {
            this._singleSlide.get_group().set_isExpanded(false);
            this._parentArea.onGroupExpandCollapse();
        }
        else {
            this._singleSlide.get_group().set_isExpanded(true);
            this._parentArea.onGroupExpandCollapse();
        }
    },

    activate: function Thumbnails_SingleSlideExpandCollapse$activate() {
        this.set_isExpanded(this._singleSlide.get_group().get_isExpanded());
        this._element.show();
    },

    unActivate: function Thumbnails_SingleSlideExpandCollapse$unActivate() {
        this._element.hide();
    }
}


Thumbnails.SingleSlide.registerClass('Thumbnails.SingleSlide');
Thumbnails.SingleSlideExpandCollapse.registerClass('Thumbnails.SingleSlideExpandCollapse');

////////////////////////////////////////////////////////////////////////////////
// Thumbnails.Dimension

Thumbnails.$create_Dimension = function Thumbnails_Dimension(width, height) {
    var $o = {};
    $o.Width = width;
    $o.Height = height;
    return $o;
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.Position

Thumbnails.$create_Position = function Thumbnails_Position(x, y) {
    var $o = {};
    $o.X = x;
    $o.Y = y;
    return $o;
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.Offset

Thumbnails.$create_Offset = function Thumbnails_Offset(top, left) {
    var $o = {};
    $o.Top = top;
    $o.Left = left;
    return $o;
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.Bounds

Thumbnails.$create_Bounds = function Thumbnails_Bounds(top, left, width, height) {
    var $o = {};
    $o.Top = top;
    $o.Left = left;
    $o.Width = width;
    $o.Height = height;
    return $o;
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.BoundsInt

Thumbnails.$create_BoundsInt = function Thumbnails_BoundsInt(top, left, width, height) {
    var $o = {};
    $o.Top = top;
    $o.Left = left;
    $o.Width = width;
    $o.Height = height;
    return $o;
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.ZoomCalculator

Thumbnails.ZoomCalculator = function Thumbnails_ZoomCalculator(containerDimension, zoomedImageDimension, thumbnailDimension) {
    this._containerDimension = containerDimension;
    this._zoomedImageDimension = zoomedImageDimension;
    this._thumbnailDimension = thumbnailDimension;
    this._deltaX = (this._zoomedImageDimension.Width - this._thumbnailDimension.Width) / 2;
    this._deltaY = (this._zoomedImageDimension.Height - this._thumbnailDimension.Height) / 2;
}
Thumbnails.ZoomCalculator.prototype = {
    _containerDimension: null,
    _zoomedImageDimension: null,
    _thumbnailDimension: null,
    _deltaX: 0,
    _deltaY: 0,

    calculatePositionToShow: function Thumbnails_ZoomCalculator$calculatePositionToShow(currentThumbnailPosition) {
        if (currentThumbnailPosition.X >= this._deltaX) {
            if (this._containerDimension.Width >= currentThumbnailPosition.X - this._deltaX + this._zoomedImageDimension.Width) {
                if (currentThumbnailPosition.Y >= this._deltaY) {
                    if (this._containerDimension.Height >= currentThumbnailPosition.Y - this._deltaY + this._zoomedImageDimension.Height) {
                        return Thumbnails.$create_Position((currentThumbnailPosition.X - this._deltaX), (currentThumbnailPosition.Y - this._deltaY));
                    }
                    else {
                        return Thumbnails.$create_Position((currentThumbnailPosition.X - this._deltaX), (this._containerDimension.Height - this._zoomedImageDimension.Height));
                    }
                }
                else {
                    return Thumbnails.$create_Position((currentThumbnailPosition.X - this._deltaX), 0);
                }
            }
            else {
                if (currentThumbnailPosition.Y >= this._deltaY) {
                    if (this._containerDimension.Height >= currentThumbnailPosition.Y - this._deltaY + this._zoomedImageDimension.Height) {
                        return Thumbnails.$create_Position((this._containerDimension.Width - this._zoomedImageDimension.Width), (currentThumbnailPosition.Y - this._deltaY));
                    }
                    else {
                        return Thumbnails.$create_Position((this._containerDimension.Width - this._zoomedImageDimension.Width), (this._containerDimension.Height - this._zoomedImageDimension.Height));
                    }
                }
                else {
                    return Thumbnails.$create_Position((this._containerDimension.Width - this._zoomedImageDimension.Width), 0);
                }
            }
        }
        else {
            if (currentThumbnailPosition.Y >= this._deltaY) {
                if (this._containerDimension.Height >= currentThumbnailPosition.Y - this._deltaY + this._zoomedImageDimension.Height) {
                    return Thumbnails.$create_Position(0, (currentThumbnailPosition.Y - this._deltaY));
                }
                else {
                    return Thumbnails.$create_Position(0, (this._containerDimension.Height - this._zoomedImageDimension.Height));
                }
            }
            else {
                return Thumbnails.$create_Position(0, 0);
            }
        }
    }
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.ZoomHelper

Thumbnails.ZoomHelper = function Thumbnails_ZoomHelper(parentArea) {
    this._parentArea = parentArea;
    this._setThumbDimensions();
    this._createZoomElement();
}
Thumbnails.ZoomHelper.prototype = {
    _parentArea: null,
    _zoomElement: null,
    _imageElement: null,
    _slideNumberElement: null,
    _expandCollapseElement: null,
    _slideTimeElement: null,
    _playLinkElement: null,
    _anchorElement: null,
    _previewLinkElement: null,
    _currentSingleSlide: null,
    _isZoomInitialized: false,
    _isExpanded: false,
    _hideHandle: 0,
    _zoomCalculator: null,
    _zoomHeight: 225,
    _zoomWidth: 300,
    _zoomFactor: 2,
    _zoomBarHeight: 24,

    _setThumbDimensions: function Thumbnails_ZoomHelper$setThumbDimensions() {
        this._zoomHeight = this._parentArea.OriginalThumbnailHeight * 2;
        this._zoomWidth = this._parentArea.OriginalThumbnailWidth * 2;
    },

    ZoomSingleSlide: function Thumbnails_ZoomHelper$ZoomSingleSlide(singleSlide) {
        var thumbnailPos = singleSlide.get_position();
        this._currentSingleSlide = singleSlide;

        this._zoomWidth = Math.floor(this._parentArea.OriginalThumbnailWidth * this._zoomFactor);
        this._zoomHeight = Math.floor(this._parentArea.OriginalThumbnailHeight * this._zoomFactor);
        this._imageElement.setAttribute('src', mPlayer.GetImageLocationUsingWidthAndHeight(singleSlide.get_slideNumber(), this._zoomWidth, this._zoomHeight));

        if (!this._isZoomInitialized) {
            this.InitializeZoom();
        }
        if (!singleSlide.get_group()) {
            this._expandCollapseElement.hide();
        }
        else {
            this._setExpanded(this._currentSingleSlide.get_group().get_isExpanded());
            this._expandCollapseElement.show();
        }
        this._setSlideNumberText();

        SfKernel.Util.SetText(this._slideTimeElement, SfKernel.GetDisplayDuration(Manifest.Slides[singleSlide.get_slideNumber() - 1].Time));
        SfKernel.Util.SetToolTip(this._imageElement, Manifest.Slides[singleSlide.get_slideNumber() - 1].Text); //handles IE
        SfKernel.Util.SetToolTip(this._focusCatcherElement, Manifest.Slides[singleSlide.get_slideNumber() - 1].Text); //handles FF etc.

        var initial = Thumbnails.$create_BoundsInt(thumbnailPos.Y, thumbnailPos.X, this._parentArea.getCurrentActualThumbnailWidth(), this._parentArea.getCurrentActualThumbnailHeight());

        var scrollOffsets = Thumbnails.$create_Offset(this._parentArea.get_slidesContainer().scrollTop, this._parentArea.get_slidesContainer().scrollLeft);
        thumbnailPos.X -= scrollOffsets.Left;
        thumbnailPos.Y -= scrollOffsets.Top;

        var displayPos = this._zoomCalculator.calculatePositionToShow(thumbnailPos);

        if (this._parentArea._currentPointNumber == 0) {
            displayPos.X += 85;
            $('thumbNailZoomAnchorElement').style.top = (thumbnailPos.Y - displayPos.Y - 7) + 'px';

        }
        //displayPos.X += scrollOffsets.Left;   
        //displayPos.Y += scrollOffsets.Top;

        if (displayPos.X + this._zoomElement.getWidth() > this._parentArea.get_slidesContainer().getWidth() - Thumbnails.ZoomHelper._scrollbarWidth) {
            displayPos.X -= Thumbnails.ZoomHelper._scrollbarWidth;
        }

        this.SetBounds(Thumbnails.$create_Bounds(initial.Top + 'px', initial.Left + 'px', initial.Width + 'px', initial.Height + 'px'));
        this._zoomElement.style.visibility = 'visible';
        this.SetBounds(Thumbnails.$create_Bounds(displayPos.Y + 'px', displayPos.X + 'px', this._zoomWidth + 'px', this._zoomHeight + 'px'))
    },

    GetZoomElement: function Thumbnails_ZoomHelper$GetZoomElement() {
        return this._zoomElement;
    },

    SetBounds: function Thumbnails_ZoomHelper$SetBounds(bounds) {
        this._zoomElement.style.top = bounds.Top;
        this._zoomElement.style.left = bounds.Left;
        this._zoomElement.style.width = bounds.Width;
        this._imageElement.style.width = bounds.Width;
        this._imageElement.style.height = bounds.Height;
    },

    _setSlideNumberText: function Thumbnails_ZoomHelper$_setSlideNumberText() {
        var text;
        if (!this._currentSingleSlide.get_group()) {
            text = '' + this._currentSingleSlide.get_slideNumber();
        }
        else {
            text = '' + this._currentSingleSlide.get_group().get_min();
        }
        SfKernel.Util.SetText(this._slideNumberElement, text);
    },

    _setExpanded: function Thumbnails_ZoomHelper$_setExpanded(val) {
        if (val) {
            SfKernel.Util.SetToolTip(this._expandCollapseElement, Localization.ThumbnailsResource.CollapseSlides);
            this._expandCollapseElement.className = 'thumbNailZoomExpandCollapseExpanded';
        }
        else {
            SfKernel.Util.SetToolTip(this._expandCollapseElement, Localization.ThumbnailsResource.ExpandSlides);
            this._expandCollapseElement.className = 'thumbNailZoomExpandCollapseCollapsed';
        }
        this._isExpanded = val;
    },

    InitializeZoom: function Thumbnails_ZoomHelper$InitializeZoom() {
        var containerDimension = this._parentArea.get_slidesContainer().getDimensions();
        this._zoomCalculator = new Thumbnails.ZoomCalculator(Thumbnails.$create_Dimension(containerDimension.width, containerDimension.height), Thumbnails.$create_Dimension(this._zoomElement.getWidth(), this._zoomElement.getHeight()), Thumbnails.$create_Dimension(this._parentArea.getCurrentActualThumbnailWidth(), this._parentArea.getCurrentActualThumbnailHeight()));
        this._isZoomInitialized = true;
    },

    _createZoomElement: function Thumbnails_ZoomHelper$_createZoomElement() {
        this._zoomElement = $(document.createElement('div'));
        this._zoomElement.className = 'thumbNailZoomElement';
        this._zoomElement.id = 'thumbNailZoomElement';

        var shadowBottom = $(document.createElement('div'));
        shadowBottom.className = "thumbnailZoomShadowBottom";
        var shadowRight = $(document.createElement('div'));
        shadowRight.className = "thumbnailZoomShadowRight";
        var shadowCorner = $(document.createElement('div'));
        shadowCorner.className = "thumbnailZoomShadowCorner";

        this._focusCatcherElement = $(document.createElement('div'));
        this._focusCatcherElement.className = 'thumbnailZoomFocusCatcher';
        this._focusCatcherElement.id = 'thumbnailZoomFocusCatcher';
        this._focusCatcherElement.setStyle({ width: (this._zoomWidth) + 'px', height: (this._zoomHeight + this._zoomBarHeight) + 'px' })
        this._zoomElement.appendChild(this._focusCatcherElement);

        this._zoomElement.appendChild(shadowRight);
        this._zoomElement.appendChild(shadowBottom);
        this._zoomElement.appendChild(shadowCorner);

        if (this._parentArea._currentPointNumber == 0) {
            this._createAnchorElement();
            this._zoomElement.appendChild(this._anchorElement);
        }
        this._zoomElement.setStyle({ width: this._zoomWidth + 'px', height: (this._zoomHeight + this._zoomBarHeight) + 'px' });

        var imgContainer = $(document.createElement('div'));
        imgContainer.className = 'thumbNailZoomImageDiv';
        this._zoomElement.appendChild(imgContainer);

        this._imageElement = $(document.createElement('img'));
        imgContainer.appendChild(this._imageElement);
        this._imageElement.setStyle({ width: this._zoomWidth + 'px', height: this._zoomHeight + 'px' });

        var bottomDiv = document.createElement('div');
        bottomDiv.className = 'thumbNailZoomBottomDiv';
        this._zoomElement.appendChild(bottomDiv);

        this._createSlideNumberElement();
        bottomDiv.appendChild(this._slideNumberElement);

        this._createExpandCollapseElement();
        bottomDiv.appendChild(this._expandCollapseElement);

        this._createSlideTimeElement();
        bottomDiv.appendChild(this._slideTimeElement);

        this._createPreviewLinkElement();
        bottomDiv.appendChild(this._previewLinkElement);

        this._addZoomElementEvents();
    },

    _createAnchorElement: function Thumbnails_ZoomHelper$_createAnchorElement() {
        this._anchorElement = $(document.createElement('div'));
        this._anchorElement.id = 'thumbNailZoomAnchorElement';
        this._anchorElement.className = 'thumbNailZoomAnchorElement';
        this._anchorElement.observe('click', Function.createDelegate(this, this._onImageClick));
        this._anchorElement.observe('mouseover', Function.createDelegate(this, this._resetZoomTimer), true);
        this._anchorElement.observe('mouseout', Function.createDelegate(this, this._onMouseOut), true);
    },

    _addZoomElementEvents: function Thumbnails_ZoomHelper$_addZoomElementEvents() {
        this._focusCatcherElement.observe('mouseover', Function.createDelegate(this, this._resetZoomTimer), true);
        this._slideNumberElement.observe('mouseover', Function.createDelegate(this, this._resetZoomTimer), true);
        this._expandCollapseElement.observe('mouseover', Function.createDelegate(this, this._resetZoomTimer), true);
        this._slideTimeElement.observe('mouseover', Function.createDelegate(this, this._resetZoomTimer), true);
        this._previewLinkElement.observe('mouseover', Function.createDelegate(this, this._resetZoomTimer), true);
        this._imageElement.observe('mouseover', Function.createDelegate(this, this._resetZoomTimer), true);
        this._zoomElement.observe('mouseout', Function.createDelegate(this, this._onMouseOut), true);
        this._focusCatcherElement.observe('click', Function.createDelegate(this, this._onImageClick));
        this._imageElement.observe('click', Function.createDelegate(this, this._onImageClick));
        this._focusCatcherElement.observe('mouseout', Function.createDelegate(this, this._onMouseOut), true);
    },

    _onImageClick: function Thumbnails_ZoomHelper$_onImageClick() {
        mPlayer.btnSlideShowInstance.OnClick();
        mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.NavigateToSlide, this, { SlideNumber: this._currentSingleSlide.get_slideNumber() });
    },

    _resetZoomTimer: function Thumbnails_ZoomHelper$_resetZoomTimer() {
        window.clearTimeout(this._hideHandle);
        this._parentArea.zoomSingleSlide(this._currentSingleSlide);
    },

    _imageOnMouseOver: function Thumbnails_ZoomHelper$_imageOnMouseOver(sender, args) {
        window.clearTimeout(this._hideHandle);
        this._parentArea.zoomSingleSlide(this._currentSingleSlide);
    },

    _createSlideNumberElement: function Thumbnails_ZoomHelper$_createSlideNumberElement() {
        this._slideNumberElement = $(document.createElement('div'));
        this._slideNumberElement.className = 'thumbNailZoomSlideNumber';
    },

    _createExpandCollapseElement: function Thumbnails_ZoomHelper$_createExpandCollapseElement() {
        this._expandCollapseElement = $(document.createElement('div'));
        SfKernel.Util.SetToolTip(this._expandCollapseElement, Localization.ThumbnailsResource.ExpandSlides);
        this._expandCollapseElement.className = 'thumbNailZoomExpandCollapseCollapsed';
        this._expandCollapseElement.observe('click', Function.createDelegate(this, this._expandCollapseOnClick));
    },

    _expandCollapseOnClick: function Thumbnails_ZoomHelper$_expandCollapseOnClick(sender, args) {
        if (this._isExpanded) {
            this._currentSingleSlide.get_group().set_isExpanded(false);
            this._parentArea.onGroupExpandCollapse();
        }
        else {
            this._currentSingleSlide.get_group().set_isExpanded(true);
            this._parentArea.onGroupExpandCollapse();
        }
    },

    _createSlideTimeElement: function Thumbnails_ZoomHelper$_createSlideTimeElement() {
        this._slideTimeElement = $(document.createElement('div'));
        this._slideTimeElement.className = 'thumbNailZoomTiming';
    },

    _createPreviewLinkElement: function Thumbnails_ZoomHelper$_createPreviewLinkElement() {
        this._previewLinkElement = $(document.createElement('div'));
        SfKernel.Util.SetToolTip(this._previewLinkElement, Localization.ThumbnailsResource.PreviewSlide);
        this._previewLinkElement.className = 'thumbNailZoomPreviewLinkOverSmall';
        this._previewLinkElement.observe('click', Function.createDelegate(this, this._previewLinkOnClick));
    },

    _previewLinkOnClick: function Thumbnails_ZoomHelper$_previewLinkOnClick(sender, args) {
        this._parentArea.showBigSlide(this._currentSingleSlide.get_slideNumber());
    },

    _onClick: function Thumbnails_ZoomHelper$_onClick(e) {
        mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.NavigateToSlide, this, { SlideNumber: this._currentSingleSlide.get_slideNumber() });
        Event.stop(e);
        window.clearTimeout(this._hideHandle);
    },

    _onMouseOver: function Thumbnails_ZoomHelper$_onMouseOver(e) {
        Event.stop(e);
        window.clearTimeout(this._hideHandle);
    },

    _onMouseOut: function Thumbnails_ZoomHelper$_onMouseOut(e) {
        Event.stop(e);
        this._hideHandle = window.setTimeout(Function.createDelegate(this, this._hide), 500);
    },

    _hide: function Thumbnails_ZoomHelper$_hide() {
        this._zoomElement.style.visibility = 'hidden';
        this._imageElement.setAttribute('src', LayoutOptions.ThemeImageBase + '/1x1.gif');
    }
}


Thumbnails.ZoomCalculator.registerClass('Thumbnails.ZoomCalculator');
Thumbnails.ZoomHelper.registerClass('Thumbnails.ZoomHelper');
Thumbnails.ZoomHelper._scrollbarWidth = 20;

////////////////////////////////////////////////////////////////////////////////
// Thumbnails.IRadioButtonGroup

Thumbnails.IRadioButtonGroup = function() { };
Thumbnails.IRadioButtonGroup.prototype = {
    selectButton: null
}
Thumbnails.IRadioButtonGroup.registerInterface('Thumbnails.IRadioButtonGroup');


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.RadioImageInfo

Thumbnails.$create_RadioImageInfo = function Thumbnails_RadioImageInfo(overImage, normalImage, checkedImage) {
    var $o = {};
    $o.overImage = overImage;
    $o.normalImage = normalImage;
    $o.checkedImage = checkedImage;
    return $o;
}


////////////////////////////////////////////////////////////////////////////////
// Thumbnails.RadioButton

Thumbnails.RadioButton = function Thumbnails_RadioButton(group, element, imageInfo, tooltip) {
    this._group = group;
    this._element = element;
    this._imageInfo = imageInfo;
    this._tooltip = tooltip;
    this._element.observe('mouseover', Function.createDelegate(this, this._onMouseOver));
    this._element.observe('mouseout', Function.createDelegate(this, this._onMouseOut));
    this._element.observe('click', Function.createDelegate(this, this._onClick));
    if (this._tooltip) {
        SfKernel.Util.SetToolTip(this._element, this._tooltip);
    }
}
Thumbnails.RadioButton.prototype = {
    _group: null,
    _element: null,
    _isChecked: false,
    _imageInfo: null,
    _tooltip: null,

    get_tooltip: function Thumbnails_RadioButton$get_tooltip() {
        return this._tooltip;
    },
    set_tooltip: function Thumbnails_RadioButton$set_tooltip(value) {
        this._tooltip = value;
        return value;
    },

    get_isChecked: function Thumbnails_RadioButton$get_isChecked() {
        return this._isChecked;
    },
    set_isChecked: function Thumbnails_RadioButton$set_isChecked(value) {
        this._isChecked = value;
        this._updateImage();
        return value;
    },

    _onClick: function Thumbnails_RadioButton$_onClick(sender, args) {
        this._group.selectButton(this);
    },

    _onMouseOver: function Thumbnails_RadioButton$_onMouseOver(sender, args) {
        if (this._isChecked) {
            return;
        }
        SfKernel.Util.SetCursor(this._element, SfKernel.CursorType.Hand);
        this._element.setAttribute('src', this._imageInfo.overImage);
    },

    _onMouseOut: function Thumbnails_RadioButton$_onMouseOut(sender, args) {
        this._updateImage();
        SfKernel.Util.SetCursor(this._element, SfKernel.CursorType.Default);
    },

    _updateImage: function Thumbnails_RadioButton$_updateImage() {
        if (this._isChecked) {
            this._element.setAttribute('src', this._imageInfo.checkedImage);
        }
        else {
            this._element.setAttribute('src', this._imageInfo.normalImage);
        }
    }
}

Thumbnails.RadioButton.registerClass('Thumbnails.RadioButton');

////////////////////////////////////////////////////////////////////////////////
// Thumbnails.ViewButtonGroup

Thumbnails.ViewButtonGroup = function Thumbnails_ViewButtonGroup(parentArea) {
    this._parentArea = parentArea;
    this._initialize();
}
Thumbnails.ViewButtonGroup.prototype = {
    _btnSlideList: null,
    _btnSmallThumbnails: null,
    _btnLargeThumbnails: null,
    _btnChapters: null,
    _parentArea: null,

    _initialize: function Thumbnails_ViewButtonGroup$_initialize() {
        this._btnSlideList = new Thumbnails.RadioButton(this, $('thumbNailViewButtonSlideList'), Thumbnails.$create_RadioImageInfo(LayoutOptions.ThemeImageBase + '/SlideSorter/btnSlideListOver.gif', LayoutOptions.ThemeImageBase + '/SlideSorter/btnSlideListNormal.gif', LayoutOptions.ThemeImageBase + '/SlideSorter/btnSlideListChecked.gif'), Localization.ThumbnailsResource.SlideList);
        this._btnSmallThumbnails = new Thumbnails.RadioButton(this, $('thumbNailViewButtonSmallThumbnails'), Thumbnails.$create_RadioImageInfo(LayoutOptions.ThemeImageBase + '/SlideSorter/btnSmallThumbOver.gif', LayoutOptions.ThemeImageBase + '/SlideSorter/btnSmallThumbNormal.gif', LayoutOptions.ThemeImageBase + '/SlideSorter/btnSmallThumbChecked.gif'), Localization.ThumbnailsResource.SmallThumbnails);
        this._btnLargeThumbnails = new Thumbnails.RadioButton(this, $('thumbNailViewButtonLargeThumbnails'), Thumbnails.$create_RadioImageInfo(LayoutOptions.ThemeImageBase + '/SlideSorter/btnLargeThumbOver.gif', LayoutOptions.ThemeImageBase + '/SlideSorter/btnLargeThumbNormal.gif', LayoutOptions.ThemeImageBase + '/SlideSorter/btnLargeThumbChecked.gif'), Localization.ThumbnailsResource.LargeThumbnails);
        this._btnSlideList.set_isChecked(false);
        this._btnSmallThumbnails.set_isChecked(false);
        this._btnLargeThumbnails.set_isChecked(true);

        if (Manifest.Chapters.length > 0) {
            this._btnChapters = new Thumbnails.RadioButton(this, $('thumbNailViewButtonChapters'), Thumbnails.$create_RadioImageInfo(LayoutOptions.ThemeImageBase + '/SlideSorter/btnChaptersOver.gif', LayoutOptions.ThemeImageBase + '/SlideSorter/btnChaptersNormal.gif', LayoutOptions.ThemeImageBase + '/SlideSorter/btnChaptersChecked.gif'), Localization.ThumbnailsResource.Chapters);
            this._btnChapters.set_isChecked(false);
        }
        else {
            $('thumbNailViewButtonChapters').style.display = 'none';
        }
        this.initializeCookieSetting();
    },

    initializeCookieSetting: function ThumbnailsArea$initializeCookieSetting() {
        var cookieValue = this._parentArea._getViewCookie();

        switch (cookieValue) {
            case 0:
                this.activateButton(this._btnSlideList);
                break;
            case 4:
                this.activateButton(this._btnSmallThumbnails);
                break;
            case 5:
                this.activateButton(this._btnLargeThumbnails);
                break;
            case 9:
                this.activateButton(this._btnChapters);
                this._parentArea.showChapters();
                break;
            default:
                this.activateButton(this._btnLargeThumbnails);
                break;
        }
    },

    activateButton: function ThumbnailsArea$activateButton(activeButton) {
        if (this._btnSlideList) { this._btnSlideList.set_isChecked(false); }
        if (this._btnSmallThumbnails) { this._btnSmallThumbnails.set_isChecked(false); }
        if (this._btnLargeThumbnails) { this._btnLargeThumbnails.set_isChecked(false); }
        if (this._btnChapters) { this._btnChapters.set_isChecked(false); }
        if (activeButton) { activeButton.set_isChecked(true); }
    },

    selectButton: function Thumbnails_ViewButtonGroup$selectButton(button) {
        this.activateButton(button);
        if (button == this._btnSlideList) {
            this._parentArea.showSlideList();
        }
        else if (button == this._btnSmallThumbnails) {
            this._parentArea.showSmallThumbnails();
        }
        else if (button == this._btnLargeThumbnails) {
            this._parentArea.showLargeThumbnails();
        }
        else if (button == this._btnChapters) {
            this._parentArea.showChapters();
        }
    }
}


Thumbnails.ViewButtonGroup.registerClass('Thumbnails.ViewButtonGroup', null, Thumbnails.IRadioButtonGroup);

/// Chapter Point Browser Panel

ChapterPointsPanel = function(container, containingWindow, id) {
    this.Container = container;
    this.ContainingWindow = containingWindow;
    this.ID = id;
    this.chaptersContainer = null;
    this.elements = null;

    this.OnLoad = function() {
        this.chaptersContainer = $(this.ID);
        this.Initialize();
    }

    this.Initialize = function() {
        this.elements = new Array(Manifest.Chapters.length);
        for (var i = 0; i < Manifest.Chapters.length; ++i) {
            this.AddChapterElement(i + 1);
            this.elements[i] = new ChapterPointElement(this, i + 1, Manifest.Chapters[i].Time);
            this.elements[i].addEvents();
        }
    }

    this.AddChapterElement = function(chapterNumber) {
        var div1 = this.createDiv('chapterDiv' + chapterNumber, 'chapterItem', null);
        this.chaptersContainer.appendChild(div1);
        var div2 = this.createDiv('chapterNumberSpan' + chapterNumber, 'chapterNumber', 'Chapter ' + chapterNumber);
        div1.appendChild(div2);
        var div3 = this.createDiv('chapterTimeSpan' + chapterNumber, 'chapterTime', SfKernel.GetDisplayDuration(Manifest.Chapters[chapterNumber - 1].Time));
        div1.appendChild(div3);
        var div4 = this.createDiv('chapterTitleSpan' + chapterNumber, 'chapterTitle', SfKernel.EncodeClean(Manifest.Chapters[chapterNumber - 1].Text));
        div4.title = SfKernel.EncodeClean(Manifest.Chapters[chapterNumber - 1].Text);
        div1.appendChild(div4);
    }

    this.createDiv = function(id, className, text) {
        var element = $(document.createElement('div'));
        element.setAttribute('id', id);
        element.className = className;
        if (text) {
            SfKernel.Util.SetText(element, text);
        }
        return element;
    }
}

ChapterPointElement = function(parentArea, chapterNumber, timing) {
    this._parentArea = parentArea;
    this._chapterNumber = chapterNumber;
    this._timing = timing;
    this._titleElement = $('chapterTitleSpan' + this._chapterNumber);
    this._chapterElement = $('chapterDiv' + this._chapterNumber);

    this.addEvents = function() {
        this._chapterElement.observe('mouseover', Function.createDelegate(this, function(sender, args) {
            this._chapterElement.className = 'chapterItemOver';
            this._titleElement.className = 'chapterTitleOver';
            SfKernel.Util.SetCursor(this._chapterElement, SfKernel.CursorType.Hand);
        }));
        this._chapterElement.observe('mouseout', Function.createDelegate(this, function(sender, args) {
            this._chapterElement.className = 'chapterItem';
            this._titleElement.className = 'chapterTitle';
            SfKernel.Util.SetCursor(this._chapterElement, SfKernel.CursorType.Default);
        }));
        this._chapterElement.observe('click', Function.createDelegate(this, function(sender, args) {
            mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.NavigateToChapter, this, { Number: this._chapterNumber, Time: this._timing });
        }));
        this._chapterElement.observe('dblclick', Function.createDelegate(this, function(sender, args) {
            mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.NavigateToChapter, this, { Number: this._chapterNumber, Time: this._timing });
            mPlayer.btnSlideShowInstance.OnClick();
        }));
    }
}
////////////////////////////////////////////////////////////////////////////////
// SpeakerInfoAnchor

SpeakerInfoAnchor = function(card, index) {
    this._card = card;
    this._index = index;
    this._element = $(this._card.ID + 'SpeakerInfoImage' + this._index);
    this._element.observe('mouseover', Function.createDelegate(this, function(sender, args) {
        this._element.setAttribute('src', this._card.ImageBase + '/presenterInfoOver.png');
    }));
    this._element.observe('mouseout', Function.createDelegate(this, function(sender, args) {
        this._element.setAttribute('src', this._card.ImageBase + '/presenterInfo.png');
    }));
    this._element.observe('mouseover', Function.createDelegate(this, function(sender, args) {
        $(this._card.ID + 'SpeakerInfoPopup' + this._index).style.display = 'block';
    }));
    $(this._card.ID + 'SpeakerInfoPopup' + this._index).observe('mouseout', Function.createDelegate(this, function(sender, args) {
        $(this._card.ID + 'SpeakerInfoPopup' + this._index).style.display = 'none';
    }));
    $(this._card.ID + 'SpeakerInfoPopup' + this._index).observe('mouseover', Function.createDelegate(this, function(sender, args) {
        $(this._card.ID + 'SpeakerInfoPopup' + this._index).style.display = 'block';
    }));
    $(this._card.ID + 'SpeakerInfoPopupInner' + this._index).observe('mouseout', Function.createDelegate(this, function(sender, args) {
        $(this._card.ID + 'SpeakerInfoPopup' + this._index).style.display = 'block';
    }));
}

SpeakerInfoAnchor.prototype = {
    _card: null,
    _index: 0,
    _element: null
}

////////////////////////////////////////////////////////////////////////////////
// PresentationCardPanel

PresentationCardPanel = function(container, containingWindow, id) {
    this.Container = container;
	this.ContainingWindow = containingWindow;
	this.ID = id;
    this._scrollDiv = $(this.ID + 'ScrollDiv');
    this._innerPadding = $(this.ID + 'InnerPadding');
    this._cardMore = $('PresentationCardAreaMore');
    this._presentersTextDiv = $(this.ID + 'PresentersText');
    
}
PresentationCardPanel.prototype= new Panel();
PresentationCardPanel.prototype.constructor=PresentationCardPanel;
PresentationCardPanel.prototype.baseClass=Panel.prototype.constructor;
PresentationCardPanel.prototype._scrollDiv=null;
PresentationCardPanel.prototype._innerPadding=null;
PresentationCardPanel.prototype._cardMore=null;
PresentationCardPanel.prototype._presentersTextDiv=null;
PresentationCardPanel.prototype._currentDimensions=null;
PresentationCardPanel.prototype._mouseoverDimensions=null;
PresentationCardPanel.prototype._isScrolling=false;
PresentationCardPanel.prototype._zIndexPrevious=0;

PresentationCardPanel.prototype.create_BoundsInt = function() { 
        return {}; 
    }
PresentationCardPanel.prototype.get_scrollDiv=function() {
        return this._scrollDiv;
    }
PresentationCardPanel.prototype.set_scrollDiv=function(value) {
        this._scrollDiv = value;
        return value;
    }

PresentationCardPanel.prototype.get_currentDimensions=function() {
        return this._currentDimensions;
    }
PresentationCardPanel.prototype.set_currentDimensions=function(value) {
        this._currentDimensions = value;
        return value;
    }

PresentationCardPanel.prototype.get_mouseoverDimensions=function() {
        return this._mouseoverDimensions;
    }
PresentationCardPanel.prototype.set_mouseoverDimensions=function(value) {
        this._mouseoverDimensions = value;
        return value;
    }    
          
PresentationCardPanel.prototype.OnLoad=function() 
{        
        this._setPresentationCardTextItem($(this.ID + 'Title'), Localization.PresentationCardResource.DefaultTitle);

        if(!LayoutOptions.HideDateTime)
        {   
            this._setPresentationCardTextItem($(this.ID + 'AirDateText'), "01/01/2000");       
            this._setPresentationCardTextItem($(this.ID + 'AirTimeText'), "12:00");
        }        
        this._setPresentationCardTextItem($(this.ID + 'DescriptionText'), Localization.PresentationCardResource.DefaultDescription);  
        this._setPresentationCardTextItem($(this.ID + 'DurationLabel'), Localization.PresentationCardResource.Duration);
        this._setPresentationCardTextItem($(this.ID + 'DurationText'), "00:00:00");
        this._setPresentationCardTextItem($(this.ID + 'More'), Localization.PresentationCardResource.More);
        this._initializeZooming();
}

PresentationCardPanel.prototype.OnDataLoad=function() 
{
        this._initializeItems();       
}
  
PresentationCardPanel.prototype._initializeItems=function() 
    {
        this._setPresentationCardTextItem($(this.ID + 'Title'), Manifest.Title);
        
        if(!LayoutOptions.HideDateTime)
        {
            this._setPresentationCardTextItem($(this.ID + 'AirDateText'), Manifest.AirDate);
            this._setPresentationCardTextItem($(this.ID + 'AirTimeText'), Manifest.AirTime);
        }
        
        if(Manifest.Duration < 1)
        {
            this._setPresentationCardTextItem($(this.ID + 'DurationLabel'), '');
            this._setPresentationCardTextItem($(this.ID + 'DurationText'), '');          
        }
        else
        {
            this._setPresentationCardTextItem($(this.ID + 'DurationText'), SfKernel.GetDisplayDuration(Manifest.Duration, true));        
        }

        
        if(Manifest.Description == null || Manifest.Description.length < 1)
        {
            this._setPresentationCardTextItem($(this.ID + 'DescriptionText'), '');  
        }
        else
        {
            this._setPresentationCardTextItem($(this.ID + 'DescriptionText'), Manifest.Description);  
        }
        
        this._initializeSpeakers();
    }
    
PresentationCardPanel.prototype._setPresentationCardTextItem=function(element, text) 
    {
        if(text != null)
        {
            element.innerHTML=SfKernel.EncodeHTML(text);
        }
        else
        {
            element.innerHTML="";
        }
    }
    
PresentationCardPanel.prototype._initializeZooming=function() {
        this._currentDimensions = this.create_BoundsInt();
        this._currentDimensions.Top = window.parseInt(this.GetDiv().style.top);
        this._currentDimensions.Left = window.parseInt(this.GetDiv().style.left);
        this._currentDimensions.Width = window.parseInt(this.GetDiv().style.width);
        this._currentDimensions.Height = window.parseInt(this.GetDiv().style.height);
        this._mouseoverDimensions = this.create_BoundsInt();
        this._mouseoverDimensions.Width = window.parseInt(this.Mouseover_Width);
        this._mouseoverDimensions.Height = window.parseInt(this.Mouseover_Height);
        this._cardMore.observe('click', Function.createDelegate(this, this._toggleScrolling));
        this._cardMore.observe('mouseover', Function.createDelegate(this, this._moreMouseover));
        this._cardMore.observe('mouseout', Function.createDelegate(this, this._moreMouseout));
        var strZIndex = this.GetDiv();
        
        strZIndex=strZIndex.style.zIndex;
        if (!strZIndex) {
            this._zIndexPrevious = 0;
        }
        else {
            this._zIndexPrevious = window.parseInt(strZIndex);
        }        
    }
    
    PresentationCardPanel.prototype._moreMouseover=function(sender, args) {
        // more button mouseover
        // change css class to mouseover version
    }
    
    PresentationCardPanel.prototype._moreMouseout=function(sender, args) {
        // more button mouseout
        // change css class to normal version
    }
    
    PresentationCardPanel.prototype._enableScrolling=function() {
        this._scrollDiv.style.overflowY = 'scroll';
        this._scrollDiv.style.overflowX = 'hidden';
    }
    
    PresentationCardPanel.prototype._disableScrolling=function() {
        this._scrollDiv.style.overflow = 'hidden';
        this._scrollDiv.style.overflowY = 'hidden';
        this._scrollDiv.style.overflowX = 'hidden';
    }
    
    PresentationCardPanel.prototype._toggleScrolling=function(sender, args) {
        if (this._scrollDiv.style.overflow == 'scroll' || this._scrollDiv.style.overflowY == 'scroll' ) {
            this._disableScrolling();
        }
        else {
            this._enableScrolling();
        }
    }

    PresentationCardPanel.prototype._initializeSpeakerPopups = function() {

        var len = Manifest.Presenters.length;
        for (var i = 0; i < len; ++i) {
            if (Manifest.Presenters[i].ImageUrl.length > 0) {
                new SpeakerInfoAnchor(this, i + 1);
            }
        }

        if (LayoutOptions) {
            var isCompact = (LayoutOptions.VideoWidth == '400' && LayoutOptions.SlideWidth == '360');
            if (LayoutOptions.DefaultPosition == 3 || LayoutOptions.DefaultPosition == 4 || isCompact) {
                var presenterPopupElements = $$('.speakerInfoPopupContainer');
                var presenterPopupInnerElements = $$('.speakerInfoPopup');
                var presenterPopupArrowElements = $$('.speakerInfoPopupArrow');
                for (var j = 0; j < presenterPopupElements.length; j++) {
                    $(presenterPopupElements[j]).className = 'speakerInfoPopupContainerDown';
                }
                for (var k = 0; k < presenterPopupInnerElements.length; k++) {
                    $(presenterPopupInnerElements[k]).className = 'speakerInfoPopupDown';
                }
                for (var l = 0; l < presenterPopupArrowElements.length; l++) {
                    $(presenterPopupArrowElements[l]).className = 'speakerInfoPopupArrowDown';
                }
            }
        }

    }
    
PresentationCardPanel.prototype._initializeSpeakers=function() {
        if(Manifest.Presenters.length < 1)
        {
            return;
        }
        
        this._addAllSpeakerNamesEtc();
        this._initializeSpeakerPopups();
    }

    PresentationCardPanel.prototype._addAllSpeakerNamesEtc = function() {
        var len = Manifest.Presenters.length;
        if (!len) {
            return;
        }
        for (var i = 1; i < len; ++i) {
            this._addSpeakerNameEtc(i, Manifest.Presenters[i - 1]);
        }
        this._addSpeakerNameEtc(len, Manifest.Presenters[len - 1]);
    }

    PresentationCardPanel.prototype._addSpeakerNameEtc = function(index, presenter) {
        var speakerElement = $(document.createElement('div'));
        speakerElement.setAttribute('id', this.ID + 'SpeakerInfoElement' + index);
        if (presenter.ImageUrl) {
            var imageElement = $(document.createElement('img'));
            imageElement.setAttribute('id', this.ID + 'SpeakerInfoImage' + index);
            imageElement.setAttribute('src', this.ImageBase + '/presenterInfo.png');
            imageElement.className = 'cardPresenterInfoImage';
            this._addSpeakerInfoPopup(speakerElement, index, presenter);
            speakerElement.appendChild(imageElement);
        }

        if (presenter.BioUrl.length > 0) {
            var a = $(document.createElement('a'));
            speakerElement.appendChild(a);
            a.setAttribute('href', presenter.BioUrl);
            a.setAttribute('target', '_blank');
            a.appendChild(document.createTextNode(presenter.Name));
        }
        else {
            speakerElement.appendChild(document.createTextNode(presenter.Name));
        }
        this._presentersTextDiv.appendChild(speakerElement);
    }
    
    PresentationCardPanel.prototype._addSpeakerInfoPopups=function() {
        var len = Manifest.Presenters.length;
        for (var i = 0; i < len; ++i) {
            this._addSpeakerInfoPopup(i + 1, Manifest.Presenters[i]);
        }
    }

    PresentationCardPanel.prototype._addSpeakerInfoPopup = function(speakerElement, index, presenter) {
    var element = $(document.createElement('div'));
        speakerElement.appendChild(element);
        element.setAttribute('id', this.ID + 'SpeakerInfoPopup' + index);
        element.setStyle({ display: 'none', position: 'absolute' });
        element.className = 'speakerInfoPopupContainer';

        var arrowElement = $(document.createElement('div'));
        arrowElement.setAttribute('id', this.ID + 'SpeakerInfoPopupArrow' + index);
        arrowElement.className = 'speakerInfoPopupArrow';
        element.appendChild(arrowElement);

        var innerElement = $(document.createElement('div'));
        innerElement.setAttribute('id', this.ID + 'SpeakerInfoPopupInner' + index);
        innerElement.className = 'speakerInfoPopup';
        element.appendChild(innerElement);

        var imageContainer = $(document.createElement('div'));
        innerElement.appendChild(imageContainer);
        imageContainer.className = 'speakerInfoPopupImageContainer';

        if (presenter.ImageUrl.length > 0) {
            var imageElement = $(document.createElement('img'));
            imageElement.setAttribute('src', this._getSpeakerImageSrc(presenter));
            imageElement.className = 'speakerInfoPopupImage';
            imageElement.style.display = 'block';

            if (presenter.BioUrl.length > 0) {
                var a = $(document.createElement('a'));
                this._presentersTextDiv.appendChild(a);
                a.setAttribute('href', presenter.BioUrl);
                a.setAttribute('target', '_blank');
                a.appendChild(imageElement);
                imageContainer.appendChild(a);
            }
            else {
                imageContainer.appendChild(imageElement);
            }
        }
    }
    
PresentationCardPanel.prototype._getSpeakerImageSrc=function(presenter) {
        return presenter.ImageUrl;
    }
    
PresentationCardPanel.prototype.OnUnLoad=function() {
    }



MediasitePlayer = function() { }

MediasitePlayer.prototype = {
    _type: 0,
    _element: null,

    CurrentSlideNumber: -1,
    CurrentFullSizeImage: null,
    DynamicAdd: false,
    PresentationEnded: false,
    IsPreview: false,
    OpenReported: false,
    ShowSlides: true,
    ImageFileType: '.png',
    LegacyThemeName: 'Mediasite for IE6',

    DefaultPopupWindowWidth: 1024,
    DefaultPopupWindowHeight: 768,

    OnBodyLoad: function() {
        if (!this.IsPreview) {
            this.LoadMediaPlayer();
        }
        else {
            $('PlayerSpeedControl').style.display = 'none';
            $('btnFullScreen').style.display = 'none';
        }
        $('PlayerMask').style.display = 'none';
    },

    OnLoad: function() {
        this.PlayerDetect = new SfKernel.PlayerDetect();
        loadingMask('loadingImage', 10, 10);

        var playerMode = SfKernel.GetQueryStringValue("mode");
        if (playerMode != null && playerMode.toLowerCase() == "skinpreview") {
            this.IsPreview = true;
        }
        if (LayoutOptions.SlideHeight == 0 || LayoutOptions.SlideWidth == 0) {
            this.ShowSlides = false;
        }

        LayoutOptions.OnLoad();

        this.LoadThemeStylesheet();
        this.BrowserHacks();
        this.ResizeWindow();


        var BannerLoaderInstance = new LoadBanners();

        BannerLoaderInstance.Banner = new Array('AdBanner', 'TitleBanner');
        if (LayoutOptions.Images["VendorLogo"]) {
            if (!$('VendorLogo')) {
                var contentElement = $('MediasitePlayerForm');
                var vendorLogoContainer = document.createElement('div');
                vendorLogoContainer.setAttribute('id', 'VendorLogo');
                vendorLogoContainer.setAttribute('height', LayoutOptions.Images["VendorLogo"].Height);
                vendorLogoContainer.setAttribute('width', LayoutOptions.Images["VendorLogo"].Width);
                contentElement.appendChild(vendorLogoContainer);
            }
            BannerLoaderInstance.Banner = new Array('AdBanner', 'TitleBanner', 'VendorLogo');
        }
        BannerLoaderInstance.OnLoad();

        var PlayerNotStartedImageInstance = new SkinImage('PlayerNotStarted');
        PlayerNotStartedImageInstance.ImageSRC = LayoutOptions.Images['PlayerNotStarted'].ImageFilename;
        PlayerNotStartedImageInstance.ImageHref = LayoutOptions.Images['PlayerNotStarted'].ImageUrl;
        PlayerNotStartedImageInstance.ImageHeight = LayoutOptions.Images['PlayerNotStarted'].Height;
        PlayerNotStartedImageInstance.ImageWidth = LayoutOptions.Images['PlayerNotStarted'].Width;
        PlayerNotStartedImageInstance.Alt = Localization.PlayerLayoutResource.NotStarted;
        PlayerNotStartedImageInstance.OnLoad();

        if (LayoutOptions.Images['PlayerAudioOnly']) {
            var AudioOnlyImageInstance = new SkinImage('PlayerAudioOnly');
            AudioOnlyImageInstance.ImageSRC = LayoutOptions.Images['PlayerAudioOnly'].ImageFilename;
            AudioOnlyImageInstance.ImageHref = LayoutOptions.Images['PlayerAudioOnly'].ImageUrl;
            AudioOnlyImageInstance.ImageHeight = LayoutOptions.Images['PlayerAudioOnly'].Height;
            AudioOnlyImageInstance.ImageWidth = LayoutOptions.Images['PlayerAudioOnly'].Width;
            AudioOnlyImageInstance.Alt = Localization.PlayerLayoutResource.AudioOnly;
            AudioOnlyImageInstance.OnLoad();
        }

        this.EventManager = new EventManager();
        this.OptionsManager = new OptionsManager();

        this.PopupWindows = new Object();
        this.PopupWindows.FullSize = null;
        this.PopupWindows.PreviewSlide = null;
        this.PopupWindows.Polls = null;

        this.presentationCard = new PresentationCardPanel("PresentationCardPanelInstance", window, "PresentationCardArea");
        this.presentationCard.ImageBase = LayoutOptions.ThemeImageBase + '/PresentationCard';
        this.presentationCard.ToolTipExpand = Localization.Common.Expand;
        this.presentationCard.ToolTipCollapse = Localization.Common.Collapse;
        this.presentationCard.AllowZooming = true;
        this.presentationCard.Mouseover_Width = "50px";
        this.presentationCard.Mouseover_Height = "65px";
        this.presentationCard.OnLoad();

        if ($('btnAskButton')) {
            this.btnAskInstance = new AskButtonPanel();
            this.btnAskInstance.button = new SfUI.Button('btnAskButton');
            this.btnAskInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnAskNormal' + this.ImageFileType);
            this.btnAskInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnAskOver' + this.ImageFileType);
            this.btnAskInstance.button.SetPressedImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnAskPressed' + this.ImageFileType);
            this.btnAskInstance.button.SetDisabledImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnAskDisabled' + this.ImageFileType);
            this.btnAskInstance.button.Enable(false);
            this.btnAskInstance.OnLoad();
        }
        if ($('btnLinks')) {
            this.btnLinksInstance = new LinksButtonPanel();
            this.btnLinksInstance.button = new SfUI.Button('btnLinks');
            this.btnLinksInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnLinksNormal' + this.ImageFileType);
            this.btnLinksInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnLinksOver' + this.ImageFileType);
            this.btnLinksInstance.button.SetDisabledImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnLinksDisabled' + this.ImageFileType);
            this.btnLinksInstance.button.Enable(false);
            this.btnLinksInstance.OnLoad();
        }
        if ($('btnPoll')) {
            this.btnPollInstance = new PollButtonPanel();
            this.btnPollInstance.button = new SfUI.Button('btnPoll');
            this.btnPollInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnPollResultsNormal' + this.ImageFileType);
            this.btnPollInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnPollResultsOver' + this.ImageFileType);
            this.btnPollInstance.button.SetPressedImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnPollResultsPressed' + this.ImageFileType);
            this.btnPollInstance.button.SetDisabledImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnPollResultsDisabled' + this.ImageFileType);
            this.btnPollInstance.button.Enable(false);
            this.btnPollInstance.OnLoad();
        }
        if ($('btnEmail')) {
            this.btnEmailInstance = new EmailButtonArea();
            this.btnEmailInstance.button = new SfUI.Button('btnEmail');
            this.btnEmailInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnEmailNormal' + this.ImageFileType);
            this.btnEmailInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnEmailOver' + this.ImageFileType);
            this.btnEmailInstance.button.SetDisabledImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnEmailDisabled' + this.ImageFileType);
            this.btnEmailInstance.button.Enable(false);
            this.btnEmailInstance.OnLoad();
        }
        if ($('btnChapters')) {
            if (LayoutOptions.SlideWidth == 0 && LayoutOptions.SlideHeight == 0) {
                this.btnChaptersInstance = new ChaptersButtonArea();
                this.btnChaptersInstance.button = new SfUI.Button('btnChapters');
                this.btnChaptersInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/Player/Buttons/btnChapNormal' + this.ImageFileType);
                this.btnChaptersInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/Player/Buttons/btnChapOver' + this.ImageFileType);
                this.btnChaptersInstance.button.SetDisabledImage(0, LayoutOptions.ThemeImageBase + '/Player/Buttons/btnChapDisabled' + this.ImageFileType);
                this.btnChaptersInstance.button.Enable(false);
                this.btnChaptersInstance.OnLoad();
            }
        }
        if ($('btnHelp')) {
            this.btnHelpInstance = new HelpButtonArea();
            this.btnHelpInstance.button = new SfUI.Button('btnHelp');
            this.btnHelpInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnHelpNormal' + this.ImageFileType);
            this.btnHelpInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnHelpOver' + this.ImageFileType);
            this.btnHelpInstance.button.SetPressedImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnHelpPressed' + this.ImageFileType);
            this.btnHelpInstance.button.SetDisabledImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnHelpDisabled' + this.ImageFileType);
            this.btnHelpInstance.button.Enable(false);
            this.btnHelpInstance.OnLoad();
        }
        if ($('SlideTicker') && this.ShowSlides) {
            this.btnPreviousSlideInstance = new PreviousSlideButtonArea('btnPreviousSlideInstance');
            this.btnPreviousSlideInstance.button = new SfUI.Button('btnPreviousSlide');
            this.btnPreviousSlideInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnPrevNormal' + this.ImageFileType);
            this.btnPreviousSlideInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnPrevOver' + this.ImageFileType);
            this.btnPreviousSlideInstance.button.SetPressedImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnPrevPressed' + this.ImageFileType);
            this.btnPreviousSlideInstance.button.SetDisabledImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnPrevDisabled' + this.ImageFileType);
            this.btnPreviousSlideInstance.OnLoad();

            this.btnNextSlideInstance = new NextSlideButtonArea('btnNextSlideInstance');
            this.btnNextSlideInstance.button = new SfUI.Button('btnNextSlide');
            this.btnNextSlideInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnNextNormal' + this.ImageFileType);
            this.btnNextSlideInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnNextOver' + this.ImageFileType);
            this.btnNextSlideInstance.button.SetPressedImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnNextPressed' + this.ImageFileType);
            this.btnNextSlideInstance.button.SetDisabledImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnNextDisabled' + this.ImageFileType);
            this.btnNextSlideInstance.OnLoad();

            this.SlideNumberPanelInstance = new SlideNumberPanel("SlideNumberPanelInstance", window, "SlideNumberArea");
            this.SlideNumberPanelInstance.SlideText = Localization.Common.Slide;
            this.SlideNumberPanelInstance.OfText = Localization.Common.Of;
            this.SlideNumberPanelInstance.DefaultText = ' ';
        }

        if ($('SlideTabs')) {
            this.btnSlideShowInstance = new SlideShowButtonArea('btnSlideShow');
            this.btnSlideShowInstance.button = new SfUI.Button('btnSlideShow');
            this.btnSlideShowInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnSlideShowNormal' + this.ImageFileType);
            this.btnSlideShowInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnSlideShowOver' + this.ImageFileType);
            this.btnSlideShowInstance.button.SetButtonType(SfUI.ButtonType.Check);
            this.btnSlideShowInstance.button.SetChecked(true);
            this.btnSlideShowInstance.button.SetNormalImage(1, LayoutOptions.ThemeImageBase + '/CommandBar/btnSlideShowCheckedNormal' + this.ImageFileType);
            this.btnSlideShowInstance.button.SetOverImage(1, LayoutOptions.ThemeImageBase + '/CommandBar/btnSlideShowCheckedOver' + this.ImageFileType);
            this.btnSlideShowInstance.Enabled = true;
            this.btnSlideShowInstance.TooltipId = Localization.Common.SlideShow;
            this.btnSlideShowInstance.ControlArea = $('CurrentSlideArea');
            this.btnSlideShowInstance.OnLoad();

            this.btnSlideListInstance = new SlideShowButtonArea('btnSlideList');
            this.btnSlideListInstance.button = new SfUI.Button('btnSlideList');
            this.btnSlideListInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnSlideNavNormal' + this.ImageFileType);
            this.btnSlideListInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/CommandBar/btnSlideNavOver' + this.ImageFileType);
            this.btnSlideListInstance.button.SetButtonType(SfUI.ButtonType.Check);
            this.btnSlideListInstance.button.SetChecked(false);
            this.btnSlideListInstance.button.SetNormalImage(1, LayoutOptions.ThemeImageBase + '/CommandBar/btnSlideNavCheckedNormal' + this.ImageFileType);
            this.btnSlideListInstance.button.SetOverImage(1, LayoutOptions.ThemeImageBase + '/CommandBar/btnSlideNavCheckedOver' + this.ImageFileType);
            this.btnSlideListInstance.Enabled = true;
            this.btnSlideListInstance.TooltipId = Localization.Common.SlideList;
            this.btnSlideListInstance.ControlArea = $('CurrentSlideArea');
            this.btnSlideListInstance.OnLoad();
        }

        if ($('StatusBar')) {
            this.PlayerStatusPanelInstance = new PlayerStatusPanel("PlayerStatusPanelInstance", window, "PlayerStatusArea");
            this.PlayerStatusPanelInstance.OnLoad();

            this.PlayerPositionPanelInstance = new PlayerPositionPanel("PlayerPositionPanelInstance", window, "PlayerPositionArea");
            this.PlayerPositionPanelInstance.OnLoad();
        }

        if ($('PlayerControls')) {
            this.btnPlayPauseInstance = new PlayPauseButtonArea("btnPlayPauseInstance", window, "btnPlayPause");
            this.btnPlayPauseInstance.button = new PlayPauseButton("btnPlayPause", "mPlayer.btnPlayPauseInstance");
            this.btnPlayPauseInstance.button.PlayImageDetails.Over = LayoutOptions.ThemeImageBase + '/Player/Buttons/btnPlayOver' + this.ImageFileType;
            this.btnPlayPauseInstance.button.PlayImageDetails.Normal = LayoutOptions.ThemeImageBase + '/Player/Buttons/btnPlayNormal' + this.ImageFileType;
            this.btnPlayPauseInstance.button.PlayImageDetails.Disabled = LayoutOptions.ThemeImageBase + '/Player/Buttons/btnPlayDisabled' + this.ImageFileType;
            this.btnPlayPauseInstance.button.PauseImageDetails.Over = LayoutOptions.ThemeImageBase + '/Player/Buttons/btnPauseOver' + this.ImageFileType;
            this.btnPlayPauseInstance.button.PauseImageDetails.Normal = LayoutOptions.ThemeImageBase + '/Player/Buttons/btnPauseNormal' + this.ImageFileType;
            this.btnPlayPauseInstance.button.PauseImageDetails.Disabled = LayoutOptions.ThemeImageBase + '/Player/Buttons/btnPauseDisabled' + this.ImageFileType;
            this.btnPlayPauseInstance.button.StopImageDetails.Over = LayoutOptions.ThemeImageBase + '/Player/Buttons/btnStopOver' + this.ImageFileType;
            this.btnPlayPauseInstance.button.StopImageDetails.Normal = LayoutOptions.ThemeImageBase + '/Player/Buttons/btnStopNormal' + this.ImageFileType;
            this.btnPlayPauseInstance.button.StopImageDetails.Disabled = LayoutOptions.ThemeImageBase + '/Player/Buttons/btnStopDisabled' + this.ImageFileType;
            this.btnPlayPauseInstance.button.ToolTipPlay = Localization.Buttons.Play;
            this.btnPlayPauseInstance.button.ToolTipPause = Localization.Buttons.Pause;
            this.btnPlayPauseInstance.button.ToolTipStop = Localization.Buttons.Stop;
            this.btnPlayPauseInstance.button.IsEnabled = false;
            this.btnPlayPauseInstance.OnLoad();

            this.btnSkipbackInstance = new SkipbackButtonArea("btnSkipbackInstance", window, "btnSkipback");
            this.btnSkipbackInstance.button = new SfUI.Button('btnSkipback');
            this.btnSkipbackInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/Player/Buttons/btnSkipbackNormal' + this.ImageFileType);
            this.btnSkipbackInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/Player/Buttons/btnSkipbackOver' + this.ImageFileType);
            this.btnSkipbackInstance.button.SetDisabledImage(0, LayoutOptions.ThemeImageBase + '/Player/Buttons/btnSkipbackDisabled' + this.ImageFileType);
            this.btnSkipbackInstance.button.Enable(false);
            this.btnSkipbackInstance.OnLoad();

            this.btnMuteInstance = new MuteButtonArea("btnMuteInstance", window, "btnMute");
            this.btnMuteInstance.button = new SfUI.Button('btnMute');
            this.btnMuteInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/Player/Volume/btnMuteNormal' + this.ImageFileType);
            this.btnMuteInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/Player/Volume/btnMuteOver' + this.ImageFileType);
            this.btnMuteInstance.button.SetDisabledImage(0, LayoutOptions.ThemeImageBase + '/Player/Volume/btnMuteDisabled' + this.ImageFileType);
            this.btnMuteInstance.button.SetButtonType(SfUI.ButtonType.Check);
            this.btnMuteInstance.button.SetNormalImage(1, LayoutOptions.ThemeImageBase + '/Player/Volume/btnMuteCheckedNormal' + this.ImageFileType);
            this.btnMuteInstance.button.SetOverImage(1, LayoutOptions.ThemeImageBase + '/Player/Volume/btnMuteCheckedOver' + this.ImageFileType);
            this.btnMuteInstance.button.Enable(false);
            this.btnMuteInstance.OnLoad();

            this.btnFullScreenInstance = new FullScreenButtonArea("btnFullScreenInstance", window, "btnFullScreen");
            this.btnFullScreenInstance.button = new SfUI.Button('btnFullScreen');
            this.btnFullScreenInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/Player/Buttons/btnFullScreenNormal' + this.ImageFileType);
            this.btnFullScreenInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/Player/Buttons/btnFullScreenOver' + this.ImageFileType);
            this.btnFullScreenInstance.button.SetDisabledImage(0, LayoutOptions.ThemeImageBase + '/Player/Buttons/btnFullScreenDisabled' + this.ImageFileType);
            this.btnFullScreenInstance.button.Enable(false);
            this.btnFullScreenInstance.OnLoad();
        }

        if ($('CurrentSlideArea') && this.ShowSlides) {
            this.CurrentSlidePanelInstance = new CurrentSlidePanel("mPlayer.CurrentSlidePanelInstance", window, "CurrentSlideArea");
            this.CurrentSlidePanelInstance.ViewportWidth = Math.floor(LayoutOptions.SlideWidth / 3);
            this.CurrentSlidePanelInstance.ViewportHeight = Math.floor(LayoutOptions.SlideHeight / 3);
            this.CurrentSlidePanelInstance.OnLoad();
        }

        if (LayoutOptions.SlideWidth == 0 && LayoutOptions.SlideHeight == 0) {
            if ($('btnChapters')) {$('btnChapters').style.display = 'block';}
            this.CreateChapterDialog();
        }
        ChangePosition.OnLoad();
        $('btnCC').style.display = 'none';

        if (!this.IsPreview) {
            this.OnDataLoad();
        }
    },

    OnDataLoad: function() {
        Manifest.OnLoad();

        if (this.btnChaptersInstance) {
            this.btnChaptersInstance.OnDataLoad();

            this.ChaptersPanel = new ChaptersPanel("mPlayer.ChaptersPanel", window, "ChapterPointsPanelDialog");
            this.ChaptersPanel.ID = "ChapterPointsPanelDialog";
            this.ChaptersPanel.OnLoad();
        }

        if (Manifest.CaptionsFile.length > 0) {
            document.writeln('<script src="' + Manifest.CaptionsFile + '" type="text/javascript"></script>');
        }

        $('ApplicationVersionArea').title = 'Mediasite ' + Manifest.Version;

        if (this.presentationCard) {
            this.presentationCard.OnDataLoad();
        }

        if (this.btnAskInstance) {
            this.btnAskInstance.OnDataLoad();
        }
        if (this.btnPollInstance) {
            this.btnPollInstance.OnDataLoad();
        }
        if (this.btnEmailInstance) {
            this.btnEmailInstance.OnDataLoad();
        }
        if (this.btnLinksInstance) {
            this.btnLinksInstance.OnDataLoad();

            this.LinksPanel = new LinksPanel("mPlayer.LinksPanel", window, "LinksPanel");
            this.LinksPanel.ID = "LinksPanel";
            this.LinksPanel.OnLoad();
        }

        if ($('SlideTabs')) {
            this.btnSlideShowInstance.OnDataLoad();
            this.btnSlideListInstance.OnDataLoad();
        }

        if ($('SlideTicker') && this.ShowSlides) {
            this.btnPreviousSlideInstance.OnDataLoad();
            this.btnNextSlideInstance.OnDataLoad();

            this.SlideNumberPanelInstance.OnDataLoad();
        }

        if ($('CurrentSlideArea') && this.ShowSlides) {
            this.CurrentSlidePanelInstance.OnDataLoad();

            this.ThumbnailsPanelInstance = new ThumbnailsPanel("mPlayer.ThumbnailsPanelInstance", window, "ThumbNailsArea");
            this.ThumbnailsPanelInstance.OnLoad();

            this.ChapterPointsPanelInstance = new ChapterPointsPanel("mPlayer.ChapterPointsPanelInstance", window, "ChapterPointsArea");
            this.ChapterPointsPanelInstance.OnLoad();
        }

        if ($('PlayerControls')) {
            this.btnPlayPauseInstance.OnDataLoad();
            this.btnSkipbackInstance.OnDataLoad();
            this.btnMuteInstance.OnDataLoad();
            this.btnFullScreenInstance.OnDataLoad();
            this.btnHelpInstance.OnDataLoad();

            this.PlayerSliderInstance = new SliderArea("mPlayer.PlayerSliderInstance", window, "PlayerSlider");
            this.PlayerSliderInstance.Orientation = SfUI.SfSlider.Orientation.Horizontal;
            this.PlayerSliderInstance.SliderBackgroundImage = LayoutOptions.ThemeImageBase + '/Player/slider_bkg' + this.ImageFileType;
            this.PlayerSliderInstance.ThumbImage = LayoutOptions.ThemeImageBase + '/Player/thumb' + this.ImageFileType;
            this.PlayerSliderInstance.ThumbOverImage = LayoutOptions.ThemeImageBase + '/Player/thumbOver' + this.ImageFileType;

            this.VolumeSliderInstance = new VolumeSliderArea("mPlayer.VolumeSliderInstance", window, "VolumeSlider");
            this.VolumeSliderInstance.Orientation = SfUI.SfSlider.Orientation.Horizontal;
            this.VolumeSliderInstance.SliderBackgroundImage = LayoutOptions.ThemeImageBase + '/Player/Volume/slider_bkg' + this.ImageFileType;
            this.VolumeSliderInstance.ThumbImage = LayoutOptions.ThemeImageBase + '/Player/Volume/thumb' + this.ImageFileType;
            this.VolumeSliderInstance.ThumbOverImage = LayoutOptions.ThemeImageBase + '/Player/Volume/thumbOver' + this.ImageFileType;
        }

        if ($('LanguageSelectionArea')) {
            this.LanguageSelectionAreaInstance = new LanguageDropDownArea("mPlayer.LanguageSelectionAreaInstance", window, "LanguageSelectionArea");
            this.LanguageSelectionAreaInstance.OnLoad();
        }

        if ($('CaptioningContainer')) {
            this.SamiDropDownPanelInstance = new SamiDropDownPanel("mPlayer.SamiDropDownPanelInstance", window, "Captioning");
            this.SamiDropDownPanelInstance.OnLoad();
        }

        if (Manifest.CaptionsFile.length > 0) {
            this.btnCCInstance = new CCButtonArea("btnCCInstance", window, "btnCC");
            this.btnCCInstance.button = new SfUI.Button('btnCC');
            this.btnCCInstance.button.SetNormalImage(0, LayoutOptions.ThemeImageBase + '/Player/Captioning/btnCCNormal' + this.ImageFileType);
            this.btnCCInstance.button.SetOverImage(0, LayoutOptions.ThemeImageBase + '/Player/Captioning/btnCCOver' + this.ImageFileType);
            this.btnCCInstance.button.SetDisabledImage(0, LayoutOptions.ThemeImageBase + '/Player/Captioning/btnCCDisabled' + this.ImageFileType);
            this.btnCCInstance.button.Enable(true);
            this.btnCCInstance.OnLoad();
        }


        window.onbeforeunload = this.OnBeforeUnload;

        document.onkeyup = this.OnKeyUp;
    },

    OnBeforeUnload: function() {
        if (mPlayer.OpenReported) {
            mPlayer.ReportViewerPageClosed();
        }

        if (mPlayer.PopupWindows.FullSize) {
            mPlayer.PopupWindows.FullSize.close();
        }

        if (mPlayer.PopupWindows.PreviewSlide) {
            mPlayer.PopupWindows.PreviewSlide.close();
        }

        if (mPlayer.PopupWindows.Polls) {
            mPlayer.PopupWindows.Polls.close();
        }
    },

    LoadMediaPlayer: function() {
        if (this.PlayerDetect.GetPlayerType() == SfKernel.MediaPlayerType.SL1) {
            this.PlayerAreaInstance = new SL1PlayerArea("mPlayer.PlayerAreaInstance", window, "PlayerArea");

            $('PlayerSpeedControl').style.display = 'none';
            $('btnFullScreen').style.display = 'none';
        }
        else {
            this.PlayerAreaInstance = new WM7PlayerArea("mPlayer.PlayerAreaInstance", window, "PlayerArea");

            this.PlayerSpeedControlInstance = new PlayerSpeedControlPanel("mPlayer.PlayerSpeedControlInstance", window, "PlayerSpeedControl");
            this.PlayerSpeedControlInstance.OnLoad();
        }

        this.PlayerAreaInstance.OnLoad();
    },

    OnKeyUp: function(e) {
        if (SfEmailIsShowing || SfForumIsShowing || mPlayer.LinksPanel.IsShowing) {
            return;
        }

        var keyEvent = (window.event) ? event : e;

        if (Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand) {
            switch (keyEvent.keyCode) {
                case 32: //Space
                    mPlayer.btnPlayPauseInstance.OnClick();
                    break;
                case 37: // left arrow
                    if (keyEvent.ctrlKey) {
                        if (mPlayer.btnPreviousSlideInstance) {
                            mPlayer.btnPreviousSlideInstance.OnClick();
                        }
                    }
                    else {
                        mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.SkipBack, this, null);
                    }
                    break;
                case 38:  // up arrow
                    if (mPlayer.PlayerSpeedControlInstance) {
                        mPlayer.PlayerSpeedControlInstance._rightDivOnClick$1();
                    }
                    break;
                case 39:  // right arrow
                    if (keyEvent.ctrlKey) {
                        if (mPlayer.btnNextSlideInstance) {
                            mPlayer.btnNextSlideInstance.OnClick();
                        }
                    }
                    else {
                        mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.SkipForward, this, null);
                    }
                    break;
                case 40:  // down arrow
                    if (mPlayer.PlayerSpeedControlInstance) {
                        mPlayer.PlayerSpeedControlInstance._leftDivOnClick$1();
                    }
                    break;
            }
        }

        switch (keyEvent.keyCode) {
            case 65:  //A
                mPlayer.btnAskInstance.OnClick();
                break;
            case 69:  //E
                mPlayer.btnEmailInstance.OnClick();
                break;
            case 76:  //L
                mPlayer.btnLinksInstance.OnClick();
                break;
            case 77:  //M
                mPlayer.btnMuteInstance.OnClick();
                break;
            case 80:  //P
                mPlayer.btnPollInstance.OnClick();
                break;
            case 83:  //S
                if (LayoutOptions.SlideHeight != 0 && LayoutOptions.SlideWidth != 0) {
                    if (keyEvent.shiftKey) {
                        if (mPlayer.CurrentSlidePanelInstance) {
                            mPlayer.CurrentSlidePanelInstance._toolbuttonController$1.ToggleSlideDescriptions();
                        }
                    }
                    else if (mPlayer.btnSlideListInstance && mPlayer.btnSlideShowInstance) {
                        if (mPlayer.btnSlideListInstance.button.GetChecked()) {
                            mPlayer.btnSlideShowInstance.OnClick();
                        }
                        else {
                            mPlayer.btnSlideListInstance.OnClick();
                        }
                    }
                }
                break;
            case 112: //F1
                mPlayer.btnHelpInstance.OnClick();
                break;
        }
    },

    LoadAudioLanguages: function(Languages, CurrentIndex) {
        if (this.LanguageSelectionAreaInstance) {
            this.LanguageSelectionAreaInstance.LoadLanguages(Languages, CurrentIndex);
        }
    },

    LoadThemeStylesheet: function() {
        var theme = LayoutOptions.ThemeId;
        // override theme for transparency compatibility on MSIE6.

        if (this.PlayerDetect.IsInternetExplorer6()) {
            var isStandAlone = false;
            try {
                isStandAlone = Manifest.IsStandAlone;
            }
            catch (error) { }

            if (!isStandAlone) {
                LayoutOptions.ThemeImageBase = LayoutOptions.ThemeImageBase.replace("/App_Themes/" + theme + "/Images", "/App_Themes/" + this.LegacyThemeName + "/Images");
                theme = this.LegacyThemeName;
            }
        }

        if (theme == this.LegacyThemeName) {
            this.ImageFileType = '.gif';
        }
        else {
            this.ImageFileType = '.png';
        }

        var href = GlobalOptions.AppRoot + '/App_Themes/' + theme + '/Images.css';
        document.writeln("<link id='themeStylesheet' rel='stylesheet' type='text/css' href='" + href + "'//>");
    },

    BrowserHacks: function() {
        // Firefox On Mac
        if (this.PlayerDetect.IsMac() && this.PlayerDetect.IsFirefox() && $('PresentationCardArea') != null) {
            // opacity used with overflow:hidden hides Silverlight video on Mac/Firefox
            $('PresentationCardArea').style.opacity = 1;
            $('PresentationCardArea').style.MozOpacity = 1;
        }
    },

    CreateChapterDialog: function() {
        var contentElement = $('PresentationCardArea');
        var chapterElement = document.createElement('div');
        chapterElement.setAttribute('id', 'ChapterPointsPanelDialog');
        chapterElement.className = 'dialogFrame';
        chapterElement.style.display = 'none';

        var title = document.createElement('div');
        title.setAttribute('id', 'ChapterPointsPanelDialogTitle');
        title.className = 'dialogTitle';

        var icon = document.createElement('div');
        icon.setAttribute('id', 'ChapterPointsPanelIcon');
        icon.className = 'dialogIcon';
        title.appendChild(icon);

        var titleText = document.createElement('div');
        titleText.setAttribute('id', 'ChapterPointsPanelTitleText');
        titleText.className = 'dialogTitleText';
        title.appendChild(titleText);

        var close = document.createElement('div');
        close.setAttribute('id', 'ChapterPointsPanelCloseButton');
        close.className = 'dialogCloseButtonNormal';
        title.appendChild(close);

        var message = document.createElement('div');
        message.setAttribute('id', 'ChapterPointsPanelDialogMessage');
        message.className = 'dialogMessageText';

        chapterElement.appendChild(title);
        chapterElement.appendChild(message);
        contentElement.appendChild(chapterElement);

        // hide this element to populate for later
    },

    ResizeWindow: function() {
        var doResize = SfKernel.GetQueryStringValue("shouldResize");

        if (doResize) {
            var currentSize = document.viewport.getDimensions();
            window.resizeBy((LayoutOptions.PlayerWidth - currentSize.width), (LayoutOptions.PlayerHeight - currentSize.height));
        }
    },

    ReportViewerPageOpened: function() {
        if (Manifest.IsStandAlone || this.OpenReported) {
            return;
        }

        var callManager = new ReportingCallManager();
        SonicFoundry.Mediasite.Player.DataAccess.PlayerService.ReportViewerPageOpened
		(
			Manifest.PlaybackTicketId,
			mPlayer.PlayerDetect.GetPlayerType(),
			Manifest.PlayStatus,
			Function.createDelegate(callManager, callManager.OnSuccess),
			Function.createDelegate(callManager, callManager.OnFailure),
			'ReportViewerPageOpened'
		);

        this.OpenReported = true;
    },

    ReportViewerPageClosed: function() {
        var syncRequest = new Sys.Net.WebRequest();
        syncRequest.set_url(String.format('{0}/ReportViewerPageClosed', SonicFoundry.Mediasite.Player.DataAccess.PlayerService.get_path()));
        syncRequest.set_httpVerb('POST');
        syncRequest.get_headers()['Content-Type'] = 'application/json; charset=utf-8';
        syncRequest.set_body(String.format('{{"playbackTicketId":"{0}"}}', Manifest.PlaybackTicketId));
        syncRequest.set_executor(new SfKernel.XMLHttpSyncExecutor());
        syncRequest.invoke();
    },

    CreateShowSlideEventArgs: function(slideNumber) {
        var args = new Object();

        args.Command = SfKernel.ScriptCmdType.ShowSlide;
        args.Index = slideNumber;

        if (slideNumber < 1) {
            return args;
        }

        args.Image = this.GetImageLocation(slideNumber, SfKernel.SlideType.Normal);
        args.FullSizeImage = this.GetImageLocation(slideNumber, SfKernel.SlideType.FullSize);
        args.ThumbNailImage = this.GetImageLocation(slideNumber, SfKernel.SlideType.ThumbNail);

        return args;
    },

    KeepAddingToSlideTimings: function(slideNumber) {
        var maxTimings = Manifest.Slides.length;
        if (maxTimings > slideNumber) {
            return;
        }

        var startIndex = maxTimings + 1;
        var endIndex = slideNumber;

        var i;
        for (i = startIndex; i <= endIndex; ++i) {
            this.AddToSlideTimings(i);
        }
    },

    AddToSlideTimings: function(slideNumber) {
        Manifest.Slides[Manifest.Slides.length] = new Slide("", -1, "");
    },

    GetImageLocationUsingWidthAndHeight: function(slideNumber, width, height) {
        return Manifest.GetSlideUrl(slideNumber, width, height);
    },

    GetImageLocation: function(slideNumber, type) {
        if (type == SfKernel.SlideType.Normal) {
            return Manifest.GetSlideUrl(slideNumber, LayoutOptions.SlideWidth, LayoutOptions.SlideHeight);
        }
        else if (type == SfKernel.SlideType.ThumbNail) {
            return Manifest.GetSlideUrl(slideNumber, mPlayer.ThumbnailsPanelInstance.ThumbnailWidth, mPlayer.ThumbnailsPanelInstance.ThumbnailHeight);
        }
        else {
            return Manifest.GetSlideUrl(slideNumber);
        }
    }
}

LinksButtonPanel = function() {
    this.OnLoad = function() {
        this.button.Initialize();
        this.button.SetTooltip(Localization.Buttons.Links);
    }

    this.OnDataLoad = function() {
        if (Manifest.SupportingLinks.length > 0) {
            this.button.Enable(true);
            this.button.SetClickHandler(this.OnClick.bind(this));
        }
    }

    this.OnClick = function() {
        if (this.button._enabled) {
            mPlayer.LinksPanel.Show();
        }
    }
}

////////////////////////
AskButtonPanel = function() {
    this.PrimarySpeakerEmail = null;

    this.OnLoad = function() {
        this.button.Initialize();
        this.button.SetClickHandler(this.OnClick.bind(this));
        this.button.SetTooltip(Localization.Buttons.Ask);
        this.AddEventHandlers();
    }

    this.OnDataLoad = function() {
        this.LoadPrimarySpeakerEmail();
        this.HandleButtonState();
    }

    this.AddEventHandlers = function() {
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.Script, this.ScriptEventHandler.bind(this));
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.LivePlaybackStarted, this.DataAvailableEventHandler.bind(this));
    }

    this.ScriptEventHandler = function(sender, args) {
        switch (args.Command) {
            case SfKernel.ScriptCmdType.EndPresentation:
                if (Manifest.PlayStatus != SfKernel.PresentationPlayStatus.OnDemand) {
                    this.button.Enable(false);
                }
                break;
        }
    }

    this.DataAvailableEventHandler = function(sender, args) {
        this.HandleButtonState();
    }

    this.HandleButtonState = function() {
        if (Manifest.ForumEnabled) {
            if (Manifest.PlayStatus == SfKernel.PresentationPlayStatus.Live || Manifest.PlayStatus == SfKernel.PresentationPlayStatus.LivePaused || Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand) {
                this.button.Enable(true);
                return;
            }
        }

        this.button.Enable(false);
    }

    this.LoadPrimarySpeakerEmail = function() {
        if (Manifest.Presenters.length < 1) {
            this.PrimarySpeakerEmail = null;
            return;
        }

        this.PrimarySpeakerEmail = Manifest.Presenters[0].Email;
    }

    this.OnClick = function() {
        if (this.button._enabled) {
            SfForum.OpenAskQuestion();
        }
    }
}

/////////////////
PollButtonPanel = function() {
    this.OnLoad = function() {
        this.button.Initialize();
        this.button.SetTooltip(Localization.Buttons.Polls);
    }

    this.OnDataLoad = function() {
        this.HandleButtonState();
    }

    this.HandleButtonState = function() {
        if (Manifest.PollingEnabled) {
            this.button.Enable(true);
            this.button.SetClickHandler(this.OnClick.bind(this));
        }
        else {
            this.button.Enable(false);
        }
    }

    this.OnClick = function() {
        if (this.button._enabled) {
            // needs to be resizeable
            mPlayer.PopupWindows.Polls = WindowHelper.CreateNamedPopup(WindowHelper.PopupNames.ShowPolls, "polls", 600, 450, true, false);
            if (mPlayer.PopupWindows.Polls) {
                mPlayer.PopupWindows.Polls.focus();
            }
        }
    }
}
//////////
ChangeVideoPositionButtonArea = function() {
    this.OnLoad = function() {
        this.button.Initialize();
        this.button.SetTooltip(Localization.Buttons.ChangeVideoPosition);
        this.button.SetClickHandler(this.OnClick.bind(this));
        this.button.Enable(true);
    }

    this.OnClick = function() {
        toggleVariant();
    }
}
//////////
EmailButtonArea = function() {
    this.OnLoad = function() {
        this.button.Initialize();
        this.button.SetTooltip(Localization.Buttons.Email);
    }

    this.OnDataLoad = function() {
        if (GlobalOptions.AllowEmailForm == true) {
            this.button.Enable(true);
            this.button.SetClickHandler(this.OnClick.bind(this));
        }
    }

    this.OnClick = function() {
        if (this.button._enabled) {
            SfEmail.OpenEmailInvitation();
        }
    }
}
///////
ChaptersButtonArea = function() {
    this.OnLoad = function() {
        this.button.Initialize();
        this.button.SetTooltip(Localization.ThumbnailsResource.Chapters);
    }

    this.OnDataLoad = function() {
        //if (Manifest.SupportingLinks.length > 0) {
        this.button.Enable(true);
        this.button.SetClickHandler(this.OnClick.bind(this));
        //}
    }

    this.OnClick = function() {
        if (this.button._enabled) {
            mPlayer.ChaptersPanel.Show();
            this.IsShowing = true;
        }
    }
}

///////
HelpButtonArea = function() {
    this.OnLoad = function() {
        this.button.Initialize();
        this.button.SetTooltip(Localization.Buttons.Help);
    }

    this.OnDataLoad = function() {
        this.button.Enable(true);
        this.button.SetClickHandler(this.OnClick.bind(this));
    }

    this.OnClick = function() {
        if (this.button._enabled) {
            WindowHelper.PopupHelp(WindowHelper.GetPopupURL(WindowHelper.PopupNames.Help), 800, 600);
        }
    }
}
ControlButtonArea = function(id) {
    this.ID = id;
    this.Enabled = true;
    this.ControlArea = null;

    this.OnLoad = function() {
        if (this.Enabled == false) {
            this.Hide();
            return;
        }
        else {
            this.Show();
        }
        this.button.Initialize();
        this.button.SetClickHandler(this.OnClick.bind(this));
        this.button.SetTooltip(this.TooltipId);
    }

    this.OnClick = function() {
        if (this.button.GetChecked()) {
            this.HideControlArea();
        }
        else {
            this.ShowControlArea();
        }
    }

    this.ShowControlArea = function() {
        this.ControlArea.Show();
        this.button.SetChecked(true);
    }

    this.HideControlArea = function() {
        this.ControlArea.Hide();
        this.button.SetChecked(false);
    }

    this.Hide = function() {
        var divElement = this.GetDiv();

        if (this._originalDisplay == null) {
            this._originalDisplay = divElement.style.display;
        }

        divElement.style.display = 'none';
    }

    this.GetDiv = function() {
        if (this._div == null) {
            this._div = $(this.ID);
        }
        return this._div;
    }

    this.Show = function() {
        var divElement = this.GetDiv();

        var currentDisplay = divElement.style.display;
        if (currentDisplay != 'none') {
            this._originalDisplay = currentDisplay;
            return;
        }

        // currentdisplay == 'none'
        if (this._originalDisplay == null) {
            // not initialized
            this._originalDisplay = 'none';
            divElement.style.display = '';
        }
        else {
            if (this._originalDisplay == 'none') {
                divElement.style.display = '';
            }
            else {
                divElement.style.display = this._originalDisplay;
            }
        }
    }
}

ControlButtonGroup = function() {
    this.OnLoad = function() {
        this.ResetClickHandlersForButtons();
        this.SelectFirstEnabledButton();
    }

    this.SelectFirstEnabledButton = function() {
        for (var i = 0; i < this.Buttons.length; ++i) {
            if (this.Buttons[i].Enabled == true) {
                this.OnClick(this.Buttons[i].ID);
                return;
            }
        }
    }

    this.ResetClickHandlersForButtons = function() {
        var len = this.Buttons.length;

        for (var i = 0; i < len; ++i) {
            this.Buttons[i].Group = this;
            this.Buttons[i].button.SetClickHandler(this.OnClick.bind(this, this.Buttons[i].ID));
        }
    }

    this.ShowThisAndHideOthers = function(index) {
        for (var i = 0; i < this.Buttons.length; ++i) {
            if (i == index) {
                this.Buttons[i].ShowControlArea();
            }
            else {
                this.Buttons[i].HideControlArea();
            }
        }
    }

    this.OnClick = function(buttonID) {
        var index = this.FindClickedButtonIndex(buttonID);
        if (this.Buttons[index].button.IsChecked == true) {
            return;
        }
        this.ShowThisAndHideOthers(index);
    }

    this.FindClickedButtonIndex = function(buttonID) {
        for (var i = 0; i < this.Buttons.length; ++i) {
            if (this.Buttons[i].ID == buttonID) {
                return i;
            }
        }
        return -1;
    }
}

////////////////////////
PreviousSlideButtonArea = function(container) {
    this.Container = container;

    this.OnLoad = function() {
        this.button.Initialize();
        this.button.SetTooltip(Localization.Buttons.PreviousSlide);
    }

    this.OnDataLoad = function() {
        this.button.SetClickHandler(this.OnClick.bind(this));
        this.button.SetDblClickHandler(this.OnClick.bind(this));
        this.AddEventHandlers();
        this.HandleButtonState(-1);
    }

    this.AddEventHandlers = function() {
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.Script, this.ScriptEventHandler.bind(this));
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.PlayingFromBeginning, this.PlayingFromBeginningEventHandler.bind(this));
    }

    this.ScriptEventHandler = function(sender, args) {
        if (args.Command != SfKernel.ScriptCmdType.ShowSlide) {
            return;
        }
        this.HandleButtonState(args.Index);
    }

    this.PlayingFromBeginningEventHandler = function(sender, args) {
        this.HandleButtonState(-1);
    }

    this.OnClick = function() {
        var currentSlide = mPlayer.CurrentSlideNumber;

        var toJumpTo;
        if (mPlayer.PresentationEnded) {
            if (Manifest.Slides.length > 0) {
                toJumpTo = Manifest.Slides.length;
            }
            else {
                return;
            }
        }
        else if (currentSlide > 1) {
            toJumpTo = currentSlide - 1;
        }
        else {
            return;
        }

        mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.NavigateToSlide, this, { SlideNumber: toJumpTo });

    }

    this.HandleButtonState = function(currentSlide) {
        if (Manifest.PlayStatus != SfKernel.PresentationPlayStatus.OnDemand) {
            this.button.Enable(false);
            return;
        }

        if (currentSlide < 2) {
            this.button.Enable(false);
            return;
        }

        this.button.Enable(true);
    }
}

////////////////////////
NextSlideButtonArea = function(container) {
    this.Container = container;

    this.OnLoad = function() {
        this.button.Initialize();
        this.button.SetTooltip(Localization.Buttons.NextSlide);
    }

    this.OnDataLoad = function() {
        this.button.SetClickHandler(this.OnClick.bind(this));
        this.AddEventHandlers();
        this.HandleButtonState(-1);
    }

    this.AddEventHandlers = function() {
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.Script, this.ScriptEventHandler.bind(this));
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.PlayingFromBeginning, this.PlayingFromBeginningEventHandler.bind(this));
    }

    this.ScriptEventHandler = function(sender, args) {
        switch (args.Command) {
            case SfKernel.ScriptCmdType.ShowSlide:
                this.HandleButtonState(args.Index);
        }
    }

    this.PlayingFromBeginningEventHandler = function(sender, args) {
        this.HandleButtonState(-1);
    }

    this.OnClick = function() {
        var currentSlide = mPlayer.CurrentSlideNumber;
        var maxSlide = Manifest.Slides.length;
        if (currentSlide == -1 && maxSlide > 0) {
            mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.NavigateToSlide, this, { SlideNumber: 1 });
        }
        else if (currentSlide < maxSlide) {
            mPlayer.EventManager.PostCommandEvent(SfKernel.CommandEventId.NavigateToSlide, this, { SlideNumber: currentSlide + 1 });
        }
    }

    this.HandleButtonState = function(currentSlide) {
        if (Manifest.PlayStatus != SfKernel.PresentationPlayStatus.OnDemand) {
            this.button.Enable(false);
            return;
        }

        var maxSlide = Manifest.Slides.length;
        if (currentSlide == -1) {
            if (maxSlide > 0) {
                this.button.Enable(true);
            }
            else {
                this.button.Enable(false);
            }
            return;
        }

        if (currentSlide < maxSlide) {
            this.button.Enable(true);
        }
        else {
            this.button.Enable(false);
        }
    }
}


SlideNumberPanel = function(container, containingWindow, id) {
    this.Container = container;
    this.ContainingWindow = containingWindow;
    this.ID = id;

    this.SlideText = null;
    this.OfText = null;
    this.DefaultText = null;

    this.OnLoad = function() {
    }

    this.OnDataLoad = function() {
        this.AddEventHandlers();
    }


    this.SetText = function(val) {
        var textNode = document.createTextNode(val);

        var div = this.GetDiv();
        var firstChild = div.childNodes[0];
        if (firstChild) {
            div.replaceChild(textNode, firstChild);
        }
        else {
            div.appendChild(textNode);
        }
    }

    this.AddEventHandlers = function() {
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.Script, this.ScriptEventHandler.bind(this));
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.PlayingFromBeginning, this.PlayingFromBeginningEventHandler.bind(this));
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.LivePlaybackStarted, this.LivePlaybackStartedEventHandler.bind(this));
    }

    this.ScriptEventHandler = function(sender, args) {
        switch (args.Command) {
            case SfKernel.ScriptCmdType.ShowSlide:
                var index = args.Index;
                if (index < 1) {
                    this.SetBlankText();
                    return;
                }
                this.SetText(this.SlideText + " " + index + " " + this.OfText + " " + Manifest.Slides.length);
                break;
            case SfKernel.ScriptCmdType.EndPresentation:
                this.SetBlankText();
                break;
        }
    }
    this.LivePlaybackStartedEventHandler = function(sender, args) {
        var slideNumber = Manifest.Slides.length;
        if (slideNumber > 0) {
            this.SetText(this.SlideText + " " + slideNumber + " " + this.OfText + " " + slideNumber);
        }

    }

    this.PlayingFromBeginningEventHandler = function(sender, args) {
        if (mPlayer.CurrentSlideNumber == -1) {
            this.SetBlankText();
        }
    }

    this.SetBlankText = function() {
        this.SetText(this.DefaultText);
    }
}

SlideNumberPanel.prototype = new Panel();
SlideNumberPanel.prototype.constructor = SlideNumberPanel;
SlideNumberPanel.prototype.baseClass = Panel.prototype.constructor;


//////////////////////
SlideShowButtonArea = function(id) {
    this.ID = id;
    this.OnLoad = function() {
        if (!this.Enabled) {
            this.Hide();
            return;
        }
        this.Show();
        this.button.Initialize();
        this.button.SetTooltip(this.TooltipId);
    }

    this.OnDataLoad = function() {
        this.button.SetClickHandler(this.OnClick.bind(this));
    }

    this.OnClick = function() {
        if (!this.button.GetChecked()) {
            if (this.ID == 'btnSlideShow') {
                this.ShowControlArea();
            }
            else {
                this.HideControlArea();
            }
        }
    }

    this.ShowControlArea = function() {
        this.ControlArea.show();
        mPlayer.btnSlideShowInstance.button.SetChecked(true);
        mPlayer.btnSlideListInstance.button.SetChecked(false);
    }

    this.HideControlArea = function() {
        this.ControlArea.hide();
        mPlayer.btnSlideListInstance.button.SetChecked(true);
        mPlayer.btnSlideShowInstance.button.SetChecked(false);
    }

    this.Hide = function() {
        var divElement = this.GetDiv();
        if (this._originalDisplay == null) {
            this._originalDisplay = divElement.style.display;
        }
        divElement.style.display = 'none';
    }

    this.GetDiv = function() {
        if (this._div == null) {
            this._div = $(this.ID);
        }
        return this._div;
    }

    this.Show = function() {
        var divElement = this.GetDiv();

        var currentDisplay = divElement.style.display;
        if (currentDisplay != 'none') {
            this._originalDisplay = currentDisplay;
            return;
        }

        // currentdisplay == 'none'
        if (this._originalDisplay == null) {
            // not initialized
            this._originalDisplay = 'none';
            divElement.style.display = '';
        }
        else {
            if (this._originalDisplay == 'none') {
                divElement.style.display = '';
            }
            else {
                divElement.style.display = this._originalDisplay;
            }
        }
    }
}

/// Theme Image
SkinImage = function(id) {
    this.ID = id;
    this.ImageSRC = null;
    //this.ImageBackSRC = null;
    this.ImageHref = null;
    this.ImageWidth = null;
    this.ImageHeight = null;
    this.ParentWidth = null;
    this.ParentHeight = null;
    this.Alt = '';
    this.Style = null;
    this.ParentStyle = null;

    this.OnLoad = function() {
        var ParentElement = $(this.ID);

        if (!ParentElement) {
            return;
        }

        this.ParentWidth = ParentElement.style.width;
        this.ParentHeight = ParentElement.style.height;

        var parentStyle = ParentElement.style;
        ParentElement.setAttribute('style', parentStyle + this.ParentStyle);
        var BannerPanel = this.createBannerPanel();
        ParentElement.appendChild(BannerPanel);
    }

    this.createBannerPanel = function() {
        //        banners as img tags.    
        //        var imgElement = $(document.createElement('img'));
        //        imgElement.setAttribute('id', this.ID + 'Image');
        //        imgElement.setAttribute('src', this.ImageSRC);
        //        imgElement.setAttribute('alt', this.Alt);
        //        imgElement.setAttribute('style', this.Style);
        //        imgElement.setAttribute('border', '0');

        //      banners as divs with background images        
        var imgElement = $(document.createElement('div'));
        imgElement.setAttribute('id', this.ID + 'Image');
        imgElement.setAttribute('style', this.Style);
        imgElement.setAttribute('border', '0');
        imgElement.setStyle({
            backgroundRepeat: 'no-repeat',
            backgroundImage: 'url(' + this.ImageSRC + ')',
            height: this.ImageHeight + 'px',
            width: this.ImageWidth + 'px'
        });
        imgElement.setAttribute('title', this.Alt);
        if (this.ImageHeight != null && this.ImageWidth != null) {
            imgElement.setAttribute('height', this.ImageHeight);
            imgElement.setAttribute('width', this.ImageWidth);
        }
        else {
            imgElement.setAttribute('height', this.ParentHeight.replace("px", ""));
            imgElement.setAttribute('width', this.ParentWidth.replace("px", ""));
        }

        if (this.ImageHref != '') // if there's no link, dont create the tag
        {
            var aElement = $(document.createElement('a'));
            aElement.setAttribute('id', this.ID + 'Link');
            aElement.setAttribute('href', this.ImageHref);
            aElement.setAttribute('target', '_offsite');
            aElement.appendChild(imgElement);
            imgElement.setStyle({ cursor: 'pointer', cursor: 'hand' })
            return aElement;
        }
        else {
            return imgElement;
        }
    }
}

// Banners
function LoadBanners() {
    this.Banner = null;
    this.OnLoad = function() {
        for (var i = 0; i < this.Banner.length; i++) {
            if (LayoutOptions.Images[this.Banner[i]]) {
                var BannerInstance = new SkinImage(this.Banner[i]);
                BannerInstance.ImageSRC = LayoutOptions.Images[this.Banner[i]].ImageFilename;
                BannerInstance.ImageHref = LayoutOptions.Images[this.Banner[i]].ImageUrl;
                BannerInstance.ImageHeight = LayoutOptions.Images[this.Banner[i]].Height;
                BannerInstance.ImageWidth = LayoutOptions.Images[this.Banner[i]].Width;
                BannerInstance.OnLoad();
            }
        }
    }
}

//Slider Area
SliderArea = function(container, containingWindow, id) {
    this.ID = id;
    this.Slider = null;
    this.mediaLengthObtainedEventHandler = null;
    this.playerTimerUpdatedEventHandler = null;
    this.IsCurrentlyDragging = false;
    this.Orientation = SfUI.SfSlider.Orientation.Vertical;

    this.OnLoad = function() {
        if (Manifest.PlayStatus == SfKernel.PresentationPlayStatus.OnDemand) {
            this.Initialize();
            this.Slider.SetEnabled(true);
            this.AddEventHandlers();
        }
    }

    this.Initialize = function() {
        var imageInfo = { SliderBackroundImage: this.SliderBackgroundImage, ThumbImage: this.ThumbImage, ThumbOverImage: this.ThumbOverImage };
        this.Slider = new SfUI.SfSlider({ NamePrefix: this.ID, Orientation: this.Orientation, ImageInfo: imageInfo });
    }

    this.AddEventHandlers = function() {
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.MediaLengthObtained, this.MediaLengthObtainedEventHandler.bind(this));
        mPlayer.EventManager.Events.addHandler(SfKernel.EventType.TimerLoop, this.TimerLoopEventHandler.bind(this));

        this.Slider.AddClickHandler(Function.createDelegate(this, this.OnSliderClick));
        this.Slider.AddDragHandler(Function.createDelegate(this, this.OnSliderDrag));
    }

    this.MediaLengthObtainedEventHandler = function(sender, range) {
        this.Slider.SetRange(range.Left, range.Right);
    }

    this.TimerLoopEventHandler = function(sender, args) {
        if (this.IsCurrentlyDragging == true) {
            return;
        }
        this.Slider.SetPosition(args["Position"]);
    }

    this.OnSliderClick = function(sender, args) {
        this.Slider.SetPosition(args.Position);

        var sliderArgs = new SfKernel.SliderArgs(SfKernel.SliderNotifyType.NewPosition, args.Position);
        mPlayer.EventManager.PostEvent(SfKernel.EventType.SliderNotify, this, sliderArgs);
    }

    this.OnSliderDrag = function(sender, dragArgs) {
        if (dragArgs.DragEventType == SfUI.SfSlider.DragEventType.DragMove) {
            this.Slider.SetPosition(dragArgs.Position);

            var sliderArgs = new SfKernel.SliderArgs(SfKernel.SliderNotifyType.DragPosition, dragArgs.Position);
            mPlayer.EventManager.PostEvent(SfKernel.EventType.SliderNotify, this, sliderArgs);
        }
        else if (dragArgs.DragEventType == SfUI.SfSlider.DragEventType.BeginDrag) {
            var sliderArgs = new SfKernel.SliderArgs(SfKernel.SliderNotifyType.BeginDrag, dragArgs.Position);

            mPlayer.EventManager.PostEvent(SfKernel.EventType.SliderNotify, this, sliderArgs);
            this.IsCurrentlyDragging = true;
        }
        else if (dragArgs.DragEventType == SfUI.SfSlider.DragEventType.EndDrag) {
            var newPositionArgs = new SfKernel.SliderArgs(SfKernel.SliderNotifyType.NewPosition, dragArgs.Position);
            mPlayer.EventManager.PostEvent(SfKernel.EventType.SliderNotify, this, newPositionArgs);

            var endDragArgs = new SfKernel.SliderArgs(SfKernel.SliderNotifyType.EndDrag, dragArgs.Position);
            mPlayer.EventManager.PostEvent(SfKernel.EventType.SliderNotify, this, endDragArgs);
            this.IsCurrentlyDragging = false;
        }
    }
}

function loadingMask(container, max, num) {

    createBlocks(container, num);
    for (var i = 0; i < max; ++i)                       // max repeats before stop
    {
        setTimeout('paintBlocks(' + num + ')', i * 1600);  // interval between repeat
    }
}

function createBlocks(container, num) {
    var blockPaintInterval = 0;
    var container = document.getElementById(container);
    for (var i = 0; i < num; ++i) {
        var e = document.createElement('div');
        e.setAttribute('id', 'spinDiv' + i);
        e.setAttribute('class', 'spinDiv');
        container.appendChild(e);
    }
}

function paintBlocks(num) {
    var i = 0;
    var t = 100;
    var c = 150;
    for (var j = 1; j < num; ++j) {
        setTimeout('colorBlock(' + i + ',' + num + ',' + c + ',' + c + ',' + c + ')', t);
        c = (c + 20);  // grayscale step
        t = t + 100;   // chase length
    }
}

function colorBlock(i, num, r, g, b) {
    if (i < num) {
        var e = document.getElementById('spinDiv' + i);
        e.style.backgroundColor = 'rgb(' + r + ',' + g + ',' + b + ')';
        setTimeout('colorBlock(' + (++i) + ',' + num + ',' + r + ',' + g + ',' + b + ')', 100);
    }
}

var mPlayer = new MediasitePlayer();
try {
    mPlayer.OnLoad();
}
catch (error) {
    PresentationFailedToLoad('manifestFailedErrorDialog', error.message);
}
