/*  Prototype JavaScript framework, version 1.5.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://prototype.conio.net/
 *
/*--------------------------------------------------------------------------*/

var Prototype = {
  Version: '1.5.0',
  BrowserFeatures: {
    XPath: !!document.evaluate
  },

  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
  emptyFunction: function() {},
  K: function(x) { return x }
}

var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
}

var Abstract = new Object();

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;
    }
  },

  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);
  }
});

Function.prototype.bind = function() {
  var __method = this, args = $A(arguments), object = args.shift();
  return function() {
    return __method.apply(object, args.concat($A(arguments)));
  }
}

Function.prototype.bindAsEventListener = function(object) {
  var __method = this, args = $A(arguments), object = args.shift();
  return function(event) {
    return __method.apply(object, [( event || window.event)].concat(args).concat($A(arguments)));
  }
}

Object.extend(Number.prototype, {
  toColorPart: function() {
    var digits = this.toString(16);
    if (this < 16) return '0' + digits;
    return digits;
  },

  succ: function() {
    return this + 1;
  },

  times: function(iterator) {
    $R(0, this, true).each(iterator);
    return this;
  }
});

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;
  }
}

/*--------------------------------------------------------------------------*/

var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
  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);
  },

  stop: function() {
    if (!this.timer) return;
    clearInterval(this.timer);
    this.timer = null;
  },

  onTimerEvent: function() {
    if (!this.currentlyExecuting) {
      try {
        this.currentlyExecuting = true;
        this.callback(this);
      } finally {
        this.currentlyExecuting = false;
      }
    }
  }
}
String.interpret = function(value){
  return value == null ? '' : String(value);
}

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 this;
  },

  truncate: function(length, truncation) {
    length = length || 30;
    truncation = truncation === undefined ? '...' : truncation;
    return this.length > length ?
      this.slice(0, length - truncation.length) + truncation : 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 div = document.createElement('div');
    var text = document.createTextNode(this);
    div.appendChild(text);
    return div.innerHTML;
  },

  unescapeHTML: function() {
    var div = document.createElement('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 name = decodeURIComponent(pair[0]);
        var value = pair[1] ? decodeURIComponent(pair[1]) : undefined;

        if (hash[name] !== undefined) {
          if (hash[name].constructor != Array)
            hash[name] = [hash[name]];
          if (value) hash[name].push(value);
        }
        else hash[name] = 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);
  },

  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.replace(/\\/g, '\\\\');
    if (useDoubleQuotes)
      return '"' + escapedString.replace(/"/g, '\\"') + '"';
    else
      return "'" + escapedString.replace(/'/g, '\\\'') + "'";
  }
});

String.prototype.gsub.prepareReplacement = function(replacement) {
  if (typeof replacement == 'function') return replacement;
  var template = new Template(replacement);
  return function(match) { return template.evaluate(match) };
}

String.prototype.parseQuery = String.prototype.toQueryParams;

var Template = Class.create();
Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
Template.prototype = {
  initialize: function(template, pattern) {
    this.template = template.toString();
    this.pattern  = pattern || Template.Pattern;
  },

  evaluate: function(object) {
    return this.template.gsub(this.pattern, function(match) {
      var before = match[1];
      if (before == '\\') return match[2];
      return before + String.interpret(object[match[3]]);
    });
  }
}

var $break    = new Object();
var $continue = new Object();

var Enumerable = {
  each: function(iterator) {
    var index = 0;
    try {
      this._each(function(value) {
        try {
          iterator(value, index++);
        } catch (e) {
          if (e != $continue) throw e;
        }
      });
    } catch (e) {
      if (e != $break) throw e;
    }
    return this;
  },

  eachSlice: function(number, iterator) {
    var index = -number, slices = [], array = this.toArray();
    while ((index += number) < array.length)
slices.push(array.slice(index, index+number));
    return slices.map(iterator);
  },

  all: function(iterator) {
    var result = true;
    this.each(function(value, index) {
      result = result && !!(iterator || Prototype.K)(value, index);
      if (!result) throw $break;
    });
    return result;
  },

  any: function(iterator) {
    var result = false;
    this.each(function(value, index) {
      if (result = !!(iterator || Prototype.K)(value, index))
        throw $break;
    });
    return result;
  },

  collect: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      results.push((iterator || Prototype.K)(value, index));
    });
    return results;
  },

  detect: function(iterator) {
    var result;
    this.each(function(value, index) {
      if (iterator(value, index)) {
        result = value;
        throw $break;
      }
    });
    return result;
  },

  findAll: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      if (iterator(value, index))
        results.push(value);
    });
    return results;
  },

  grep: function(pattern, iterator) {
    var results = [];
    this.each(function(value, index) {
      var stringValue = value.toString();
      if (stringValue.match(pattern))
        results.push((iterator || Prototype.K)(value, index));
    })
    return results;
  },

  include: function(object) {
    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) {
    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) {
    var result;
    this.each(function(value, index) {
      value = (iterator || Prototype.K)(value, index);
      if (result == undefined || value >= result)
        result = value;
    });
    return result;
  },

  min: function(iterator) {
    var result;
    this.each(function(value, index) {
      value = (iterator || Prototype.K)(value, index);
      if (result == undefined || value < result)
result = value;
    });
    return result;
  },

  partition: function(iterator) {
    var trues = [], falses = [];
    this.each(function(value, index) {
      ((iterator || Prototype.K)(value, index) ?
        trues : falses).push(value);
    });
    return [trues, falses];
  },

  pluck: function(property) {
    var results = [];
    this.each(function(value, index) {
      results.push(value[property]);
    });
    return results;
  },

  reject: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      if (!iterator(value, index))
        results.push(value);
    });
    return results;
  },

  sortBy: function(iterator) {
    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 (typeof args.last() == 'function')
      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,
  member:  Enumerable.include,
  entries: Enumerable.toArray
});
var $A = Array.from = function(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) {
    return iterable.toArray();
  } else {
    var results = [];
    for (var i = 0, length = iterable.length; i < length; i++)
      results.push(iterable[i]);
    return results;
  }
}

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(value && value.constructor == Array ?
        value.flatten() : [value]);
    });
  },

  without: function() {
    var values = $A(arguments);
    return this.select(function(value) {
      return !values.include(value);
    });
  },

  indexOf: function(object) {
    for (var i = 0, length = this.length; i < length; i++)
      if (this[i] == object) return i;
    return -1;
  },

  reverse: function(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  },

  reduce: function() {
    return this.length > 1 ? this : this[0];
  },

  uniq: function() {
    return this.inject([], function(array, value) {
      return array.include(value) ? array : array.concat([value]);
    });
  },

  clone: function() {
    return [].concat(this);
  },

  size: function() {
    return this.length;
  },

  inspect: function() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  }
});

Array.prototype.toArray = Array.prototype.clone;

function $w(string){
  string = string.strip();
  return string ? string.split(/\s+/) : [];
}

if(window.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(arguments[i].constructor == Array) {
        for(var j = 0, arrayLength = arguments[i].length; j < arrayLength; j++)
          array.push(arguments[i][j]);
      } else {
        array.push(arguments[i]);
      }
    }
    return array;
  }
}
var Hash = function(obj) {
  Object.extend(this, obj || {});
};

Object.extend(Hash, {
  toQueryString: function(obj) {
    var parts = [];

	  this.prototype._each.call(obj, function(pair) {
      if (!pair.key) return;

      if (pair.value && pair.value.constructor == Array) {
        var values = pair.value.compact();
        if (values.length < 2) pair.value = values.reduce();
        else {
        	key = encodeURIComponent(pair.key);
          values.each(function(value) {
            value = value != undefined ? encodeURIComponent(value) : '';
            parts.push(key + '=' + encodeURIComponent(value));
          });
          return;
        }
      }
      if (pair.value == undefined) pair[1] = '';
      parts.push(pair.map(encodeURIComponent).join('='));
	  });

    return parts.join('&');
  }
});

Object.extend(Hash.prototype, Enumerable);
Object.extend(Hash.prototype, {
  _each: function(iterator) {
    for (var key in this) {
      var value = this[key];
      if (value && value == Hash.prototype[key]) continue;

      var pair = [key, value];
      pair.key = key;
      pair.value = value;
      iterator(pair);
    }
  },

  keys: function() {
    return this.pluck('key');
  },

  values: function() {
    return this.pluck('value');
  },

  merge: function(hash) {
    return $H(hash).inject(this, function(mergedHash, pair) {
      mergedHash[pair.key] = pair.value;
      return mergedHash;
    });
  },

  remove: function() {
    var result;
    for(var i = 0, length = arguments.length; i < length; i++) {
      var value = this[arguments[i]];
      if (value !== undefined){
        if (result === undefined) result = value;
        else {
          if (result.constructor != Array) result = [result];
          result.push(value)
        }
      }
      delete this[arguments[i]];
    }
    return result;
  },

  toQueryString: function() {
    return Hash.toQueryString(this);
  },

  inspect: function() {
    return '#<Hash:{' + this.map(function(pair) {
      return pair.map(Object.inspect).join(': ');
    }).join(', ') + '}>';
  }
});

function $H(object) {
  if (object && object.constructor == Hash) return object;
  return new Hash(object);
};
ObjectRange = Class.create();
Object.extend(ObjectRange.prototype, Enumerable);
Object.extend(ObjectRange.prototype, {
  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 (typeof responder[callback] == 'function') {
        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 = function() {};
Ajax.Base.prototype = {
  setOptions: function(options) {
    this.options = {
      method:       'post',
      asynchronous: true,
      contentType:  'application/x-www-form-urlencoded',
      encoding:     'UTF-8',
      parameters:   ''
    }
    Object.extend(this.options, options || {});

    this.options.method = this.options.method.toLowerCase();
    if (typeof this.options.parameters == 'string')
      this.options.parameters = this.options.parameters.toQueryParams();
  }
}

Ajax.Request = Class.create();
Ajax.Request.Events =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
  _complete: false,

  initialize: function(url, options) {
    this.transport = Ajax.getTransport();
    this.setOptions(options);
    this.request(url);
  },

  request: function(url) {
    this.url = url;
    this.method = this.options.method;
    var params = this.options.parameters;

    if (!['get', 'post'].include(this.method)) {
      // simulate other verbs over post
      params['_method'] = this.method;
      this.method = 'post';
    }

    params = Hash.toQueryString(params);
    if (params && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) params += '&_='

    // when GET, append parameters to URL
    if (this.method == 'get' && params)
      this.url += (this.url.indexOf('?') > -1 ? '&' : '?') + params;

    try {
      Ajax.Responders.dispatch('onCreate', this, this.transport);

      this.transport.open(this.method.toUpperCase(), this.url,
        this.options.asynchronous);

      if (this.options.asynchronous)
        setTimeout(function() { this.respondToReadyState(1) }.bind(this), 10);

      this.transport.onreadystatechange = this.onStateChange.bind(this);
      this.setRequestHeaders();

      var body = this.method == 'post' ? (this.options.postBody || params) : null;

      this.transport.send(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 (typeof extras.push == 'function')
        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() {
    return !this.transport.status
        || (this.transport.status >= 200 && this.transport.status < 300);
},

  respondToReadyState: function(readyState) {
    var state = Ajax.Request.Events[readyState];
    var transport = this.transport, json = this.evalJSON();

    if (state == 'Complete') {
      try {
        this._complete = true;
        (this.options['on' + this.transport.status]
         || this.options['on' + (this.success() ? 'Success' : 'Failure')]
         || Prototype.emptyFunction)(transport, json);
      } catch (e) {
        this.dispatchException(e);
      }

      if ((this.getHeader('Content-type') || 'text/javascript').strip().
        match(/^(text|application)\/(x-)?(java|ecma)script(;.*)?$/i))
          this.evalResponse();
    }

    try {
      (this.options['on' + state] || Prototype.emptyFunction)(transport, json);
      Ajax.Responders.dispatch('on' + state, this, transport, json);
    } 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 }
  },

  evalJSON: function() {
    try {
      var json = this.getHeader('X-JSON');
      return json ? eval('(' + json + ')') : null;
    } catch (e) { return null }
  },

  evalResponse: function() {
    try {
      return eval(this.transport.responseText);
    } catch (e) {
      this.dispatchException(e);
    }
  },

  dispatchException: function(exception) {
    (this.options.onException || Prototype.emptyFunction)(this, exception);
    Ajax.Responders.dispatch('onException', this, exception);
  }
});

Ajax.Updater = Class.create();

Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
  initialize: function(container, url, options) {
    this.container = {
      success: (container.success || container),
      failure: (container.failure || (container.success ? null : container))
    }

    this.transport = Ajax.getTransport();
    this.setOptions(options);

    var onComplete = this.options.onComplete || Prototype.emptyFunction;
    this.options.onComplete = (function(transport, param) {
      this.updateContent();
      onComplete(transport, param);
    }).bind(this);

    this.request(url);
  },

  updateContent: function() {
    var receiver = this.container[this.success() ? 'success' : 'failure'];
    var response = this.transport.responseText;

    if (!this.options.evalScripts) response = response.stripScripts();

    if (receiver = $(receiver)) {
      if (this.options.insertion)
        new this.options.insertion(receiver, response);
      else
        receiver.update(response);
    }

    if (this.success()) {
      if (this.onComplete)
        setTimeout(this.onComplete.bind(this), 10);
    }
  }
});

Ajax.PeriodicalUpdater = Class.create();
Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
  initialize: function(container, url, options) {
    this.setOptions(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(request) {
    if (this.options.decay) {
      this.decay = (request.responseText == this.lastText ?
        this.decay * this.options.decay : 1);

      this.lastText = request.responseText;
    }
    this.timer = setTimeout(this.onTimerEvent.bind(this),
      this.decay * this.frequency * 1000);
  },

  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 (typeof element == 'string')
    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(query.snapshotItem(i));
    return results;
  };
}

document.getElementsByClassName = function(className, parentElement) {
  if (Prototype.BrowserFeatures.XPath) {
    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
    return document._getElementsByXPath(q, parentElement);
  } else {
    var children = ($(parentElement) || document.body).getElementsByTagName('*');
    var elements = [], child;
    for (var i = 0, length = children.length; i < length; i++) {
      child = children[i];
      if (Element.hasClassName(child, className))
        elements.push(Element.extend(child));
    }
    return elements;
  }
};

/*--------------------------------------------------------------------------*/

if (!window.Element)
  var Element = new Object();

Element.extend = function(element) {
  if (!element || _nativeExtensions || element.nodeType == 3) return element;

  if (!element._extended && element.tagName && element != window) {
    var methods = Object.clone(Element.Methods), cache = Element.extend.cache;

    if (element.tagName == 'FORM')
      Object.extend(methods, Form.Methods);
    if (['INPUT', 'TEXTAREA', 'SELECT'].include(element.tagName))
      Object.extend(methods, Form.Element.Methods);

    Object.extend(methods, Element.Methods.Simulated);

    for (var property in methods) {
      var value = methods[property];
      if (typeof value == 'function' && !(property in element))
        element[property] = cache.findOrStore(value);
    }
  }

  element._extended = true;
  return element;
};

Element.extend.cache = {
  findOrStore: function(value) {
    return this[value] = this[value] || function() {
      return value.apply(null, [this].concat($A(arguments)));
    }
  }
};

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, html) {
    html = typeof html == 'undefined' ? '' : html.toString();
    $(element).innerHTML = html.stripScripts();
    setTimeout(function() {html.evalScripts()}, 10);
    return element;
  },

  replace: function(element, html) {
    element = $(element);
    html = typeof html == 'undefined' ? '' : html.toString();
    if (element.outerHTML) {
      element.outerHTML = html.stripScripts();
    } else {
      var range = element.ownerDocument.createRange();
      range.selectNodeContents(element);
      element.parentNode.replaceChild(
        range.createContextualFragment(html.stripScripts()), element);
    }
    setTimeout(function() {html.evalScripts()}, 10);
    return element;
  },

  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('*'));
  },

  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 (typeof selector == 'string')
      selector = new Selector(selector);
    return selector.match($(element));
  },

  up: function(element, expression, index) {
    return Selector.findElement($(element).ancestors(), expression, index);
  },

  down: function(element, expression, index) {
    return Selector.findElement($(element).descendants(), expression, index);
  },

  previous: function(element, expression, index) {
    return Selector.findElement($(element).previousSiblings(), expression, index);
  },

  next: function(element, expression, index) {
    return Selector.findElement($(element).nextSiblings(), expression, index);
  },

  getElementsBySelector: function() {
    var args = $A(arguments), element = $(args.shift());
    return Selector.findChildElements(element, args);
  },

  getElementsByClassName: function(element, className) {
    return document.getElementsByClassName(className, element);
  },

  readAttribute: function(element, name) {
    element = $(element);
    if (document.all && !window.opera) {
      var t = Element._attributeTranslations;
      if (t.values[name]) return t.values[name](element, name);
      if (t.names[name])  name = t.names[name];
      var attribute = element.attributes[name];
      if(attribute) return attribute.nodeValue;
    }
    return element.getAttribute(name);
  },

  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;
    if (elementClassName.length == 0) return false;
    if (elementClassName == className ||
        elementClassName.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
      return true;
    return false;
  },

  addClassName: function(element, className) {
    if (!(element = $(element))) return;
    Element.classNames(element).add(className);
    return element;
  },

  removeClassName: function(element, className) {
    if (!(element = $(element))) return;
    Element.classNames(element).remove(className);
    return element;
  },

  toggleClassName: function(element, className) {
    if (!(element = $(element))) return;
    Element.classNames(element)[element.hasClassName(className) ? 'remove' : 'add'](className);
    return element;
  },

  observe: function() {
    Event.observe.apply(Event, arguments);
    return $A(arguments).first();
  },

  stopObserving: function() {
    Event.stopObserving.apply(Event, arguments);
    return $A(arguments).first();
  },

  // 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.match(/^\s*$/);
  },

  descendantOf: function(element, ancestor) {
    element = $(element), ancestor = $(ancestor);
    while (element = element.parentNode)
      if (element == ancestor) return true;
    return false;
  },

  scrollTo: function(element) {
    element = $(element);
    var pos = Position.cumulativeOffset(element);
    window.scrollTo(pos[0], pos[1]);
    return element;
  },

  getStyle: function(element, style) {
    element = $(element);
    if (['float','cssFloat'].include(style))
      style = (typeof element.style.styleFloat != 'undefined' ? 'styleFloat' : 'cssFloat');
    style = style.camelize();
    var value = element.style[style];
    if (!value) {
      if (document.defaultView && document.defaultView.getComputedStyle) {
        var css = document.defaultView.getComputedStyle(element, null);
        value = css ? css[style] : null;
      } else if (element.currentStyle) {
        value = element.currentStyle[style];
      }
    }

    if((value == 'auto') && ['width','height'].include(style) && (element.getStyle('display') != 'none'))
      value = element['offset'+style.capitalize()] + 'px';

    if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
      if (Element.getStyle(element, 'position') == 'static') value = 'auto';
    if(style == 'opacity') {
      if(value) return parseFloat(value);
      if(value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
        if(value[1]) return parseFloat(value[1]) / 100;
      return 1.0;
    }
    return value == 'auto' ? null : value;
  },

  setStyle: function(element, style) {
    element = $(element);
    for (var name in style) {
      var value = style[name];
      if(name == 'opacity') {
        if (value == 1) {
          value = (/Gecko/.test(navigator.userAgent) &&
            !/Konqueror|Safari|KHTML/.test(navigator.userAgent)) ? 0.999999 : 1.0;
          if(/MSIE/.test(navigator.userAgent) && !window.opera)
            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
        } else if(value === '') {
          if(/MSIE/.test(navigator.userAgent) && !window.opera)
            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'');
        } else {
          if(value < 0.00001) value = 0;
          if(/MSIE/.test(navigator.userAgent) && !window.opera)
            element.style.filter = element.getStyle('filter').replace(/alpha\([^\)]*\)/gi,'') +
              'alpha(opacity='+value*100+')';
        }
      } else if(['float','cssFloat'].include(name)) name = (typeof element.style.styleFloat != 'undefined') ? 'styleFloat' : 'cssFloat';
      element.style[name.camelize()] = 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.style.overflow || 'auto';
    if ((Element.getStyle(element, 'overflow') || 'visible') != '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;
  }
};

Object.extend(Element.Methods, {childOf: Element.Methods.descendantOf});

Element._attributeTranslations = {};

Element._attributeTranslations.names = {
  colspan:   "colSpan",
  rowspan:   "rowSpan",
  valign:    "vAlign",
  datetime:  "dateTime",
  accesskey: "accessKey",
  tabindex:  "tabIndex",
  enctype:   "encType",
  maxlength: "maxLength",
  readonly:  "readOnly",
  longdesc:  "longDesc"
};

Element._attributeTranslations.values = {
  _getAttr: function(element, attribute) {
    return element.getAttribute(attribute, 2);
  },

  _flag: function(element, attribute) {
    return $(element).hasAttribute(attribute) ? attribute : null;
  },

  style: function(element) {
    return element.style.cssText.toLowerCase();
  },

  title: function(element) {
    var node = element.getAttributeNode('title');
    return node.specified ? node.nodeValue : null;
  }
};

Object.extend(Element._attributeTranslations.values, {
  href: Element._attributeTranslations.values._getAttr,
  src:  Element._attributeTranslations.values._getAttr,
  disabled: Element._attributeTranslations.values._flag,
  checked:  Element._attributeTranslations.values._flag,
  readonly: Element._attributeTranslations.values._flag,
  multiple: Element._attributeTranslations.values._flag
});

Element.Methods.Simulated = {
  hasAttribute: function(element, attribute) {
    var t = Element._attributeTranslations;
    attribute = t.names[attribute] || attribute;
    return $(element).getAttributeNode(attribute).specified;
  }
};

// IE is missing .innerHTML support for TABLE-related elements
if (document.all && !window.opera){
  Element.Methods.update = function(element, html) {
    element = $(element);
    html = typeof html == 'undefined' ? '' : html.toString();
    var tagName = element.tagName.toUpperCase();
    if (['THEAD','TBODY','TR','TD'].include(tagName)) {
      var div = document.createElement('div');
      switch (tagName) {
        case 'THEAD':
        case 'TBODY':
          div.innerHTML = '<table><tbody>' +  html.stripScripts() + '</tbody></table>';
          depth = 2;
          break;
        case 'TR':
          div.innerHTML = '<table><tbody><tr>' +  html.stripScripts() + '</tr></tbody></table>';
          depth = 3;
          break;
        case 'TD':
          div.innerHTML = '<table><tbody><tr><td>' +  html.stripScripts() + '</td></tr></tbody></table>';
          depth = 4;
      }
      $A(element.childNodes).each(function(node){
        element.removeChild(node)
      });
      depth.times(function(){ div = div.firstChild });

      $A(div.childNodes).each(
        function(node){ element.appendChild(node) });
    } else {
      element.innerHTML = html.stripScripts();
    }
    setTimeout(function() {html.evalScripts()}, 10);
    return element;
  }
};

Object.extend(Element, Element.Methods);

var _nativeExtensions = false;

if(/Konqueror|Safari|KHTML/.test(navigator.userAgent))
  ['', 'Form', 'Input', 'TextArea', 'Select'].each(function(tag) {
    var className = 'HTML' + tag + 'Element';
    if(window[className]) return;
    var klass = window[className] = {};
    klass.prototype = document.createElement(tag ? tag.toLowerCase() : 'div').__proto__;
  });

Element.addMethods = function(methods) {
  Object.extend(Element.Methods, methods || {});

  function copy(methods, destination, onlyIfAbsent) {
    onlyIfAbsent = onlyIfAbsent || false;
    var cache = Element.extend.cache;
    for (var property in methods) {
      var value = methods[property];
      if (!onlyIfAbsent || !(property in destination))
        destination[property] = cache.findOrStore(value);
    }
  }

  if (typeof HTMLElement != 'undefined') {
    copy(Element.Methods, HTMLElement.prototype);
    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
    copy(Form.Methods, HTMLFormElement.prototype);
    [HTMLInputElement, HTMLTextAreaElement, HTMLSelectElement].each(function(klass) {
      copy(Form.Element.Methods, klass.prototype);
    });
    _nativeExtensions = true;
  }
}

var Toggle = new Object();
Toggle.display = Element.toggle;

/*--------------------------------------------------------------------------*/

Abstract.Insertion = function(adjacency) {
  this.adjacency = adjacency;
}

Abstract.Insertion.prototype = {
  initialize: function(element, content) {
    this.element = $(element);
    this.content = content.stripScripts();

    if (this.adjacency && this.element.insertAdjacentHTML) {
      try {
        this.element.insertAdjacentHTML(this.adjacency, this.content);
      } catch (e) {
        var tagName = this.element.tagName.toUpperCase();
        if (['TBODY', 'TR'].include(tagName)) {
          this.insertContent(this.contentFromAnonymousTable());
        } else {
          throw e;
        }
      }
    } else {
      this.range = this.element.ownerDocument.createRange();
      if (this.initializeRange) this.initializeRange();
      this.insertContent([this.range.createContextualFragment(this.content)]);
    }

    setTimeout(function() {content.evalScripts()}, 10);
  },

  contentFromAnonymousTable: function() {
    var div = document.createElement('div');
    div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
    return $A(div.childNodes[0].childNodes[0].childNodes);
  }
}

var Insertion = new Object();

Insertion.Before = Class.create();
Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
  initializeRange: function() {
    this.range.setStartBefore(this.element);
  },

  insertContent: function(fragments) {
    fragments.each((function(fragment) {
      this.element.parentNode.insertBefore(fragment, this.element);
    }).bind(this));
  }
});

Insertion.Top = Class.create();
Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(true);
  },

  insertContent: function(fragments) {
    fragments.reverse(false).each((function(fragment) {
      this.element.insertBefore(fragment, this.element.firstChild);
    }).bind(this));
  }
});

Insertion.Bottom = Class.create();
Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(this.element);
  },

  insertContent: function(fragments) {
    fragments.each((function(fragment) {
      this.element.appendChild(fragment);
    }).bind(this));
  }
});

Insertion.After = Class.create();
Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
  initializeRange: function() {
    this.range.setStartAfter(this.element);
  },

  insertContent: function(fragments) {
    fragments.each((function(fragment) {
      this.element.parentNode.insertBefore(fragment,
        this.element.nextSibling);
    }).bind(this));
  }
});

/*--------------------------------------------------------------------------*/

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);
var Selector = Class.create();
Selector.prototype = {
  initialize: function(expression) {
    this.params = {classNames: []};
    this.expression = expression.toString().strip();
    this.parseExpression();
    this.compileMatcher();
  },

  parseExpression: function() {
    function abort(message) { throw 'Parse error in selector: ' + message; }

    if (this.expression == '')  abort('empty expression');

    var params = this.params, expr = this.expression, match, modifier, clause, rest;
    while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
      params.attributes = params.attributes || [];
      params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
      expr = match[1];
    }

    if (expr == '*') return this.params.wildcard = true;

    while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
      modifier = match[1], clause = match[2], rest = match[3];
      switch (modifier) {
        case '#':       params.id = clause; break;
        case '.':       params.classNames.push(clause); break;
        case '':
        case undefined: params.tagName = clause.toUpperCase(); break;
        default:        abort(expr.inspect());
      }
      expr = rest;
    }

    if (expr.length > 0) abort(expr.inspect());
  },

  buildMatchExpression: function() {
    var params = this.params, conditions = [], clause;

    if (params.wildcard)
      conditions.push('true');
    if (clause = params.id)
      conditions.push('element.readAttribute("id") == ' + clause.inspect());
    if (clause = params.tagName)
      conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
    if ((clause = params.classNames).length > 0)
      for (var i = 0, length = clause.length; i < length; i++)
        conditions.push('element.hasClassName(' + clause[i].inspect() + ')');
    if (clause = params.attributes) {
      clause.each(function(attribute) {
        var value = 'element.readAttribute(' + attribute.name.inspect() + ')';
        var splitValueBy = function(delimiter) {
          return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
        }

        switch (attribute.operator) {
          case '=':       conditions.push(value + ' == ' + attribute.value.inspect()); break;
          case '~=':      conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
          case '|=':      conditions.push(
                            splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
                          ); break;
          case '!=':      conditions.push(value + ' != ' + attribute.value.inspect()); break;
          case '':
          case undefined: conditions.push('element.hasAttribute(' + attribute.name.inspect() + ')'); break;
          default:        throw 'Unknown operator ' + attribute.operator + ' in selector';
        }
      });
    }

    return conditions.join(' && ');
  },

  compileMatcher: function() {
    this.match = new Function('element', 'if (!element.tagName) return false; \
      element = $(element); \
      return ' + this.buildMatchExpression());
  },

  findElements: function(scope) {
    var element;

    if (element = $(this.params.id))
      if (this.match(element))
        if (!scope || Element.childOf(element, scope))
          return [element];

    scope = (scope || document).getElementsByTagName(this.params.tagName || '*');

    var results = [];
    for (var i = 0, length = scope.length; i < length; i++)
      if (this.match(element = scope[i]))
        results.push(Element.extend(element));

    return results;
  },

  toString: function() {
    return this.expression;
  }
}

Object.extend(Selector, {
  matchElements: function(elements, expression) {
    var selector = new Selector(expression);
    return elements.select(selector.match.bind(selector)).map(Element.extend);
  },

  findElement: function(elements, expression, index) {
    if (typeof expression == 'number') index = expression, expression = false;
    return Selector.matchElements(elements, expression || '*')[index || 0];
  },

  findChildElements: function(element, expressions) {
    return expressions.map(function(expression) {
      return expression.match(/[^\s"]+(?:"[^"]*"[^\s"]+)*/g).inject([null], function(results, expr) {
        var selector = new Selector(expr);
        return results.inject([], function(elements, result) {
          return elements.concat(selector.findElements(result || element));
        });
      });
    }).flatten();
  }
});

function $$() {
  return Selector.findChildElements(document, $A(arguments));
}
var Form = {
  reset: function(form) {
    $(form).reset();
    return form;
  },

  serializeElements: function(elements, getHash) {
    var data = elements.inject({}, function(result, element) {
      if (!element.disabled && element.name) {
        var key = element.name, value = $(element).getValue();
        if (value != undefined) {
          if (result[key]) {
            if (result[key].constructor != Array) result[key] = [result[key]];
            result[key].push(value);
          }
          else result[key] = value;
        }
      }
      return result;
    });

    return getHash ? data : Hash.toQueryString(data);
  }
};

Form.Methods = {
  serialize: function(form, getHash) {
    return Form.serializeElements(Form.getElements(form), getHash);
  },

  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().each(function(element) {
      element.blur();
      element.disabled = 'true';
    });
    return form;
  },

  enable: function(form) {
    form = $(form);
    form.getElements().each(function(element) {
      element.disabled = '';
    });
    return form;
  },

  findFirstElement: function(form) {
    return $(form).getElements().find(function(element) {
      return element.type != 'hidden' && !element.disabled &&
        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
    });
  },

  focusFirstElement: function(form) {
    form = $(form);
    form.findFirstElement().activate();
    return form;
  }
}

Object.extend(Form, Form.Methods);

/*--------------------------------------------------------------------------*/

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 Hash.toQueryString(pair);
      }
    }
    return '';
  },

  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    return Form.Element.Serializers[method](element);
  },

  clear: function(element) {
    $(element).value = '';
    return element;
  },

  present: function(element) {
    return $(element).value != '';
  },

  activate: function(element) {
    element = $(element);
    element.focus();
    if (element.select && ( element.tagName.toLowerCase() != 'input' ||
      !['button', 'reset', 'submit'].include(element.type) ) )
      element.select();
    return element;
  },

  disable: function(element) {
    element = $(element);
    element.disabled = true;
    return element;
  },

  enable: function(element) {
    element = $(element);
    element.blur();
    element.disabled = false;
    return element;
  }
}

Object.extend(Form.Element, Form.Element.Methods);
var Field = Form.Element;
var $F = Form.Element.getValue;

/*--------------------------------------------------------------------------*/

Form.Element.Serializers = {
  input: function(element) {
    switch (element.type.toLowerCase()) {
      case 'checkbox':
      case 'radio':
        return Form.Element.Serializers.inputSelector(element);
      default:
        return Form.Element.Serializers.textarea(element);
    }
  },

  inputSelector: function(element) {
    return element.checked ? element.value : null;
  },

  textarea: function(element) {
    return element.value;
  },

  select: function(element) {
    return this[element.type == 'select-one' ?
      'selectOne' : 'selectMany'](element);
  },

  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 = function() {}
Abstract.TimedObserver.prototype = {
  initialize: function(element, frequency, callback) {
    this.frequency = frequency;
    this.element   = $(element);
    this.callback  = callback;

    this.lastValue = this.getValue();
    this.registerCallback();
  },

  registerCallback: function() {
    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  onTimerEvent: function() {
    var value = this.getValue();
    var changed = ('string' == typeof this.lastValue && 'string' == typeof value
      ? this.lastValue != value : String(this.lastValue) != String(value));
    if (changed) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  }
}

Form.Element.Observer = Class.create();
Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.Observer = Class.create();
Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
  getValue: function() {
    return Form.serialize(this.element);
  }
});

/*--------------------------------------------------------------------------*/

Abstract.EventObserver = function() {}
Abstract.EventObserver.prototype = {
  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.bind(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();
Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.EventObserver = Class.create();
Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
  getValue: function() {
    return Form.serialize(this.element);
  }
});
if (!window.Event) {
  var Event = new Object();
}

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,

  element: function(event) {
    return event.target || event.srcElement;
  },

  isLeftClick: function(event) {
    return (((event.which) && (event.which == 1)) ||
            ((event.button) && (event.button == 1)));
  },

  pointerX: function(event) {
    return event.pageX || (event.clientX +
      (document.documentElement.scrollLeft || document.body.scrollLeft));
  },

  pointerY: function(event) {
    return event.pageY || (event.clientY +
      (document.documentElement.scrollTop || document.body.scrollTop));
  },

  stop: function(event) {
    if (event.preventDefault) {
      event.preventDefault();
      event.stopPropagation();
    } else {
      event.returnValue = false;
      event.cancelBubble = true;
    }
  },

  // find the first node with the given tagName, starting from the
  // node the event was triggered on; traverses the DOM upwards
  findElement: function(event, tagName) {
    var element = Event.element(event);
    while (element.parentNode && (!element.tagName ||
        (element.tagName.toUpperCase() != tagName.toUpperCase())))
      element = element.parentNode;
    return element;
  },

  observers: false,

  _observeAndCache: function(element, name, observer, useCapture) {
    if (!this.observers) this.observers = [];
    if (element.addEventListener) {
      this.observers.push([element, name, observer, useCapture]);
      element.addEventListener(name, observer, useCapture);
    } else if (element.attachEvent) {
      this.observers.push([element, name, observer, useCapture]);
      element.attachEvent('on' + name, observer);
    }
  },

  unloadCache: function() {
    if (!Event.observers) return;
    for (var i = 0, length = Event.observers.length; i < length; i++) {
      Event.stopObserving.apply(this, Event.observers[i]);
      Event.observers[i][0] = null;
    }
    Event.observers = false;
  },

  observe: function(element, name, observer, useCapture) {
    element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.attachEvent))
      name = 'keydown';

    Event._observeAndCache(element, name, observer, useCapture);
  },

  stopObserving: function(element, name, observer, useCapture) {
    element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.detachEvent))
      name = 'keydown';

    if (element.removeEventListener) {
      element.removeEventListener(name, observer, useCapture);
    } else if (element.detachEvent) {
      try {
        element.detachEvent('on' + name, observer);
      } catch (e) {}
    }
  }
});

/* prevent memory leaks in IE */
if (navigator.appVersion.match(/\bMSIE\b/))
  Event.observe(window, 'unload', Event.unloadCache, false);
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;
  },

  realOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.scrollTop  || 0;
      valueL += element.scrollLeft || 0;
      element = element.parentNode;
    } while (element);
    return [valueL, valueT];
  },

  cumulativeOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
    } while (element);
    return [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 [valueL, valueT];
  },

  offsetParent: 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;
  },

  // 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 = this.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 = this.realOffset(element);

    this.xcomp = x + offsetcache[0] - this.deltaX;
    this.ycomp = y + offsetcache[1] - this.deltaY;
    this.offset = this.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;
  },

  page: 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)
        if (Element.getStyle(element,'position')=='absolute') break;

    } while (element = element.offsetParent);

    element = forElement;
    do {
      if (!window.opera || element.tagName=='BODY') {
        valueT -= element.scrollTop  || 0;
        valueL -= element.scrollLeft || 0;
      }
    } while (element = element.parentNode);

    return [valueL, valueT];
  },

  clone: function(source, target) {
    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 = Position.page(source);

    // find coordinate system to use
    target = $(target);
    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(target,'position') == 'absolute') {
      parent = Position.offsetParent(target);
      delta = Position.page(parent);
    }

    // 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)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
    if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
    if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
    if(options.setHeight) target.style.height = source.offsetHeight + 'px';
  },

  absolutize: function(element) {
    element = $(element);
    if (element.style.position == 'absolute') return;
    Position.prepare();

    var offsets = Position.positionedOffset(element);
    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';
  },

  relativize: function(element) {
    element = $(element);
    if (element.style.position == 'relative') return;
    Position.prepare();

    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;
  }
}

// Safari returns margins on body which is incorrect if the child is absolutely
// positioned.  For performance reasons, redefine Position.cumulativeOffset for
// KHTML/WebKit only.
if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
  Position.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 [valueL, valueT];
  }
}

Element.addMethods();/*-------------------- External Js Dependency Management ---------------------------*/
function w3gIncludeJs(filename){ 
	if(w3gIsJsIncluded(filename)==true)return;
	document.write('<script type="text/javascript" src="/'+window.w3gContex+'/'+filename+'"></script>');

}
function w3gIsJsIncluded(filename)
{ 	
	if (window.document.getElementsByTagName) {
	   var inclusion = document.getElementsByTagName('head')[0].getElementsByTagName("script");
	   for (i = 0; i < inclusion.length; i++) {
	   	var obj = inclusion[i];
	   	if(obj && obj.src){
	   		if(obj.src.toString().indexOf(filename)>-1) return true;
	   }
	  }
	}
	return  false;
}

/*-------------------- openPop ----------------------------------*/
function openPop(myIndirizzo, myTarget, popTitle, option ){ 
	if(myTarget && myTarget!=null && typeof myTarget != 'undefined'){
		try {// forzo la chiusura della finestra precedentemente aperta per permettere l'apertura con dimensione corretta
			popUpWindow = window.open('/'+window.w3gContex+'/portal/pageBlank.jsp',myTarget,winOpt);
			if (!popUpWindow.closed) popUpWindow.close();
		} catch (e) {/*DO NOTHING*/}
	}
	
	if ((popTitle) && (popTitle!=null) && (popTitle.length>0))
		myIndirizzo += (myIndirizzo.indexOf("?")>=0 ? "&" : "?") + "popTitle="+popTitle;
		
	if (getW3gParameterCheck("idDevice=mobile"))
		myTarget =  "_top";
	//2007.07.24@IV fix openpop from pop, target must be setted otherwise 'access denied'
	if (myTarget==null) myTarget = "_blank";
		
	if (option==null){
		var viewport = window.screenDimensions();		
		// 2008.05.05@FC REMOVED, resolution 90%x80% only for media...
		//var defaultOption = 'width='+(screen.width*0.9)+',height='+(screen.height*0.8)+',status=yes,resizable=yes,scrollbars=yes,toolbar=no,menubar=no';
		var defaultOption = 'width=510,height=580,status=yes,resizable=yes,scrollbars=yes,toolbar=no,menubar=no,top=20px,left=20px';
		if (/*myIndirizzo.indexOf("show?")>=0 && */myTarget!="_top") {					
			var myIdMedia = null;
			if(myIndirizzo.indexOf("show?")>=0){
				myIdMedia = myIndirizzo.substr(myIndirizzo.indexOf("show?")+(("show?").length));
			}else if(myIndirizzo.indexOf("popupMedia.do?id=")>=0){				
				myIdMedia = myIndirizzo.substr(myIndirizzo.indexOf("popupMedia.do?id=")+(("popupMedia.do?id=").length));
			}			
			if(myIdMedia!=null){
				myIdMedia = myIdMedia.match(/\d*/g)[0];
				var myMedia = new w3gMedia(myIdMedia);
				myMedia.load(function(){w3gOpenPop4MediaAjax(myMedia,myIndirizzo,myTarget)});				
				return;
			}else{
				//2008.04.28@FC open window with 90% user screen resolution 
				option = defaultOption;
			}
		} else{
			option = defaultOption;
		}
	}
	window.open(myIndirizzo, myTarget, option).focus();
}  
function w3gOpenPop4MediaAjax(mediaObj,requestUrl,myTarget){
	//if (myTarget==null) myTarget = "_blank"; 
	var winOpt = "status=yes,resizable=yes,toolbar=no,menubar=no";			
	if(mediaObj.isImage()){		
		try {	
			var myImage = mediaObj.getImage();
			var iw = mediaObj.getImageWidth()
			if(iw==null || iw<=0)iw = myImage.width;
			var ih = mediaObj.getImageHeight()
			if(ih==null || ih<=0)ih = myImage.height;
			//if (iw>50||ih>50)	
			
			//21.08.2008@MV if image is larger than screen dimensions show scrollbars
			var screen = window.screenDimensions();	
			if (ih>screen.height || iw>screen.width)
				winOpt += ",scrollbars=yes";
				
			winOpt += ",width="+(iw+20)+",height="+(ih+25)+"";			
		}catch(err){winOpt += ",width=100,height=100";}
	}else{
		//2008.04.28@FC open window with 90% user screen resolution 
		var screen = window.screenDimensions();		
		winOpt += ",width="+(screen.width*0.9)+",height="+(screen.height*0.8);	
	}	
	window.open( (requestUrl || mediaObj.getUrl()), myTarget, winOpt).focus();
}
var myTtFunction = new function(){};
/* ---------------- openPop4Media with autosizing for true image objects -----------------*/
var cntPict=0;
var idPict=new Array();

function openPop4Media(img, target){
	if (target==null) target = "_blank"; //2007.07.24@IV fix openpop from pop, target must be setted otherwise 'access denied'
	cntPict++;
	idPict[cntPict] = new Image();
	idPict[cntPict].src = img;
	idPict[cntPict].target = target;
	targetWin = window.open("/"+window.w3gContex+"/portal/pageBlank.jsp", target, "width=100,height=100"); //2006.05.03@FV fix "openpop from pop"
	if (targetWin!=window) targetWin.close(); //close pre-opened target window 
	var interrupt = "viewPop4Media("+cntPict+")";  
	setTimeout( interrupt, 200 ); // set delay to allow data download
}
function viewPop4Media(id){
	var winOpt = "status=yes,resizable=yes,toolbar=no,menubar=no";
	try {
		if (idPict[id].width>50||idPict[id].height>50)	
		winOpt += ",width="+(idPict[id].width+20)+",height="+(idPict[id].height+25);
	} catch (e) {}
	var popUpWindow = window.open(idPict[id].src, idPict[id].target, winOpt);
	if (popUpWindow!=null) popUpWindow.focus();
}

/*-------------------- getW3gDocumentURL ---------------------------*/
function getW3gDocumentURL(){
	var urlLimit = document.URL.indexOf("?");
	var strUrl = document.URL.substring( 0, (urlLimit>0 ? urlLimit : document.URL.length));
	if (w3gItemAndSezione!=null) strUrl += "?"+w3gItemAndSezione;
	return strUrl;
} 
/*-------------------- getW3gDocumentURL ---------------------------*/
function getW3gParameterCheck( p ){
	try {
		var w3gp = w3gItemAndSezione.split("&");
		for (var i=0; i<w3gp.length; i++) {
			if (w3gp[i]==p) return true;
		}
	} catch (err) {};
	return false;
} 
/*-------------------- language ----------------------------------*/
//var var w3gItemAndSezione; 2008.05.29@FC FIX, in mobile devices redraw with undefined SezioneMetaTile w3gItemAndSezione in page.
//23-07-2008@IV w3gItemAndSezione cannot be undefined; next check statement destroys the meaning of w3gItemAndSezione in mobile javascript engine
//if(typeof w3gItemAndSezione == 'undefined')var w3gItemAndSezione=false;

//2006.09.25@FV fix "location" value is not persistent on IE browser.
//2007.02.21@FV fix clear idLanguage parameter if present in qs
function language(idLanguage) {
	var strUrl = getW3gDocumentURL().replace(/#.*/g,"");
	var args = strUrl.split("&");
	var newUrl="";
	for (var i=0; i<args.length; i++) {
	 newUrl += (args[i].indexOf("idLanguage")>=0 ) ? "" : (i>0?"&":"")+args[i];
	}
	newUrl += (newUrl.indexOf("?")>0 ? "&":"?") + "idLanguage=" + idLanguage;
	window.open(newUrl,'_self','');
}
/*--------------------------- onloadFunctionAppender ----------------------*/
function onloadAddFunction( fnctn ) {
	if (window.addEventListener) 
		window.addEventListener( 'load', fnctn, false );
	else if (window.attachEvent)  
		window.attachEvent( 'onload', fnctn );
	else window.onLoad = fnctn;
}
/*-------------------- openerWindow ----------------------------------*/
//23.05.2008@FV-FC ADD mobile exception managment - 25.07.08@FV fix
function openerWindow( url ) {
var win;
try {
	if (getW3gParameterCheck("idDevice=mobile"))
		win = window.open( url, '_self','');
	else if (typeof opener != 'undefined' && opener!=null)
		win = opener.window.open( url, '_self','');
} catch (e) { 
	if (confirm("W3G lost synchronization. Please re-load main page"))
		window.close();
}
return win;
}

/*-------------------- formatData ----------------------------------*/
var w3gDateExclusive = false;

function w3gDateAlert(message,obj){
	if(!w3gDateExclusive){
		w3gDateExclusive=true;
		w3gAlert(message,w3gDateCallback.bind(null,obj));
	}
}
function w3gDateCallback(obj){
	w3gDateExclusive=false;
	if(obj)obj.focus();
}
function formatData(campo){
   app = campo.value;
   lungh = app.length;
   // put the separator during the typing
   if(lungh == 3 || lungh == 6) campo.value = campo.value.substring(0,lungh-1) + "-";
   if(lungh == 11) campo.value = campo.value.substring(0,lungh-1) + " ";
   if(lungh == 14) campo.value = campo.value.substring(0,lungh-1) + ":";
} // formatData

/*------------------------- isDateTime ---------------------------------*/
function isDateTime(dateTime, messDescr, messFormat, messNumDays, messFebruary, messMonth, messYear, fullCondition) {
	var dateTimeStr = dateTime.value;
	var isOk = false;
	dateTime.value = (dateTimeStr.length>10) ? dateTimeStr.substring(0,10) : dateTimeStr; // isDate() need html object
	if (isDate(dateTime, messDescr, messFormat, messNumDays, messFebruary, messMonth, messYear, fullCondition) ) {
		dateTime.value = dateTimeStr;
		var timeStr  = (dateTimeStr.length>10) ? dateTimeStr.substring(11) : dateTimeStr;
		isOk = isTime( timeStr, messDescr, messFormat ,dateTime);
		if (!isOk) dateTime.focus();
	}
	return isOk;
}

/*------------------------- isTime ---------------------------------*/
function isTime(timeCrt, messDescr, messFormat ,dateObj){
   var timePat = /^(\d{2})(\:)(\d{2})$/;
   var matchArray = timeCrt.match(timePat); // il formato č corretto?

   if(matchArray == null && timeCrt != "") {
	  w3gDateAlert(messDescr + " : " + messFormat);
      return false;
   }

   if(matchArray != null)  {    
	   hh = matchArray[1];
   	mm = matchArray[3];
   	if (!(hh.length==2 && hh>="00" && hh<"24" && mm.length==2 && mm>="00" && mm<"60" )) {
	   	w3gDateAlert(messDescr + " : " + messFormat,dateObj);
      	return false;
      }
   }  

   return true;
}//isTime*/

/*------------------------- isDate ---------------------------------*/
function isDate(dateObj, messDescr, messFormat, messNumDays, messFebruary, messMonth, messYear, fullCondition) {
   dateCrt = dateObj.value;
   var datePat = /^(\d{2})(\-)(\d{2})(\-)(\d{4})$/;
   var matchArray = dateCrt.match(datePat); // il formato č corretto?
   if(matchArray == null && dateCrt != "") {
	   w3gDateAlert(messDescr + " : " + messFormat,dateObj);
	   //dateObj.focus();
      return false;
   }  
   if(matchArray != null)  {    
      day = matchArray[1];
      month = matchArray[3];
      year = matchArray[5];
    	// look the format
    	if (! checkDataValue("" + day, "" + month, "" + year, messDescr, messNumDays, messFebruary, messMonth, messYear, fullCondition, dateObj) != "" ) {
		  // dateObj.focus();
  			return false;
  		}
	}
   return true;
} // isDate


/*-------------------------- checkDataValue ------------------------*/
function checkDataValue(valGG, valMM, valYY, messDescr, messNumDays, messFebruary, messMonth, messYear, fullCondition,dateObj){
   dataFormatted = "";
   if(valMM != "" && valGG != "" && valYY != "") {
      if (valGG > "31") { // more than 31 days
         w3gDateAlert (messDescr + " : "+ messNumDays,dateObj );
         return dataFormatted;
      }
      if(valGG == "31") { // 31 days
         if(valMM == "04" || valMM == "06" || valMM == "09" || valMM == "11") {
            w3gDateAlert (messDescr + " : " + messNumDays,dateObj );
            return dataFormatted;
         }
      }
      if(valMM == "02") { // feb with 28 days
         if (valGG > "29") {
            w3gDateAlert (messDescr + " : " + messNumDays,dateObj );
            return dataFormatted;
         }
   	   // look if the number of days is 28 or 29 (leap year)
			var data = new Date(valYY, parseInt(valMM), 1);
         data = new Date(data - (24 * 60 * 60 * 1000));
         numDaysInMonth = data.getDate();
			if(parseInt(valGG) > parseInt("" + numDaysInMonth)) {
            w3gDateAlert (messDescr + " : " + messFebruary,dateObj);
            return dataFormatted;
         }
      }
      // check the month
      if(valMM < "01" || valMM > "12") {
         w3gDateAlert (messDescr + " : " + messMonth,dateObj);
         return dataFormatted;
      }
         
      if (fullCondition) {
        	// check the year only if fullCondition IS TRUE
      	if(valYY < "1900") {
         	w3gDateAlert (messDescr + " : " + messYear,dateObj);
         	return dataFormatted;
      	}
      }
   }
   // returns the formatted data
   dataFormatted = valGG + "/" + valMM + "/" + valYY;
   return dataFormatted;
} // checkDataValue
  
/*-------------------------- adjustIFrameSize ------------------------*/
function adjustIFrameSize(iframeWindow) {
  if (iframeWindow.document.height) {
    var iframeElement = parent.document.getElementById(iframeWindow.name);
    iframeElement.style.height = iframeWindow.document.height + 'px';
    iframeElement.style.width = iframeWindow.document.width + 'px';
  }
  else if (document.all) {
    var iframeElement = parent.document.all[iframeWindow.name];
    if (iframeElement) {
	    if (iframeWindow.document.compatMode &&
	        iframeWindow.document.compatMode != 'BackCompat') 
	    {
	      iframeElement.style.height = iframeWindow.document.documentElement.scrollHeight + 'px';// + 5 + 'px';
	      iframeElement.style.width = iframeWindow.document.documentElement.scrollWidth + 'px';// + 5 + 'px';
	    }
	    else {
	      iframeElement.style.height = iframeWindow.document.body.scrollHeight + 'px';// + 5 + 'px';
	      iframeElement.style.width = iframeWindow.document.body.scrollWidth + 'px';// + 5 + 'px';
	    }
		 //move scrollbar to display window
		 parent.window.scrollTo(iframeWindow.screenLeft-iframeElement.style.pixelWidth,iframeWindow.screenTop-iframeElement.style.pixelHeight)
	}
  }
}

/*----------------------------- hideAdmin ----------------------------*/
function hideAdmin() {
	displayAdmin( window.name, "none", "none" );
}
  		  
/*----------------------------- showAdmin ----------------------------*/
function showAdmin( winName, noCover ) {
	displayAdmin( winName, "block", "none", noCover );
}

/*----------------------------- displayAdmin ----------------------------*/
function displayAdmin( winName, mode, modeInnerWin, noCover ) {

  if (winName == 'w3gAdminFrame') {

	   if (noCover==null || !noCover) {
		   // admin window blocks/releases browser page 
	  	   window.top.displayCover( 'Page', mode );
		   // admin window blocks/releases control panel
	  	   panel=window.open('','w3gPanel','height=1,width=1,status=no,toolbar=no,menubar=no,titlebar=no,scrollbar=no');
	  	   if (panel!=null)
		  	  try { panel.displayCover( 'Panel', mode ); } catch (e) { panel.close() }
	   }

	   window.parent.w3gAction.style.display=modeInnerWin;
	   window.parent.w3gList.style.display  =modeInnerWin;
	   window.parent.w3gAdmin.style.display =mode;

	   //reduce frame to 1x1 px, new content will resize window!  
	   hideFrame(window.parent.w3gActionFrame.window);
	   hideFrame(window.parent.w3gListFrame.window);
	   hideFrame(window.parent.w3gAdminFrame.window);
  }
  
  if (winName == 'w3gListFrame') {
	   window.parent.w3gAction.style.display=modeInnerWin;
	   window.parent.w3gList.style.display  =mode;
	   
	   hideFrame(window.parent.w3gActionFrame.window);
	   hideFrame(window.parent.w3gListFrame.window);
  }
  
  if (winName == 'w3gActionFrame') {
	   window.parent.w3gAction.style.display=mode;

  	   hideFrame(window.parent.w3gActionFrame.window);
  }	
  
  //2008.04.17@MV added w3gPanelFrame for added functionalities (for example w3gMap)
  if (winName == 'w3gPanelFrame') {
	   window.parent.w3gPanel.style.display=mode;

  	   hideFrame(window.parent.w3gPanelFrame.window);
  }	
}

/*---------------------------- hideFrame ------------------------------*/
function hideFrame (iframeWindow) {
  if (iframeWindow.document.height) {
    var iframeElement = parent.document.getElementById(iframeWindow.name);
    iframeElement.style.height = '1px';
    iframeElement.style.width = '1px';
  }
  else if (document.all) {
    var iframeElement = parent.document.all[iframeWindow.name];
    if (iframeWindow.document.compatMode &&
        iframeWindow.document.compatMode != 'BackCompat') 
    {
      iframeElement.style.height = '1px';
      iframeElement.style.width  = '1px';
    }
    else {
      iframeElement.style.height = '1px';
      iframeElement.style.width  = '1px';
    }
  }
}
/*2006.07.27@FV----------------------------- coverAdmin ----------------------------*/
coverStyleFilter="Alpha(Opacity=35, FinishOpacity=35, Style=2, StartX=50, StartY=50, FinishX=0, FinishY=0)"; 
function displayCover( name, status, msg ) {

	var cover = document.getElementById("w3g"+name+"Cover");
	var wait = document.getElementById("w3g"+name+"Wait");
	if (cover!=null) {
		if (status=='block') {
			try { // to extend cover to current window height&width.....
				cover.style.height= document.getElementById("w3gEndPage").offsetTop;
				cover.style.width= document.getElementById("w3gEndPage").offsetLeft;
			} catch (e) {}
			cover.style.filter = coverStyleFilter;
		}
		cover.style.display = status;
		//alert( "displayCover() w3g"+ name + "Cover = "+ status );
	}	
	if (wait!=null) {
		wait.style.display = status;
		//alert( "displayCover() w3g"+ name + "Wait = "+ status );
		if (msg!=null) wait.innerText = msg;
	}		
}
/*---------------------------- normalizeUTF8 ------------------------------*/
if (document.layers) { //in Netscape4 always filtered!
	window.captureEvents(Event.KEYPRESS);
	window.onkeypress = normalizeUTF8;
}
function normalizeUTF8( evt ) {
	wkc = (evt.which || evt.keyCode || evt.charCode);
	return (wkc<255)&&(wkc!=128);
}

/*2005.07.18@FV new--------------------------------- isEmail ------------------------------*/
function isEmail (s){
   if (s.length == 0) return (false);
   i = s.indexOf(" ");
   if (i > 0) return (false);
   indiceAt = s.indexOf("@");
   if (indiceAt <= 0) return (false);
   indiceUltimoPunto = s.lastIndexOf(".", s.length);
   if (indiceUltimoPunto <= 0) return (false);
   nomeDominio = s.substring((indiceAt+1), indiceUltimoPunto);
   if (!isDomainName(nomeDominio,1)) return (false);
   topLevelDomain = s.substring((indiceUltimoPunto+1), s.length);
   if (!isDomainName(topLevelDomain,2))  return (false);

   return (true);
}

/*2005.07.18@FV new------------------------------------- isDomainName ----------------------------*/
function isDomainName(checkStr, minLength){
  if (checkStr.length < minLength) return false;
  var checkOK = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-.";
  var allValid = true;
  for (i = 0;  i < checkStr.length; i++)
  {
    ch = checkStr.charAt(i);
    for (j = 0;  j < checkOK.length; j++)
      if (ch == checkOK.charAt(j))
        break;
    if (j == checkOK.length)
    {
      allValid = false;
      break;
    }
  }
  return allValid;
}

/*2005.09.01@FV new------------------------------------- myInnerText ----------------------------*/
function myInnerText( xStr ) {
   var regExp = /<\/?[^>]+>/gi;
   xStr = xStr.replace(regExp,"");
   return xStr;
}

/*2006.07.18@FV new------------------------------------- set/get cookie ----------------------------*/
function getCookie( cookieName ) {
	var cookieJar = document.cookie.split( "; " );
	for( var x = 0; x < cookieJar.length; x++ ) {
		var oneCookie = cookieJar[x].split( "=" );
		if( oneCookie[0] == escape( cookieName ) ) { 
		return unescape( oneCookie[1] ); 
		}
	}
	return null;
}

function setCookie( cookieName, cookieValue, lifeTime, path, domain, isSecure ) {
	if( !cookieName ) { return false; }
	if( lifeTime == "delete" ) { lifeTime = -1; } //this is in the past. Expires immediately.
	/* document.cookie = newValue is equivalent to document.cookie = newValue + "; " + document.cookie; */
	document.cookie = escape( cookieName ) + "=" + escape( cookieValue ) +
		( lifeTime ? ";expires=" + ( new Date( ( new Date() ).getTime() + ( 1000 * lifeTime ) ) ).toGMTString() : "" ) +
		( path ? ";path=" + path : "") + ( domain ? ";domain=" + domain : "") + 
		( isSecure ? ";secure" : "");
	//check if the cookie has been set/deleted as required
	if( lifeTime < 0 ) { if( typeof( getCookie( cookieName ) ) == "string" ) { return false; } return true; }
	if( typeof( getCookie( cookieName ) ) == "string" ) { return true; } return false;
}

/*2006.07.18@FV new------------------------------------- hotkey check ----------------------------*/
function isJSHotKeyActive(){
	var fname=''+document.onkeypress;
	var hkfname='HotKey';
	if (fname==''||fname==null) return false;
	// recupera il nome della funzione dal corpo
	if(fname.substr(0,'function'.length).toLowerCase()=='function')
		fname=fname.substr('function'.length+1,fname.indexOf('(')-('function'.length+1));
	return fname==hkfname?true:false;
}

/*2007.04.23@FV new------------------------------------- tags visibility ----------------------------*/
function hideTags(elemID) {
	setTagsVisibility( elemID, "hidden" );
}
function showTags(elemID) {
	setTagsVisibility( elemID, "visible" );
}
function setTagsVisibility(elemID, status) {
	 if (window.document.all) {
	   for (i = 0; i < document.all.tags(elemID).length; i++) {
		obj = document.all.tags(elemID)[i];
		if (! obj || ! obj.offsetParent) {alert(i + ' skipped');continue;}
		obj.style.visibility = status;
	   }
	 }	
	 if (parent.frames["result_set"]!=null) {   
	   for (i = 0; i < result_set.document.all.tags(elemID).length; i++) {
		 obj = result_set.document.all.tags(elemID)[i];
		 if (! obj || ! obj.offsetParent) 
		 	continue;
		 obj.style.visibility = status;
	   }
	 }
}
/*2007.05.15@FV ----------------------------- WAI facility ------------------*/
function w3gFixBadAnchorsAttributes() {
	try {
		 if (window.document.getElementsByTagName) {
		   var anchors = window.document.getElementsByTagName("A");	   
		   for (i = 0; i < anchors.length; i++) {
		   	 var obj = anchors[i];
		   	 if (! obj || ! obj.offsetParent) continue;
		   	 w3gAdjustOpenPopAnchorTitle(obj);
		   	 w3gExternalAnchorURLWrapping(obj);	
		   	 w3gApplyContexRootToAnchorURL(obj);	
		   	 
		   	 /*2008.02.05@MV esegue altre funzioni dichiarate all'interno dell'array di funzioni
		   	 w3gAnchorFunctionArray dichiarato all'intero del media
		   	 */
		   	 if(typeof(w3gAnchorFunctionArray)!='undefined'){
		   	 	if(w3gAnchorFunctionArray!=null)
		   	 		for(j=0;j<w3gAnchorFunctionArray.length;j++)
w3gAnchorFunctionArray[j](obj);
      		}
             	 		 			
		   }	
	   	}
	}catch (e) {/*alert(e)*/
	}
}

function w3gAdjustOpenPopAnchorTitle(obj){
	if(w3gUtils.Undefined(obj))return;	
	try {	
	  var w3gSN = location.host;
	  var w3gCTX = "/" + window.w3gContex;
      if (waiOpenPopKeywords && waiOpenPopAlert && waiOpenPopAttachment) {	   
			//if (! obj || ! obj.offsetParent) continue;
			// 2008.09.16@SO fix su controllo waiOpenPopKeywords e previene che venga settato il titolo pių di una volta
			if ((obj.href.indexOf("openPop(")>=0) && 
			    (!new RegExp(waiOpenPopKeywords.replace(/,/g,'|')).test(obj.title)) &&
//				(obj.title.length==0 || waiOpenPopKeywords.indexOf(obj.title)<0)) { //not already set via cms
				(obj.title.length==0 || (obj.title.indexOf(waiOpenPopAttachment)<0 && obj.title.indexOf(waiOpenPopAlert)<0))) { //not already set via cms
					var txt="";
					if (obj.href.indexOf("media/show")>=0) //link to an attachment
						txt = waiOpenPopAttachment;
					else
						txt = waiOpenPopAlert;
					obj.title = (obj.title.length>0) ? obj.title+". "+txt : txt;
			}
   	  }
  } catch(e) {/*alert(e)*/} 
}

function w3gExternalAnchorURLWrapping(obj) {
	if(w3gUtils.Undefined(obj))return;
	var original_href = obj.href;			  		  
  	try {		 
  		var w3gSN = location.host;
  		var w3gCTX = "/" + window.w3gContex;   
		var href_lower = obj.href.toLowerCase();
		if ((href_lower.indexOf("http://")>=0 || href_lower.indexOf("https://")>=0) && obj.href.indexOf(w3gSN)<0) {
		 /*2007.07.21@IV redraw external links for redirect*/
			var new_href = obj.href;
			if (href_lower.indexOf("javascript")>=0) {
		 		var my_href = new_href;
	  			new_href = my_href.substring(0,my_href.indexOf("'")+1);
	  			my_href = my_href.slice(my_href.indexOf("'")+1);
	  			new_href = new_href + escape(my_href.substring(0,my_href.indexOf("'"))) + my_href.slice(my_href.indexOf("'"));  		
		  	} else {
		  		new_href = escape(obj.href);  		
		  	}
		  	//obj.href = new_href.replace(new RegExp("http","i"),"externalUrl.jsp?url=http");
	  	} else {
		  	/*2007.07.21@IV redraw internal links for media*/
		    if (obj.href.indexOf("openPop")>=0 && obj.href.indexOf("media/show?")>=0)
	    		obj.href = obj.href.replace("media/show?","popupMedia.do?id=");  
		}
   } catch(e) {obj.href=original_href;}
}

function w3gApplyContexRootToAnchorURL(obj) {
	if(w3gUtils.Undefined(obj))return;
	try {
	 	var w3gSN = location.host;
  	 	var w3gCTX = "/" + window.w3gContex; 	  		  
   	  	var original_href = w3gUtils.Undefined(obj.getAttribute('href'))?null:obj.getAttribute('href');	
	  	var openPopRegExp = new RegExp("(javascript(?: )?:(?: )?openPop(?: )?\\((?: )?')","i");
   	  	if(w3gUtils.Nullalize(original_href)!=null){
 	 		var new_href = w3gUtils.Trim(original_href);
     	 	var lnew_href=  new_href.toLowerCase();
     	 	if(lnew_href.indexOf('/')!=0
	     	 	&& lnew_href.indexOf('javascript:')<0
&& lnew_href.indexOf('#')!=0
	     	 	&& lnew_href.indexOf('http:')!=0
	     	 	&& lnew_href.indexOf('https:')!=0	
	     	 	&& lnew_href.indexOf('mailto:')<0	){
   	 	 		new_href = w3gCTX+'/'+ new_href;
	   	 	 	obj.setAttribute('href',new_href);		   	 	 	
	     	 }else if(
	     	 	new_href.match(openPopRegExp)&&
	     	 	(!new_href.match(new RegExp("'( )?http",'i')))&&
				(!new_href.match(new RegExp("'( )?/",'i')))
	     	 ){
	     	 	new_href = new_href.replace(openPopRegExp,'$1'+w3gCTX+'/')		     	 	
	     	 	obj.removeAttribute('href');
	   	 	 	obj.setAttribute('href',new_href);		   	 	 		     	 
	     	 }
     	}
	}catch(e){/*alert(e)*/} 
}


/*2008.02.05@MV Funzione per la generazione di Help balloons da associare alle chiamate al Wrapper */
var w3gWrapperCalled=0;
var w3gHelpBalloons=new Array();

function w3gAdjustWrapperUrl(obj) {
	  try {
	    var href = obj.href;
	    if (href.indexOf("W3GWrapper?W3GAction=help")>=0) {
		    //trova la prima occorrenza del carattere '
		    var indexOfWrapperUrl = href.indexOf("'");
		    var wrapperUrl = href.substring(indexOfWrapperUrl+1);
		    //trova la seconda occorrenza del carattere '
		    var indexOfLastChar = wrapperUrl.indexOf("'");
		    // estrae l'url della chiamata al wrapper
		    wrapperUrl = wrapperUrl.substring(0,indexOfLastChar);
		    // associa una id incrementale all'ancora (per poterci associare un evento)
		    obj.id='w3gHelpBalloon'+w3gWrapperCalled;
		      
		    //trova il titolo di default
		    var patternForTitleStart = "W3GAction=";
		    var patternForTitleEnd = "\&";
		     
		    var indexForTitleStart = wrapperUrl.indexOf(patternForTitleStart);
		    var indexForTitleEnd = wrapperUrl.indexOf(patternForTitleEnd);
		    var title = wrapperUrl.substring(indexForTitleStart+patternForTitleStart.length,indexForTitleEnd); 
		    // estrae l'url della chiamata al wrapper
		    wrapperUrl = wrapperUrl.substring(0,indexOfLastChar);

            if(typeof(w3gCostumizedHelpBalloon)=='function') {
                // deve essere definita la funzione w3gCostumizedHelpBalloon nella quale passare tutti
                // i parametri necessari alla generazione dell'help balloons (si veda esempio helpBalloons.js)
                w3gWrapperCalled++;
                w3gHelpBalloons[obj.id] = w3gCostumizedHelpBalloon(obj.id, title, wrapperUrl);
		    	obj.href="javascript: void(0);";  
		    	obj.title = title;
		    }
	   }	     
	 } catch(e) {/*alert(e)*/} 
}


onloadAddFunction(w3gFixBadAnchorsAttributes);

//2008.04.28@FC get user's screen resolution.
window.screenDimensions= function() {
   var width = window.innerWidth || (window.document.documentElement.clientWidth || window.document.body.clientWidth);
	var height = window.innerHeight || (window.document.documentElement.clientHeight || window.document.body.clientHeight);
	return {
        height: parseInt(height||0, 10),
        width: parseInt(width||0, 10)
   	 }; 
}
//2008.04.28@FC get window full dimension (scrollSize included).
window.dimensions=  function() {
	var width = document.all ? Math.max(Math.max(document.documentElement.offsetWidth, document.documentElement.scrollWidth), document.body.scrollWidth) : (document.body ? document.body.scrollWidth : ((document.documentElement.scrollWidth != 0) ? document.documentElement.scrollWidth : 0));
    var height = document.all ? Math.max(Math.max(document.documentElement.offsetHeight, document.documentElement.scrollHeight), Math.max(document.body.offsetHeight, document.body.scrollHeight)) : (document.body ? document.body.scrollHeight : ((document.documentElement.scrollHeight != 0) ? document.documentElement.scrollHeight : 0));
	
	return {
        height: parseInt(height||0, 10),
        width: parseInt(width||0, 10)
   	 };     
}
//2008.04.28@FC get the current viewport on user browser.
window.viewportDimensions= function() {
    var intH = 0, intW = 0;
        
    if(self.innerHeight) {
       intH = window.innerHeight;
       intW = window.innerWidth;
    } 
    else if(document.documentElement && document.documentElement.clientHeight) {
            intH = document.documentElement.clientHeight;
            intW = document.documentElement.clientWidth;
    }
    else if(document.body) {
            intH = document.body.clientHeight;
            intW = document.body.clientWidth;
    }
    return {
        height: parseInt(intH, 10),
        width: parseInt(intW, 10)
    };
}

var w3gCSS = {
	css_namePrefix: 'generali',
    css_cookieId: 'w3gStyleSheet'
}

w3gCSS.reloadCSS = function(url){
    if(!url)url=getW3gDocumentURL();
	window.open(url,'_self','');		
}
w3gCSS.changeParam = function(name,value){
	var args = getW3gDocumentURL().split('&');
	var newUrl='';
	for (var i=0; i<args.length; i++) {
	 newUrl += (args[i].indexOf(name)>=0 ) ? '' : (i>0?'&':'')+args[i];
	}
	newUrl += (newUrl.indexOf('?')>0 ? '&':'?') + name+'=' + value;
	w3gCSS.reloadCSS(newUrl);
}
w3gCSS.setFontSize = function(preferredStyle) {
	if(!preferredStyle)preferredStyle=w3gCSS.css_namePrefix;
	setCookie(w3gCSS.css_cookieId+'-fontSize',preferredStyle,0,'/');	
	w3gCSS.changeParam('fontSize',preferredStyle);
}

w3gCSS.setContrast = function(preferredStyle) {
	if(!preferredStyle)preferredStyle=w3gCSS.css_namePrefix;
	setCookie(w3gCSS.css_cookieId+'-contrast',preferredStyle,0,'/');	
	w3gCSS.changeParam('contrast',preferredStyle);
}

w3gCSS.toggleContrast = function() {
	var args = getW3gDocumentURL().split('&');
	var value = null;
	for (var i=0; i<args.length; i++) {
	  if(args[i].indexOf('contrast')==0 )
			value=args[i].split('=')[1];
	}
	value = value=='null' ? 'dark' : 'null';
	w3gCSS.setContrast(value);
}

//08.11.07@FC Classe di utilitā;
function w3gUtils(){return;}
w3gUtils.Undefined = function(variable){
	return typeof(variable)=='undefined';
}
w3gUtils.Trim= function (toTrim){
	if(w3gUtils.Undefined(toTrim))throw 'w3gUtils.Trim require parameter';
	while (toTrim.substring(0,1) == ' ')
		toTrim = toTrim.substring(1, toTrim.length);
	while (toTrim.substring(toTrim.length-1, toTrim.length) == ' ')
		toTrim = toTrim.substring(0,toTrim.length-1);
	return toTrim;
}	
w3gUtils.Nullalize = function (toNull){
	if(w3gUtils.Undefined(toNull))throw 'w3gUtils.Nullalize require parameter';
    if(toNull==null)return toNull;
    return w3gUtils.Trim(toNull)==''? null : toNull;
}
w3gUtils.NullToBlank = function (toBlank){
    if(w3gUtils.Undefined(toBlank))throw 'w3gUtils.NullToBlank require parameter';
    if(toBlank==null)return '';
    return toBlank;
}
w3gUtils.Version= function(){
	var release ='1';
	var major='0';
	var minor='0';		
	this.release=release;this.major=major;this.minor=minor;	
	function fullVersion(){	return release+'.'+major+'.'+minor; }
	return fullVersion();
}
//ritorna il contex w3g o quello contenuto nella location
w3gUtils.Contex = function(){
	return window.w3gContex || location.pathname.split("/")[1];
}

if(!window.find){
	window.find=function (pattern){	
	    if(!pattern || pattern=='')return false;
		var textRange = document.body.createTextRange();
	    var found = textRange.findText(pattern); 
	    if(found){
	      try{textRange.select();}catch(err){/*IE6 CSS bug, unselectable text*/}
	      textRange.scrollIntoView();  
	    }
		return found;
	}
}
/** STRING EXTENSION ******************************************************************************************************/
String.encodeHTML= function(text){
  var len = text.length, escaped='', thisChar = '';
  for (var i=0; i < len; ++i)  {
    thisChar = text.substring(i, i+1);
    var codeChar = thisChar.charCodeAt(0);
    if (codeChar>160) thisChar="&#"+codeChar+";";    
    escaped += thisChar;         
  }
  return escaped;
}
String.prototype.encodeHTML= function(){
  return String.encodeHTML(this);
}
String.decodeHTML=function(text){
  var match = text.match(/&#(\d\d\d\d?);/g);  
  if(match!=null){
	  for(var i=0; i<match.length; i++){
	    var html = match[i];
	    var thisChar = Number(html.replace(/&|#|;/g,''));
	    if(!isNaN(thisChar)){
	      var thisChar = String.fromCharCode(thisChar);       
	      text = text.replace(html,thisChar);
	    }
	  }
  }
  return text;
}
String.prototype.decodeHTML= function(){
  return String.decodeHTML(this);
}
/***************************************************************************************************************************/
/**
* Evidenza tutte le ricorrenza di un dato patter di ricerca (supporto wild char google like)
*/
window.search = function(pattern){
  var start = new Date().getTime();
  var first = null; 
  window.undoHighlight();
  //conversione wildchar in RegExp
  function parseQuery(key){
    key = key.replace(/\\+/g,"")
			.replace(/\-/g,"")			
			.replace(/\./g,"\\\\.")	
			.replace(/\~/g,"")
			.replace(/\?/g,".")
			.replace(/\*/g,".*?");
    return key;
  }
  //Evidenzia
  function doHighlight(bodyText, searchTerm, style) {
    style =  style||{color:'blue','background-color':'yellow'};
    var  highlightStartTag = "<font class='highlighted' style='";
    for(name in style){
      highlightStartTag += name+':'+style[name]+" !important;"
    }
    highlightStartTag += "'>";
    var highlightEndTag = "</font>"; 
    var newText = "";    
    var i = -1;
    var lcBodyText = bodyText.toLowerCase();    
    while (bodyText.length > 0) {
      var offset = i+1;
      i = bodyText.substr(offset).search(new RegExp(searchTerm,'img'));      
      if (i>=0) i += offset;   
      if (i < 0) {newText += bodyText;bodyText = "";
      } else {
        var matched = bodyText.substr(offset).match(new RegExp(searchTerm,'img'))[0]; 
        if (bodyText.lastIndexOf(">", i) >= bodyText.lastIndexOf("<", i)) {
          if (lcBodyText.lastIndexOf("/script>", i) >= lcBodyText.lastIndexOf("<script", i)) {
            if(first==null){first=matched;} 
            newText += bodyText.substring(0, i) + highlightStartTag + bodyText.substr(i, matched.length) + highlightEndTag;
            bodyText = bodyText.substr(i + matched.length);
            lcBodyText = bodyText.toLowerCase();
            i = -1;
          }
        }
      }
    }
    return newText;
  }
  //palette CSS evidenze
  var styles =[
    {color:'black','background-color':'yellow'},
    {color:'black','background-color':'cyan'},
    {color:'black','background-color':'PaleGreen'},
    {color:'black','background-color':'LightPink'},    
    {color:'black','background-color':'Orange'},    
    {color:'black','background-color':'mediumPurple'},
    {color:'black','background-color':'RoyalBlue'},
    {color:'black','background-color':'Violet'}
    
    
  ];
  var searchArray = new Array();
  //estrazione ricerca frase "string1 string2 ... stringN"
  var phrases = pattern.match(/".+?"/)|| new Array();
  for(var i=0; i < phrases.length; i++){
     pattern = pattern.replace(phrases[i],'');
     phrases[i] = phrases[i].replace(/"/g,'');
  }
  var keys = pattern.split(" "); 
  for(var i=0; i < keys.length; i++){if(parseQuery(keys[i])!="") searchArray.push(parseQuery(keys[i]));}
  for(var i=0; i < phrases.length; i++){if(phrases[i]!="") searchArray.push(phrases[i]);}
  if (!document.body || typeof(document.body.innerHTML) == "undefined")
    return false;  
  var bodyText = document.body.innerHTML;
  for (var i = 0; i < searchArray.length; i++) {
    bodyText = doHighlight(bodyText, searchArray[i],styles[i % styles.length]);
    if(new Date().getTime()-start > 10000){
      alert("timeout!");
      return;
    }
  }  
  document.body.innerHTML = bodyText;
  if(first!=null){
    var fonts = document.getElementsByTagName("FONT");
    for(var i=0;i<fonts.length;i++){
var font =fonts[i];
      if(font.className =='highlighted'){
        window.find(font.innerHTML);
        return;
      }
    }
  }
  return true;
}
window.undoHighlight = function(){
  var fonts = document.getElementsByTagName("FONT");
  var afonts=[];
  for(var i=0;i<fonts.length;i++){
afonts.push(fonts[i]);
  }
  for(var i=0;i<afonts.length;i++){
var font =afonts[i];
    if(font.className =='highlighted'){
      if(font.outerHTML)
        font.outerHTML = font.innerHTML;
      else{
        var iRange = document.createRange();
        iRange.setStartBefore(font);
        var strFragment = iRange.createContextualFragment(font.innerHTML);
        var sRangeNode = iRange.startContainer;
        iRange.insertNode(strFragment);
        sRangeNode.removeChild(font);
      }
    }
  }
}
function w3gCheckHighlighter(){
	if( typeof w3gItemAndSezione == 'undefined')return;
	var params = w3gItemAndSezione.split("&");
	//alert(w3gItemAndSezione);
	for(var i =0; i<params.length ; i++){
	   // alert("p: "+params[i]);
		var value = params[i].split("=");
		if(value[0]=="hlsearch"){
		    var pattern = unescape(value[1]).decodeHTML();
			window.search(pattern);
		}
	}
}
onloadAddFunction(w3gCheckHighlighter);






//-------------------------------------------------------------------------------------------
//------------------------------Prototype Extensions ----------------------------------------
//-------------------------------------------------------------------------------------------

if( typeof Prototype != 'undefined' ){ // Extend object ONLY if prototy.js is included
Object.extend(Element,{
	needOverlappingFix: (/Explorer/.test(navigator.appName)  && !/MSIE 7/.test(navigator.appVersion)) || /Opera/.test(navigator.appName) || /Safari/.test(navigator.appVersion)
});

/* 13.01.2009@MV copy main menu on chosen html element
  destId: id of html element to append menu
  menuClass: css class to assign at the menu
  mainItemClass: css class to assign at the main items of the menu */
/* 18.06.2009@MV FIX della funzione di copia del menu nel footer per velocizzare il rendering su IE: la funzione
   originale era eseguita durante il rendering in pagina, questa sull'onload evitando il blocco
   sul rendering della porzione principale della pagina */
var w3gCopyMainMenu = function(destId, menuClass, mainItemClass) {
	try {
    	var dest = $(destId);
       	//ottiene tutti gli elementi con classe '.item_menu_root': ossia la tabelle con le voci di 2°livello
       	//corrispondenti a ciascuna voce di 1°livello
       	var classElements = document.getElementsByClassName('item_menu_root');
       	var allCode="";
       	classElements.each(function(element) {
       		//ottiene l'identificatore numero della voce di 1°livello (da 1 a ...)
            var index = (element.id).indexOf("subMenu")+ "subMenu".length;
            var idNumber = (element.id).substr(index);
            //ottiene il titolo della voce di 1°livello
            var titolo = $('mMenu'+idNumber);
            var titoloText;
            if (titolo.innerText != undefined) {
            	titoloText = titolo.innerText;
            } else 
                titoloText = titolo.textContent;
                        
            titoloText = titoloText.strip(); // toglie spazi vuoti
            //crea un div contenitore che conterrā un nuovo div con il titolo di una voce di 1°livello
            //e la tabella (spostata, non copiata attraverso l'uso di appendChild) con le voci di 2°livello
            //che prima erano nascoste nel menu principale creato ad inizio pagina
            firstLevelLink = "<a href=\""+titolo.href+"\">"+titoloText+ "</a>";
            firstLevelSpan ="<span id=\"firstLevel"+idNumber+"\" class=\""+mainItemClass+"\">"+firstLevelLink+"</span>";
            var temp = element.innerHTML;
            allCode += "<div id=\"footerMenu"+idNumber+"\" class=\""+menuClass+"\">"+ firstLevelSpan + temp +"</div>";
            element.style.display='none';
            element.innerHTML="";
		});
        dest.innerHTML = allCode;
        var classElements2 = document.getElementsByClassName('item_menu_table');
        classElements2.each(function(element) {element.style.display='block'});
        classElements2 = document.getElementsByClassName('item_menu_bottom');
        classElements2.each(function(element) {element.style.display='block'});
        //document.write("<style>.item_menu_table, .item_menu_bottom {display:block}</style>");
	} catch (e) {}
}

/**
 2008.04.02@FC
 estensione di Element(prototype) che descrive un elementdo del DOM
 per rendere disponibili in esso metodi per nascondere le select sottostanti in IE <7.x
*/
Element.addMethods({
	overlappedChache:
		function(element,chace){
		element = $(element);
		if(!element._overlappedChache){
			element._overlappedChache = [];
		}
		if(chace)
			element._overlappedChache= chace;
		return element._overlappedChache;
	}
	,
	onTopPosition: function(obj){		
		var pos = Position.cumulativeOffset(obj)
		var y = parseInt(pos[1]);
		var x = parseInt(pos[0]);
		var dim = obj.getDimensions();
		var w = parseInt(dim.width);
		var h = parseInt(dim.height);		
		var x2 = x + w;
		var y2 = y + h;
		/*if(obj.id=='w3gDOMConsole')
			$LOG('x:'+x+' y:'+y+', w:'+w+' h:'+h);*/
		return {'x':x, 'y':y, 'x2':x2, 'y2':y2 , 'w':w, 'h':h};

	},
	/**
	* Determina se obj č figlio di element
	* @param {Element} obj
	* @param {Element} element << metodize in Element instance (es: nomeVar.isChild(obj); )
	*/
	isChild: function(element,obj)
	{		
		element = $(element);
		var i = 15;
		do{
			if(obj == element) return true;
			obj = obj.parentNode;
		}while(obj && i--);
		return false
	},
	/**
	* Determina se l'element č sopra obj
	* @param {Element} obj
	* @param {Element} element << metodize in Element instance (es: nomeVar.isOver(obj); )
	*/
	isOver: function(element,obj){ 
		element = $(element);
		obj = $(obj);
		if(element.isChild(obj)) return false;		
		var a = obj.onTopPosition();		
		var b = element.onTopPosition();		
		//2008.04.09@FC FIX isOver algorithm
		return  ( 
			( a.w!=0 && a.h!=0 && b.w!=0 && b.h!=0 )
			&&			 
		 	( Math.abs(a.x - b.x) <= a.w || Math.abs(a.x - b.x) <= b.w ) 
		 	&&
		 	( Math.abs(a.y2 - b.y2) <= a.h || Math.abs(a.y2 - b.y2) <= b.h )			 
			&& 			
			( Math.abs(a.y - b.y) <= a.h || Math.abs(a.y - b.y) <= b.h ) 
			&&
			( Math.abs(a.x2 - b.x2) <= a.w || Math.abs(a.x2 - b.x2) <= b.w ) 
			
		);
		
	},
	showLowerElements: function(element){
		element = $(element);		
		if (Element.needOverlappingFix){				
			var elements = element.overlappedChache();	
			//if(elements.length>0)$ERR(element.id +" "+elements);	
			for(var i = 0; i < elements.length; i++){			
				
				if(elements[i].style.visibility != 'visible' && elements[i].hiddenBy == element){
					elements[i].style.visibility = 'visible';
					elements[i].hiddenBy = null;
					if(elements[i].mask)
						elements[i].mask.hide();						
				}
				
			}
			element.overlappedChache([]);			
		}
		
		return element;		
	},
	hideLowerElements: function(element){ 
		element = $(element);		
		if (Element.needOverlappingFix){
			var elements = element.weirdAPIElements();	
			var elChache = element.overlappedChache();	
			var tt = 0;
			//Vanilla loop optimization
			for(var j = 0; len = elements.length, j < len; ++j)
			{
				var item = elements[j];
				if(item.style.display!='none' && item.style.visibility !='hidden'){
					item.style.visibility = 'hidden';
					item.hiddenBy = element;
					item.maskSelect();										
					elChache.push(item);					
				}
			}				
			element.overlappedChache(elChache);
			
		}				
		return element;
	},
	maskSelect:function(element){
		element = $(element);
		var _mask=element.mask;		
		if(!_mask){
			_mask = document.createElement('DIV');
			_mask.setAttribute('class', 'selectMask');
			_mask.setAttribute('align', 'left');
			_mask.className='selectMask';
			_mask.style.cursor= 'not-allowed';
			_mask.innerHTML = "&nbsp;&nbsp;---";				
			element.parentNode.appendChild(_mask);
			_mas = Position.absolutize(_mask);						
			element.mask = _mask;			
		}		
		Position.clone(element, _mask);	
		if(_mask.style.width)
			_mask.style.width=(parseInt(_mask.style.width)-2)+'px';
		if(_mask.style.height)
		_mask.style.height=(parseInt(_mask.style.height)-2)+'px';				
		_mask = element.mask;		
		_mask.show();
		element.mask=_mask;
		return element;
	},
	weirdAPIElements: function(element){ 
	    if (Element.needOverlappingFix){ // Se il browser č MSIE diverso dal 7.x o Opera o Safari		    
			element = $(element);	
			var elements = [];
			var e = document.getElementsByTagName('select');
			//Vanilla loop optimization
			for(var j = 0; len = e.length, j < len; ++j)
			{
				var current = e[j];				
				if(element.isOver(current))elements.push(current);
			}
			return elements;
		} else return [];
	},
	/**
		Metodo hide definito in prototype js
	*/
	originalHide: Element.Methods.hide
	,
	/**
		wrapping del metodo hide di un elemento del DOM
		che riprostina la visibilitā delle eventuali select 
		nascoste da hideOverlappedSelect
	*/	
	overlappedReleaseHide: function(element){
		element = $(element)
		if (Element.needOverlappingFix){					
			element.showLowerElements();
			element.originalHide();
			element.hide = element.originalHide;			
		}
		return element;
	},
	/*
		IE < 7.x FIX nasconde le select che si sovrappongono ad un elemento del DOM
		e wrappa il metodo hide() dell'elemento per far si che venga anche 
		ripristinata la visibilitā delle select nascoste.
	*/
	hideOverlappedSelect: function(element) {
		element = $(element)		
		if (Element.needOverlappingFix){
			element.hideLowerElements();	
			
		   	if( element.overlappedChache().length > 0 ){
		   		element.hide=element.overlappedReleaseHide;
		   		
		   	}
		   
	   	}	   
	   	return element;
  	},
  	/*
		IE < 7.x FIX nasconde le select che si sovrappongono ad un elemento del DOM
		e wrappa il metodo hide() dell'elemento per far si che venga anche 
		ripristinata la visibilitā delle select nascoste.
	*/
	showOverlappedSelect: function(element) {
		element = $(element)
		if (Element.needOverlappingFix){			
		   	element.showLowerElements();
		   	element.hide = element.originalHide;		   
	   	}
	   	return element;
  	},
  	backupDimension: function(element,overide){
  	    element = $(element);
  		if(!element.backups)
  			element.backups = {dimensions:false};
  		if(!element.backups.dimensions || overide==true)
  			element.backups.dimensions = element.getDimensions();  		
		return element;  		 
  	},
  	rollbackDimension:function(element){
  		element = $(element);
  		if(element.backups && element.backups.dimensions)
  		  	element.setStyle({
          		height:element.backups.dimensions.height+'px', 
          		width:element.backups.dimensions.width+'px'});
        return element;         
  	},
  	clone: function(element) {
  		var clone = new Element(element.tagName);
  		$A(element.attributes).each(function(attribute) { 
  			if( attribute.name != 'style' ) clone[attribute.name] = attribute.value; });
  				clone.setStyle( element.getStyles() );
  				clone.update(element.innerHTML);  		  				  				
  		return clone;
	},
	getStyles: function(element) {
	  element = $(element);
	  return $A(element.style).inject({}, function(styles, styleName) {
	    styles[styleName.camelize()] = element.getStyle( styleName );
	    return styles;
	  } );

	}
});
}//END IF Element present
/**
***************************************************************************************************************
* w3gDialogs, this class allow to show message.
* - 2008.16.05@FC first release (1.0.0)
* @author FC
* @since 2008.16.05
*/
/** STATICS **/
var w3gDialogs = { 
  Version: function(){
	var release ='1';
	var major='0';
	var minor='0';		
	this.release=release;this.major=major;this.minor=minor;	
	function fullVersion(){	return release+'.'+major+'.'+minor; }
	return fullVersion();
  },
  missingPrototype: Class=='undefined',
  //url for retrive media msg box template
  //2009.03.20@FC FIX templateURL empty by default
  templateURL: false,
  //types and buttons descriptors
  OK:1,CANCEL:0,YES:2,NO:3, BLANKTEXT: '',MESSAGE: 1,PROGRESS: 2,INPUT:3,  WAIT:4,
  //use only for fixing css, very very low perfomance
  CSSFIX: function(direction,el){
    var dim = $(el).getDimensions(); var screen = window.viewportDimensions();  
    var top = (screen.height-dim.height) / 2;  var left = (screen.width-dim.width) / 2;
    var delta = { left:parseInt(window.pageXOffset|| document.documentElement.scrollLeft|| document.body.scrollLeft|| 0),top:parseInt(window.pageYOffset|| document.documentElement.scrollTop|| document.body.scrollTop || 0)}
    return direction=='left' ?  (left + delta.left) : (top + delta.top);
  },
  //button's localizations
  
  _locale: typeof w3gDialogsButtonLocale != 'undefined' ? w3gDialogsButtonLocale :  { 1:{0:'ok',1:'ok'}, 0:{0:'annulla',1:'cancel'}, 2:{0:'si',1:'yes'}, 3:{0:'no',1:'no'}  },
  istances: new Array(),
  /**
  * Register an istance of w3gDialogs
  * @param [w3gDialog.xxx] istance to register
  */
  register: function(istance){
    this.observer();
    istance.zIndex= istance.box.style.zIndex;
    this.istances = this.istances.compact();
    this.istances.push(istance);
    this.istances = this.istances.uniq();
    istance.controls.focus = this.focusMe.bindAsEventListener(w3gDialogs,istance);
    Event.observe(istance.box, "click", istance.controls.focus);
  },
  /**
  * Return the index of an register istance 
  * @param [w3gDialog.xxx] istance
  * @return [Number] index or istances numbers
  */
  priority: function(istance){
    if(!istance)return w3gDialogs.istances.size();
    var index = w3gDialogs.istances.indexOf(istance);
    return index>=0 ? index : w3gDialogs.istances.size();    
  },
  /**
  * Unregister an istance of w3gDialogs
  * @param [w3gDialog.xxx] istance to unregister
  */
  unregister:function(istance){
     this.istances = this.istances.without(istance);
     this.istances = this.istances.compact();
     this.istances = this.istances.uniq(); 
     if(istance.controls.focus)
     Event.stopObserving(istance.header, "click", istance.controls.focus);
  },
  /** -- PRIVATE --
  * Internal event handle
  * @param [Event] event fired
  */
  moveHandler:function(event){  
    try{w3gDialogs.istances.each(function(istance){istance.undraggable();istance.draw()});}catch(e){/*NOP*/}
  },
  /**
  * Bring to front an dialog
  * @param [w3gDialog.xxx] me: dialog to send fucus
  * @param [Event] event click
  */
  focusMe:function(event,me){
     //08.11.11@MV added customizable z-index
     var zIndex;
     w3gDialogs.istances.each(function(istance){zIndex=istance.zIndex; istance.box.style.zIndex=istance.zIndex});
     me.box.style.zIndex=zIndex;
  },
  /** -- PRIVATE --
  * Create RAW dialog Element, cloning template element
  * @param [Function] callback: function to call after process
  */
  buildRawTemplate:function(callback){//process 
      if(!$('w3gDialogsTemplate')){        
          container = $(document.createElement('DIV'));
          container.update('<div class="w3gDialogs"><table cellpadding=0 cellspacing=0><tr><td colspan=3><table cellpadding=0 cellspacing=0 width="100%"><tr><td class="w3gDialogs-topleft" height=25 width=10></td><td class="w3gDialogs-topmiddle"><div class="w3gDialogs-header">@titolo</div></td><td class="w3gDialogs-topright" height=25 width=10></td></tr></table></td></tr><tr><td class="w3gDialogs-frameleft" width=7 ></td><td bgcolor="white"><div class="w3gDialogs-body"><div class="w3gDialogs-icon"></div><div class="w3gDialogs-message">@message</div></div><div class="w3gDialogs-footer"></div></td><td class="w3gDialogs-frameright" width=7></td></tr><tr><td class="w3gDialogs-bottomleft" height=7 width=7></td><td class="w3gDialogs-bottommiddle" height=7></td><td class="w3gDialogs-bottomright" height=7 width=7></td></tr></table></div>');
       	  container.setAttribute('id','w3gDialogsTemplate');
          container.setStyle({display:'none',visibility:'hidden'});
          document.getElementsByTagName('BODY')[0].appendChild(container);

      }
      callback($('w3gDialogsTemplate').down().cloneNode(true));   
  },
  /** -- PRIVATE --
  * Process html of template and return to function in response hash
  * @param [Hash] response: Ajax.Request transport
  */
  processTemplate:function(response){//process 
      var callback = response.options.callback 
      if(!$('w3gDialogsTemplate')){
        var container= false;
        if(response.status >= 200 && response.status < 300){//success...
container = $(document.createElement('DIV'));
          container.update(response.responseText);        
        }else{//build raw divs
          container = $(document.createElement('DIV'));
          container.update('<div class="w3gDialogs"><table cellpadding=0 cellspacing=0><tr><td colspan=3><table cellpadding=0 cellspacing=0 width="100%"><tr><td class="w3gDialogs-topleft" height=25 width=10></td><td class="w3gDialogs-topmiddle"><div class="w3gDialogs-header">@titolo</div></td><td class="w3gDialogs-topright" height=25 width=10></td></tr></table></td></tr><tr><td class="w3gDialogs-frameleft" width=7 ></td><td bgcolor="white"><div class="w3gDialogs-body"><div class="w3gDialogs-icon"></div><div class="w3gDialogs-message">@message</div></div><div class="w3gDialogs-footer"></div></td><td class="w3gDialogs-frameright" width=7></td></tr><tr><td class="w3gDialogs-bottomleft" height=7 width=7></td><td class="w3gDialogs-bottommiddle" height=7></td><td class="w3gDialogs-bottomright" height=7 width=7></td></tr></table></div>');
        }
        if(container){
          container.setAttribute('id','w3gDialogsTemplate');
          container.setStyle({display:'none',visibility:'hidden'});
          document.getElementsByTagName('BODY')[0].appendChild(container);
        }
      }
      callback($('w3gDialogsTemplate').down().cloneNode(true));   
  },
  /**
  * Create dialog Element, cloning template element
  * @param [Function] callback: function to call after process
  */
  create:function(callback){   
    var template = $('w3gDialogsTemplate');
    if(!template){
      if(!this.templateURL){
      	this.buildRawTemplate(callback);
      }else{
      	new Ajax.Request(this.templateURL,{method:'POST',callback:callback ,onComplete:this.processTemplate.bind(callback),onException:this.processTemplate.bind(callback)});
      }
    }else{
      callback(template.down().cloneNode(true));
    }  
  },  
  /** -- PRIVATE --
  * Start to observ window scroll and resize events and nullalize itsef for prevent other calls
  */
  observer: function(){
  	Event.observe(window, "scroll", w3gDialogs.moveHandler.bindAsEventListener(w3gDialogs));
	Event.observe(window, "resize", w3gDialogs.moveHandler.bindAsEventListener(w3gDialogs));
	this.observer=Prototype.emptyFunction;
  }
};
  	/*Event.observe(window, "scroll", w3gDialogs.moveHandler.bindAsEventListener());
	Event.observe(window, "resize", w3gDialogs.moveHandler.bindAsEventListener());*/
/**
* w3gDialogs abstract class
*/
if(!w3gDialogs.missingPrototype){/*****************************************************/

w3gDialogs._base = Class.create();
Object.extend(w3gDialogs._base.prototype,{   
  MIE6 : /Explorer/.test(navigator.appName)  && !/MSIE 7/.test(navigator.appVersion),
  controls: {},  
  options: {k:null},  
  delta:{top:0,left:0},
  box: false,
  input:false,
  underveil:false,
  swapped:false,
  dimensions:false,
  /**
  * abstract contructor
  * @param [Hash] option, the configuration 
  */
  _baseinitialize: function(options){    
    try{
	    this.GUID = 'w3gDialogs:'+ w3gDialogs.priority(this) +':'+new Date().getTime();	 //scope ID    
	    this.options = {
	           title: w3gDialogs.BANKTEXT, //dialog title
	           message: w3gDialogs.BANKTEXT, //the message
	           icon: false, //icon
	           width: false, //fix width
	           minwidth: 145, //fix width
	           type:w3gDialogs.MESSAGE, //type of dialogos (w3gDialogs.MESSAGE, PROGRESS, INPUT,  WAIT)
	           closable:true, //show X close button on top          
	           onAction: Prototype.emptyFunction, //callback after button click
	           onClose: Prototype.emptyFunction, //callback after close
	           onMove: Prototype.emptyFunction, //callback during repositioning
	           onMoveStart: Prototype.emptyFunction, //callback before repositioning
	           onMoveEnd: Prototype.emptyFunction, //callback after repositioning
	           onShow: Prototype.emptyFunction, //callback after show dialog
	           onError: Prototype.emptyFunction,  //callback on error        
	           className: 'w3gDialogs', //css class name          
	           focus:true, //block under element with cover div
	           rows:false, //rows for textarear (works only with type:w3gDialogs.INPUT)
	           cols:false, //colums for textarear (works only with type:w3gDialogs.INPUT)
	           time:false, //second befor force closing
	           buttons: [w3gDialogs.OK], //[Array] buttons (w3gDialogs.OK, YES, NO, CANCEL)
	           progressbar:false, //progressbar class (works only with type:w3gDialogs.PROGRESS)
	           zIndex: 999   //08.11.11@MV added customizable z-index
	           }
	    this.controls={
	            drag: false, 
	            resizeHandler:false, 
	            fade:false,
	            pulse:false, 
	            appear:false, 
	            move:false, 
	            initialized:false,
	            focus:false, 
	            fireFinally:new Array(),
	            timer:false,
	            _default:function(){
	              for(var ctrl in this){
	                if(ctrl=='fireFinally')
	                	this[ctrl]==new Array();
	                else if(ctrl!='_default')
	                  	this[ctrl]=false;
	                
	              }
	            }
	           }
	    this.controls._default();
	    //retrive locale form URI in w3gItemAndSezione
	    var w3gItemAndSezione = w3gItemAndSezione || window.parent.w3gItemAndSezione
	    if(w3gItemAndSezione){      
	      var splited = w3gItemAndSezione.split('&');
	      var locale;
	      splited.each(function(param){
	        try{
	          var pair = param.split('=');  
	          if(pair[0]=='idLanguage'){
	            locale=pair[1].toString();
	          }
	        }catch(err){};
	      });
	      this.locale=locale;
	    }else{
	    	// 2009.12.16@SO
	    	// 2010.02.25@FC back compatibity fix
			this.locale=typeof w3gDialogsButtonLocale != 'undefined' ? "IT" : 0;
		}
	    //overwrite default option whit user defined
	    Object.extend(this.options,options || {});
	    if(!this.options.minwidth) this.options.minwidth = 200;
	    //create element
	    w3gDialogs.create(this.create.bind(this));
	    //this.box=$('w3gDialogsTemplate').down().cloneNode(true);   
	 }catch(error){
	 	this.exception(error);
	 }
       
  },
  /** -PRIVATE-
  * callback method for w3gDialogs.create, prepare and reference elements component
  * @param [Element] dialogElement, the main element container
  */  
  create:function(dialogElement){
    this.box=dialogElement;
    this.box.addClassName(this.options.className);
    this.box.setStyle({
      width: (this.options.width ?this.options.width+'px' : 'auto'),
      hiegth: 'auto'}
    )
    //delta scroll
    this.delta = {
      left:parseInt(window.pageXOffset|| document.documentElement.scrollLeft|| document.body.scrollLeft|| 0),
      top:parseInt(window.pageYOffset|| document.documentElement.scrollTop|| document.body.scrollTop || 0)
    };
    this.controls.resizeHandler = this.draw.bindAsEventListener(this);    
    //build inner elements
    this.build();
    //show dialog
    this.open();  
    this.controls.initialized = true;   
  },
  /*
  * Show the dialog
  * @fires onShow
  */
  open: function(){
    this.box.hide();    
    //render the elements
    this.draw();    
    if(this.controls.appear)
      this.controls.appear.cancel();
    try{ 
      //try to use scriptaculous Effect.Grow    
      try{this.box.showOverlappedSelect();}catch(e){}
      this.controls.appear = new Effect.Grow(this.box,{
        duration:0.3,
        controller:this,
        restoreAfterFinish:true,
        queue:{ position:'start', scope:this.GUID},
        afterFinish: function(effect){           
              var istance = effect.options.controller;
              //register thi object in w3gDialogs stack 
              w3gDialogs.register(istance);
              istance.controls.appear=false; //reset effect controller
              istance.notify('onShow',istance); //fire event             
              if (istance.options.type == w3gDialogs.PROGRESS && istance.progressbar){                
                istance.progressbar.stop(true);
                istance.progressbar.start();
              }
              istance.draggable();
              istance.startTimer();
              //initialize true dimension
              istance.dimensions=istance.box.getDimensions();
              //forza il focus sul primo bottone visibile.          
              try{istance.footer.buttonStack[0].focus();}catch(e){}              
              try{istance.box.hideOverlappedSelect();}catch(e){}
            }              
        }              
      );
      //init Effect.Pulsate for WAIT message...
      if(this.options.type==w3gDialogs.WAIT){
        if(!this.controls.pulse)
          this.controls.pulse=new Effect.Pulsate(this.message,{duration:1,
            duration: 10,
            fps: 50,
            delay:0.1,
            queue:{ position:'end',scope:this.GUID},
            afterFinish: function(effect){              
              effect.start(effect.options); //loop             
            }
            });
      }
    }catch(notEffect){
      //on error plain show....
      this.box.show();
      w3gDialogs.register(this);
      this.notify('onShow',this);
      this.dimensions=this.box.getDimensions();
      this.startTimer();     
      this.draggable();
      try{this.box.hideOverlappedSelect();}catch(e){}
    }
    
    
  }, 
  /**
  * Close the dialog
  * @param [Event] event
  * @fires onClose
  */
  close: function(event){
    if(!this.controls.initialized) {
    	setTimeout(this.close.bind(this),500);
    	return;
    }
    //stop effects and timer
    if(this.controls.pulse)
      this.controls.pulse.cancel();   
    this.controls.timer
    if(this.controls.timer)
      clearTimeout(this.controls.timer); 
    if(!this.controls.fade){ 
      this.box.controller = this;
      try{
        this.controls.fade = new Effect.DropOut(this.box,{duration:0.3,controller:this,
          afterFinish: function(effect){           
              var istance = effect.options.controller;
              if(istance.underveil)istance.underveil.hide();                      
              istance.controls.fireFinally.push(istance.notify.bind(istance,'onClose',istance));  
              istance.destroy();             
            }      
          });  
      }catch(notEffect){
      	//fire event on destroy      
        this.controls.fireFinally.push(this.notify.bind(this,'onClose',this));  
        this.destroy();
      }
    }    
    if(event)Event.stop(event);
    
    
  },
  /** -PRIVATE-
  * Destroy dialog and child objects and de-allocate it in DOM elements and binding.
  */
  destroy: function(){ 
    w3gDialogs.unregister(this);
    if (this.options.type == w3gDialogs.PROGRESS && this.options.progressbar){
      try{this.progressbar.stop();}catch(e){}
    }
    if(this.controls.pulse)
      this.controls.pulse.cancel();
    this.controls._default();
    if(this.underveil){
      this.underveil.remove();
    }
    if(this.controls.drag)
      this.controls.drag.destroy();
    try {
		this.box.remove();
		//fire all deferred events
    	this.controls.fireFinally.each(function(fireEvent){fireEvent()});
	} catch (e0) {
		// setTimeout(this.box.remove,1000);
	}
    //fire all deferred events
    //this.controls.fireFinally.each(function(fireEvent){fireEvent()});       
  },
  /** -PROTECTED-
  * Render the dialog
  * @param [Event] event
  */
  draw: function(event){ 
    //if(!event && this.controls.move) return;
    
    //08.11.11@MV added customizable z-index
    this.box.style.zIndex=this.options.zIndex;
    
    this.undraggable();
    if(event)Event.stop(event);
    try{this.box.showOverlappedSelect();}catch(notPreset){/*NOP*/}
    var mydim = this.box.getDimensions();    
    var screen = window.viewportDimensions(); 
    if(!this.dimensions ){ //redim if too large
      if( mydim.width < this.options.minwidth){
this.box.setStyle({width:this.options.minwidth+'px'}); 
      }
      if( mydim.width > screen.width){
        this.box.setStyle({width:(screen.width)+'px'});   
      }
      try{this.box.forceRerendering();}catch(notPresent){}
      this.dimensions = this.box.getDimensions();    
    }
    mydim = this.dimensions; 
    this.body.setStyle({width:(mydim.width - 24)+'px'});
    //scroll delta
    this.delta = {
      left:parseInt(window.pageXOffset|| document.documentElement.scrollLeft|| document.body.scrollLeft|| 0),
      top:parseInt(window.pageYOffset|| document.documentElement.scrollTop|| document.body.scrollTop || 0)
    };    
    if(this.options.focus && this.underveil){ // build and show under cover    
      var dim = window.dimensions()
      this.underveil.setStyle({width:dim.width+'px', height:dim.height+'px'});   
      this.underveil.show();
      try{this.underveil.hideOverlappedSelect();}catch(notPreset){/*NOP*/}
    }
    //repositioning in the middle of the browser viewport
    var offset = w3gDialogs.priority(this) * 10;
    var top = (screen.height / 2)+this.delta.top + offset ;
    var left = (screen.width / 2)+this.delta.left + offset;           
    top = top - parseInt(mydim.height) / 2;
    left = left - parseInt(mydim.width) / 2;     
    //if is visibile (show) try to use effect for moviment
    if(this.box.visible() && typeof(Scriptaculous)!='undefined'){
      if(this.controls.move)try{this.controls.move.cancel();}catch(e){}
      this.controls.move = new Effect.Move(this.box,{controller:this,x: left, y: top, mode: 'absolute', duration:0.4, 
        afterFinish:function(effect){
          var dialog=effect.options.controller;
          dialog.draggable();
          dialog.controls.move=false;
          try{dialog.box.hideOverlappedSelect();}catch(e){/*NOP*/}
      }});
    }else{
      //direct move
      this.box.setStyle( { left : left+'px' , top : top+'px' } ); 
      this.draggable();
      try{this.box.hideOverlappedSelect();}catch(notPreset){/*NOP*/}
    }
  
  },
  /** -PRIVATE-
  * Start close timer if time is specify
  */
  startTimer: function(){
    if(this.options.time){
      if(this.controls.timer){
        clearTimeout(this.controls.timer);
        this.controls.timer=false;
      }        
      this.controls.timer = setTimeout(this.close.bind(this),this.options.time*1000);
    }
  },
  /** -PRIVATE-
  * recall user defined function on event fire
  */
  notify: function(eventFired){
		if(this.options[eventFired])
			return [this.options[eventFired].apply(this.options[eventFired],$A(arguments).slice(1))];
  },
  /** -PRIVATE-
  * Draggable & Effect Move start handler
  */
  onMove: function(){ 
    try{this.box.showOverlappedSelect();}catch(e){}
    this.controls.move=true;
    this.footer.style.visibility='hidden';
    this.body.style.visibility='hidden';   
    this.box.setStyle({cursor:'move'});
    this.notify('onMoveStart',this);
    this.notify('onMove',this); 
  },
  /** -PRIVATE-
  * Draggable & Effect Move end handler
  */
  endMove: function(){
    try{this.box.hideOverlappedSelect();}catch(e){}
    this.controls.move=false;   
    this.footer.style.visibility='visible';    
    this.body.style.visibility='visible';
    this.box.setStyle({cursor:'default'});
    this.notify('onMoveEnd',this);
  },
  /** -PRIVATE-
  * Set dialog draggable
  */
  draggable: function(){
    if(this.controls.drag)return;
    try{      
       this.controls.drag = new Draggable(this.box, {onStart: this.onMove.bind(this),onEnd: this.endMove.bind(this)});   
    }catch(notPresent){this.controls.drag = false;}  
  },
  /** -PRIVATE-
  * Set dialog fixed
  */
  undraggable: function(){
    try{
      if(this.controls.drag)
       this.controls.drag.destroy();  
      this.controls.drag=false;
    }catch(notPresent){this.controls.drag = false;}  
  },
  /** -PRIVATE-
  * create inner HTML
  */
  build:function(){    
    this.box.id = this.GUID;    
    if(this.options.focus){ //under cover...
      this.underveil = $(document.createElement('DIV'));     
      var dim =window.dimensions();
      /*{
        width:document.all ? Math.max(Math.max(document.documentElement.offsetWidth, document.documentElement.scrollWidth), document.body.scrollWidth) : (document.body ? document.body.scrollWidth : ((document.documentElement.scrollWidth != 0) ? document.documentElement.scrollWidth : 0)),
        height:document.all ? Math.max(Math.max(document.documentElement.offsetHeight, document.documentElement.scrollHeight), Math.max(document.body.offsetHeight, document.body.scrollHeight)) : (document.body ? document.body.scrollHeight : ((document.documentElement.scrollHeight != 0) ? document.documentElement.scrollHeight : 0))
      }*/
      this.underveil.setStyle({cursor:'not-allowed',width:dim.width+'px', height:dim.height+'px','min-height':'100%',margin:'0px',position:'absolute',top:'0px',left:'0px'});   
    
      this.underveil.addClassName('');
      this.underveil.style.backgroundColor ='#000'
      this.underveil.update('&nbsp');
      this.underveil.setOpacity(0.1);   
      
      //08.11.11@MV added customizable z-index
      this.underveil.style.zIndex=this.options.zIndex;  
      
      document.getElementsByTagName('BODY')[0].appendChild(this.underveil);      
    }
    document.getElementsByTagName('BODY')[0].appendChild(this.box);  
    //setting class name
    this.box.addClassName(this.box,this.options.className)
    this.header = Element.getElementsByClassName(this.box,this.options.className+'-header')[0];    
    this.body =Element.getElementsByClassName(this.box,this.options.className+'-body')[0];    
    this.icon = Element.getElementsByClassName(this.body,this.options.className+'-icon')[0];
    this.message = Element.getElementsByClassName(this.body,this.options.className+'-message')[0];   
    this.footer = Element.getElementsByClassName(this.box,this.options.className+'-footer')[0];  
    //header...
    this.buildHeader();
    //body...
    this.buildBody();
    if (this.options.type == w3gDialogs.PROGRESS && this.options.progressbar)
      this.footer.hide();
    //footer..
    this.buildFooter();
  },
  /** -PRIVATE-
  * create header HTML
  */
  buildHeader: function(){
    this.header.update('');
    this.header.appendChild(document.createTextNode(this.options.title));
    if(this.options.closable){
      var closebutton= $(document.createElement('DIV'));
      closebutton.addClassName(this.options.className+'-CLOSE');      
      this.header.appendChild(closebutton);
      Event.observe(closebutton, "click", this.close.bind(this));      
    }
  },
  /** -PRIVATE-
  * create body HTML
  */
  buildBody:function(){
  	try{
	    if(!this.options.icon){
	      this.icon.hide();      
	      this.message.setStyle({diplay:'block'});
	    }else{
	      this.icon.show();
	      this.icon.addClassName(this.options.className+'-'+this.options.icon);
	    }
	    if(this.options.type == w3gDialogs.INPUT){
	      //03.12.2008@FC FIX new line rendering
	      this.message.update('');
	      this.message.update(this.options.message.replace(/\n/img,'<BR/>'));
	      this.input = null;
	      if(this.options.rows){        
	        this.input = $(document.createElement('TEXTAREA'));      
	        this.input.setAttribute('rows',this.options.rows);
	        this.input.setAttribute('cols',this.options.cols);  
	      }else{
	        this.input = $(document.createElement('INPUT'));
	        this.input.setAttribute('type','text');     
	        this.input.setAttribute('size',this.options.cols);          
	      }       
	      this.message.appendChild(document.createElement('BR'));      
	      this.input.addClassName(this.box,this.options.className+'-field'); 
	      this.message.appendChild(this.input);
	    }else if (this.options.type == w3gDialogs.PROGRESS && this.options.progressbar){
	      this.message.update('');    
	      this.message.appendChild(document.createTextNode(this.options.message.replace(/\n/g,'<BR/>')));
	      this.message.appendChild(this.options.progressbar.element);   
	      this.progressbar = new w3gProgressBar(this.options.progressbar.element,this.options.progressbar.options);
	    }else
	      this.message.update('<p>'+this.options.message.replace(/\n/g,'</p><p>')+'</p>');
   	}catch(error){
	 this.exception(error);
	}
  },
  /** -PRIVATE-
  * create footer HTML
  */
  buildFooter:function(){    
    if(!this.options.buttons || this.options.buttons.length<0)
this.options.buttons=[w3gDialogs.OK];
    for(var i=0;i<this.options.buttons.length;i++){
var key = this.options.buttons[i];
      var label = w3gDialogs._locale[key][this.locale];        
      this.footer.appendChild(this.bulidButton(key,label));
    }
  },
  /** -PRIVATE-
  * create an footer  button
  * @param [String] type
  * @param [String] text
  * @return [Element] button
  */
  bulidButton: function(type, text){
    var button = $(document.createElement('INPUT'));
    button.addClassName(this.options.className+'-button');
    button.setAttribute('type','button');
    button.setAttribute('value',text);
    button.addClassName('w3gDialogs');
    button.actionId=type;
    Event.observe(button, "click", this.callback.bind(this,button));
    return button;
  },
  /** -PRIVATE-
  * show the button bar, works only whit PROGRESS
  */
  enableButton:function(){
    try{
      new Effect.Appear(this.footer,{interval:0.5});
    }catch(err){
      this.footer.show();
    }
  },
  /**  -PRIVATE-
  * prepare and recall user define onAction function handler
  * @param [Element] button pressed
  */
  callback: function(button){
    this.close(); 
    var ret = {button:button.actionId,input:false}
    if(this.options.type == w3gDialogs.INPUT)
      ret.input=this.input.value;
    this.controls.fireFinally.push(this.notify.bind(this,'onAction',ret));    
  },
  /**  -PRIVATE-
  * Exception handler
  * @param [Throwable] the error
  */
  exception: function(throwable){
  	new w3gDialogs.exception(throwable);
  	this.destroy();
  	throw throwable;
  }
  
});
//-- IMPLEMENTATION ------------------------------------------------------------------------------
/**
* Alert w3gDialog 
*/

w3gDialogs.alert = Class.create();
Object.extend(w3gDialogs.alert.prototype,w3gDialogs._base.prototype); 
Object.extend(w3gDialogs.alert.prototype,{
  initialize: function(options){
    var redefine = {icon:false,closable:false};
    Object.extend(redefine,options || {});
    redefine.type=w3gDialogs.MESSAGE;
    this._baseinitialize(redefine)
  }
});
/**
* Confirm w3gDialog 
*/
w3gDialogs.confirm = Class.create();
Object.extend(w3gDialogs.confirm.prototype,w3gDialogs._base.prototype); 
Object.extend(w3gDialogs.confirm.prototype,{
  initialize: function(options){
    var mybutton = options.cancel ? [w3gDialogs.YES,w3gDialogs.NO,w3gDialogs.CANCEL] : [w3gDialogs.YES,w3gDialogs.NO];
    var redefine = {icon:'QUESTION',buttons:mybutton};
    Object.extend(redefine,options || {});
    redefine.type=w3gDialogs.MESSAGE;
    this._baseinitialize(redefine);
  }
});
/**
* Input w3gDialog 
*/
w3gDialogs.input = Class.create();
Object.extend(w3gDialogs.input.prototype,w3gDialogs._base.prototype); 
Object.extend(w3gDialogs.input.prototype,{
  initialize: function(options){
    var redefine = {cols:35,icon:false,buttons:[w3gDialogs.OK,w3gDialogs.CANCEL]};
    Object.extend(redefine,options || {});
    redefine.type=w3gDialogs.INPUT;
    this._baseinitialize(redefine);
  }
});
/**
* Wait w3gDialog 
*/
w3gDialogs.wait = Class.create();
Object.extend(w3gDialogs.wait.prototype,w3gDialogs._base.prototype); 
Object.extend(w3gDialogs.wait.prototype,{
  initialize: function(options){
    var redefine = {icon:'WAIT',buttons:[],closable:false};
    Object.extend(redefine,options || {});
    redefine.type=w3gDialogs.WAIT;
    this._baseinitialize(redefine)
  }
});
/**
* Progressbar w3gDialog 
*/
w3gDialogs.progress = Class.create();
Object.extend(w3gDialogs.progress.prototype,w3gDialogs._base.prototype); 
Object.extend(w3gDialogs.progress.prototype,{  
  initialize: function(options,pbaroptions){    
    var redefine = {icon:false,buttons:[w3gDialogs.OK],closable:false};
    Object.extend(redefine,options || {});
    if(redefine.buttons || redefine.buttons.length < 1)
redefine.buttons=[w3gDialogs.OK];
    redefine.type=w3gDialogs.PROGRESS;
    var pbel = $(document.createElement('DIV'));
    pbel.setAttribute('id','progressBar');
    pbel.addClassName('progressBar');
    pbel.setStyle({width:'300px'}); 
    pbaroptions = pbaroptions || {step:1,interval:.1}; 
    Object.extend(pbaroptions,{
      onComplete:this.enableButton.bind(this),
      onError: this.enableButton.bind(this)
    });
    Object.extend(redefine,{
      progressbar:{element:pbel,options:pbaroptions}});    

    this._baseinitialize(redefine);
  }
});
/**
* Inner Exception w3gDialog 
*/
w3gDialogs.exception = Class.create();
Object.extend(w3gDialogs.exception.prototype,w3gDialogs._base.prototype); 
Object.extend(w3gDialogs.exception.prototype,{
  initialize: function(throwable){
    var title = 'Javascript Exception';
    var message = '\n<u><b>name</b></u>: '+throwable.name+'\n<u><b>message</b></u>: '+throwable.message;
    var redefine = {title:title,message:message,icon:'ERROR',closable:false,buttons:[w3gDialogs.OK],focus:false,onShow:this.highilight.bind(this)};    
    redefine.type=w3gDialogs.MESSAGE;
    this._baseinitialize(redefine);
  },
  highilight:function(){    
  	try{
  	    this.message.setStyle({color:'red'})	  	
    }catch(exception){}
  }
});
//-- QUICK ACCESS FUNCTION  ------------------------------------------------------------------------------
/**
* Plain Alert 
* @param [String] message, content message
* @param [String] outercallback, callback function on action
* @param [String] title, dialog title (default hostname or 'W3G')
* @param [String] icon, ('WARNING','INFO','ERROR','QUESTION','WAIT')
*/
var w3gAlert = function(message,outercallback,title,icon){ 
  message = message || ''; 
  title = title || window.location.hostname || 'W3G';
  outercallback = outercallback || Prototype.emptyFunction;  
  var _internarlCallback = function (ret){
    if(!ret)
      outercallback(false);
    else
      outercallback(ret==w3gDialogs.OK);    
  }
  return new w3gDialogs.alert({title:title,message:message,onAction:_internarlCallback,icon:icon||false});  
}
/**
* Error icon Alert 
* @param [String] message, content message
* @param [String] outercallback, callback function on action
* @param [String] title, dialog title (default hostname or 'W3G')
*/
var w3gAlertError = function(message,outercallback,title){
  return w3gAlert(message,outercallback,title,'ERROR');
}
/**
* Warning icon Alert 
* @param [String] message, content message
* @param [String] outercallback, callback function on action
* @param [String] title, dialog title (default hostname or 'W3G')
*/
var w3gAlertWarning = function(message,outercallback,title){
  return w3gAlert(message,outercallback,title,'WARNING');
}
/**
* Info icon Alert 
* @param [String] message, content message
* @param [String] outercallback, callback function on action
* @param [String] title, dialog title (default hostname or 'W3G')
*/
var w3gAlertInfo = function(message,outercallback,title){
  return w3gAlert(message,outercallback,title,'INFO');
}
/**
* Confirm
* @param [String] message, content message
* @param [String] outercallback, callback function on action
* @param [String] title, dialog title (default hostname or 'W3G')
*/
var w3gConfirm = function(message,outercallback,title){  
  message = message || ''; 
  title = title || window.location.hostname || 'W3G';
  outercallback = outercallback || Prototype.emptyFunction;  
  var _internarlCallback = function (ret){
    if(!ret)
      outercallback(false);
    else
      outercallback(ret.button==w3gDialogs.YES);    
  }
  return new w3gDialogs.confirm({title:title,message:message,onAction:_internarlCallback,closable:false});  
}
/**
* Confirm Yes/No/Cancel
* @param [String] message, content message
* @param [String] outercallback, callback function on action
* @param [String] title, dialog title (default hostname or 'W3G')
*/
var w3gConfirmYNC = function(message,outercallback,title){  
  message = message || ''; 
  title = title || window.location.hostname || 'W3G';
  outercallback = outercallback || Prototype.emptyFunction;  
  var _internarlCallback = function (ret){
    if(!ret)
      outercallback(null);
    else
      outercallback( (ret.button==w3gDialogs.CANCEL) ? null : ret.button==w3gDialogs.YES );    
  }
  return new w3gDialogs.confirm({title:title,message:message,onAction:_internarlCallback,cancel:true,closable:true});  
}

/**
* Wait
* @param [String] message, content message
* @param [Number] time, time in seconds before close
* @param [String] title, dialog title (default hostname or 'W3G')
* @return w3gDialogs.wait (use .close() method to force closing)
*/
var w3gWait = function(message,time,title){
  message = message || ''; 
  title = title || window.location.hostname || 'W3G';
  return new w3gDialogs.wait({title:title,message:message,icon:'WAIT',time:(time||false)});  
}

//	2008.08.26@SO

}/******************** END if(!w3gDialogs.missingPrototype) */
/**
* 07.11.07@FC	1.0.0	First release.
*
*/
function w3gMedia(idMediaVal)
{
//PRIVATE ATTRIBUTES ----------------------------------------------------------------
    var _idMedia=idMediaVal ? idMediaVal : null;
    var _nome=null;          // nome
    var _idTipoPortale=null;        // id_tipo_portale
    var _descrizione=null;   // descrizione
    var _idTipo=null;        // id_tipo
    var _indirizzo=null;     // indirizzo
    var _contentLength=0; // contentlength
    var _contentType=null;   // contenttype
    var _owner=null;         // owner  
    var _creationDate=null;         // data_creazione FV@29.03.2005
    var _ready=false;         // ready
    var _statoWorkflow; // id_stato_workflow
    var _dataIn=null;        // datain
    var _dataOut;       // dataout
    var _idSezione;     // idSezione
    var _media;		// media
    var _populate = false;
    var _image = null;
    var _url = null;
    var _imageWidth =0;
    var _imageHeight =0;
    
    
//PUBBLIC GETTER\SETTER METHOD --------------------------------------------------------
    function getIdMedia(){return _idMedia;}
      this.getIdMedia = getIdMedia;    
      
    function setIdMedia(idMediaVal){_idMedia=w3gUtils.Nullalize(idMediaVal);}
      this.setIdMedia = setIdMedia;       
    
    function getNome(){return _nome;}
      this.getNome = getNome; 
    function setNome(nomeVal){_nome=w3gUtils.Nullalize(nomeVal);}
      this.setNome = setNome; 
    
    function getIdTipoPortale(){return _idTipoPortale;}
      this.getIdTipoPortale = getIdTipoPortale;
    function setIdTipoPortale(idTipoPortaleVal){_idTipoPortale=w3gUtils.Nullalize(idTipoPortaleVal);}
      this.setIdTipoPortale = setIdTipoPortale;
    
    function getDescrizione(){return _descrizione;}
      this.getDescrizione = getDescrizione;
    function setDescrizione(descrizioneVal){_descrizione=w3gUtils.Nullalize(descrizioneVal);}
      this.setDescrizione = setDescrizione;
    
    function getIdTipo(){return _idTipo;}
      this.getIdTipo = getIdTipo;
    function setIdTipo(idTipoVal){_idTipo=w3gUtils.Nullalize(idTipoVal);}
      this.setIdTipo = setIdTipo;
    
    function getIndirizzo(){return _indirizzo;}
      this.getIndirizzo = getIndirizzo;
    function setIndirizzo(indirizzoVal){_indirizzo=w3gUtils.Nullalize(indirizzoVal);}
      this.setIndirizzo = setIndirizzo;

    function getContentLength(){return _contentLength;}
      this.getContentLength = getContentLength;
    function setContentLength(contentLengthNum)
    {
      if(!contentLengthNum)_contentLength=0;
      else _contentLength=isNaN(Number(contentLengthNum))? 0 : Number(contentLengthNum);
    }
      this.setContentLength = setContentLength;
    
    function getContentType(){return _contentType;}
      this.getContentType = getContentType;
    function setContentType(contentTypeVal){_contentType=w3gUtils.Nullalize(contentTypeVal);}
      this.setContentType = setContentType;
    
    function getOwner(){return _owner;}
      this.getOwner = getOwner;
    function setOwner(ownerVal){_owner=ownerVal;}
      this.setOwner = setOwner;
    
    function getCreationDate(){return _creationDate;}
      this.getCreationDate = getCreationDate;
    function setCreationDate(creationDateVal){_creationDate=creationDateVal;}
      this.setCreationDate = setCreationDate;
    
    function isReady(){return _ready;}
      this.isReady = isReady;
    function setReady(readyBoolVal){_ready=readyBoolVal;}
      this.setReady = setReady;
    
    function getStatoWorkflow(){return _statoWorkflow;}
      this.getStatoWorkflow = getStatoWorkflow;
    function setStatoWorkflow(statoWorkflowVal){_statoWorkflow=w3gUtils.Nullalize(statoWorkflowVal);}
      this.setStatoWorkflow = setStatoWorkflow;

    function getDataIn(){return _dataIn;}
      this.getDataIn = getDataIn;
    function setDataIn(dataInVal){_dataIn=dataInVal};
      this.setDataIn = setDataIn;
    
    function getDataOut(){return _dataOut;}
      this.getDataOut = getDataOut;
    function setDataOut(dataOutVal){_dataIn=dataOutVal};
      this.setDataOut = setDataOut;

    function getIdSezione(){return _idSezione;}
      this.getIdSezione = getIdSezione;
    function setIdSezione(idSezioneVal){_idSezione=w3gUtils.Nullalize(idSezioneVal);}
      this.setIdSezione = setIdSezione;

    function getMedia(){return _media;}
      this.getMedia = getMedia;
    function setMedia(mediaVal){_media=w3gUtils.Nullalize(mediaVal);}
      this.setMedia = setMedia;
      
    function getImage(){return _image;}
      this.getImage = getImage;
    function setImage(imageObj){_image=imageObj;}
      this.setImage = setImage;
      
    function getUrl(){return _url;}
      this.getUrl = getUrl;    
     
    function toString(){
       var info = 'idMedia:'+_idMedia+';'+
   		'nome:'+_nome+';'+
   		'idTipoPortale:'+_idTipoPortale+';'+
   		'descrizione:'+_descrizione+';'+
   		'idTipo:'+_idTipo+';'+
   		'indirizzo:'+_indirizzo+';'+
   		'contentLength:'+_contentLength+';'+
   		'contentType:'+_contentType+';'+
   		'owner:'+_owner+';'+
   		'creationDate:'+_creationDate+';'+
   		'ready:'+_ready+';'+
   		'statoWorkflow:'+_statoWorkflow+';'+
   		'dataIn:'+_dataIn+';'+
   		'dataOut:'+_dataOut+';'+
   		'idSezione:'+_idSezione+';'+
   		'media:'+_media+';'+
   		'populate:'+_populate+';'+
   		'url:'+_url+';';
   		'isImage:'+this.isImage()+';';   		
   		if(this.isImage()&&_image){
   		 info+='imageWidth:'+_imageWidth+';';
   		 info+='imageHeight:'+_imageHeight+';';
   		 info+='[Image]:{src:'+_image.src+';width:'+_image.width+';height:'+_image.height+';}';
   		}
   		return info;
    }
    this.toString=toString;
    
    function isImage(){
    	return _contentType.indexOf('image/')==0;
    }
    this.isImage=isImage    
    
    function getImageWidth(){return _imageWidth}
    this.getImageWidth = getImageWidth;    
        
    function getImageHeight(){return _imageHeight;}
    this.getImageHeight = getImageHeight;
   
    
    
//SUCCESSFULLY LOAD FLAG --------------------------------------------------------------
    function isPopulate(){return _populate;}
      this.isPopulate=isPopulate;

//AJAX DATA LOAD FUNCTION --------------------------------------------------------------
    function load(returnFunction,actionUrl)
    {
       if(_idMedia==null)
       		throw "idMedia is null, cannot perform w3gMedia.load"
       if(!returnFunction || typeof(returnFunction)!="function")
       		throw "w3gMedia.load method require the return function parameter to perform this task!"
       var action = '/'+window.w3gContex+'/'+(actionUrl ? actionUrl : 'AjaxMediaInfoAction.do');
       var media = this;
       new Ajax.Request(action,{
       			method:'get',
       			parameters: {id: _idMedia, time: new Date().getMilliseconds()},
       			onSuccess: function(transport){
     			 var response = transport.responseText || "ERR";         			  			
      			 if(response=="ERR"){
      				 _populate=false;
      			 	if(returnFunction)returnFunction.call(this,media);
      			 }else{
      			 	try{      			 	
      			 	eval(response); 
      			 	_populate=true;
      			 	if(returnFunction)returnFunction.call(this,media);
      			 	}catch(err){      			 		
			    		_populate=false;
      			 		if(returnFunction)returnFunction.call(this,media);
			    	}
      			 }
    			},
    			onFailure: function(){ 
    				_populate=false;
      			 	if(returnFunction)returnFunction.call(this,media);
      			 	} 
      			});    

    }
    this.load = load;
//PRIVATE METHODS ----------------------------------------------------------------------    
   
    function setImageHeight(height){_imageHeight=Number(height);}
    function setImageWidth(width){_imageWidth=Number(width);}    	
  
    function setUrl(urlVal){
    	_url=urlVal;
    	setImageUrl(urlVal);
    }     
    function setImageUrl(imageURL){
    	var imageObj = new Image();
    	if(imageURL)imageObj.src=imageURL;
    	_image=imageObj;
    }  
    
	  
}
//STATIC METHODS -----------------------------------------------------------------------
/*check if external js object are loaded, otherwise if dontInclude Parameter 
 equal false or isn't present, include required *.js file using w3g.js function 
 or myIncludeJs internal function if non aviable */
w3gMedia.CheckDependency = function(dontInclude){
	//internal include function
	function myIncludeJs(filename)
	 {
	 	var scriptElt = document.createElement('script');
	 	scriptElt.type = 'text/javascript';
		scriptElt.src = "/"+window.w3gContex+"/"+filename;
		//append on HEAD section
	 	document.getElementsByTagName('head')[0].appendChild(scriptElt); 
	 }	 
	if(typeof(Ajax)=='undefined'){
		if(!dontInclude)
		 	try{
		 		w3gIncludeJs("js/scriptaculous/prototype.js");
		 	}catch(err){
		 		myIncludeJs("js/scriptaculous/prototype.js")
		 	}
		else
			throw 'w3gMedia object not successfully loaded, dependency obj not found';
	}
	if(typeof(w3gUtils)=='undefined'){
		if(!dontInclude)
		 	try{
		 		w3gIncludeJs("js/obj/w3gUtils.js");
		 	}catch(err){
		 		myIncludeJs("js/obj/w3gUtils.js")
		 	}
		else
			throw 'w3gMedia object not successfully loaded, dependency obj not found';
	}
}
w3gMedia.Version= function(){
	var release ='1';
	var major='0';
	var minor='0';		
	this.release=release;this.major=major;this.minor=minor;	
	function fullVersion(){	return release+'.'+major+'.'+minor; }
	return fullVersion();
}
// check if this obj is aviable
w3gMedia.CheckDependency();

