/*  Prototype JavaScript framework, version 1.5.1.1
 *  (c) 2005-2007 Sam Stephenson
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://www.prototypejs.org/
 *
/*--------------------------------------------------------------------------*/

var Prototype = {
  Version: '1.5.1.1',

  Browser: {
    IE:     !!(window.attachEvent && !window.opera),
    Opera:  !!window.opera,
    WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
    Gecko:  navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
  },

  BrowserFeatures: {
    XPath: !!document.evaluate,
    ElementExtensions: !!window.HTMLElement,
    SpecificElementExtensions:
      (document.createElement('div').__proto__ !==
       document.createElement('form').__proto__)
  },

  ScriptFragment: '<script[^>]*>([\\S\\s]*?)<\/script>',
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,

  emptyFunction: function() { },
  K: function(x) { return x }
}

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;
    }
  },

  toJSON: function(object) {
    var type = typeof object;
    switch(type) {
      case 'undefined':
      case 'function':
      case 'unknown': return;
      case 'boolean': return object.toString();
    }
    if (object === null) return 'null';
    if (object.toJSON) return object.toJSON();
    if (object.ownerDocument === document) return;
    var results = [];
    for (var property in object) {
      var value = Object.toJSON(object[property]);
      if (value !== undefined)
        results.push(property.toJSON() + ': ' + value);
    }
    return '{' + results.join(', ') + '}';
  },

  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);
  },

  serialize: function(object) {
    var results = [];
    for (var property in object) {
    	results.push (property + '=' + object[property]);
    }
    return results.join(', ');
    //return Hash.toQueryString(results).replace('&', ',');
  },

  isElement: function(object) {
    return object && object.nodeType == 1;
  },

  isArray: function(object) {
    return object && object.constructor === Array;
  },

  isHash: function(object) {
    return object instanceof Hash;
  },

  isFunction: function(object) {
    return typeof object == "function";
  },

  isString: function(object) {
    return typeof object == "string";
  },

  isNumber: function(object) {
    return typeof object == "number";
  },

  isUndefined: function(object) {
    return typeof object == "undefined";
  },

  isObject: function(object) {
  	return typeof object == "object";
  },

  isNull: function(object) {
  	return object == null;
  }

});

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));
  }
}

Object.extend(Number.prototype, {
  toColorPart: function() {
    return this.toPaddedString(2, 16);
  },

  succ: function() {
    return this + 1;
  },

  times: function(iterator) {
    $R(0, this, true).each(iterator);
    return this;
  },

  toPaddedString: function(length, radix) {
    var string = this.toString(radix || 10);
    return '0'.times(length - string.length) + string;
  },

  toJSON: function() {
    return isFinite(this) ? this.toString() : 'null';
  }
});

Date.prototype.toJSON = function() {
  return '"' + this.getFullYear() + '-' +
    (this.getMonth() + 1).toPaddedString(2) + '-' +
    this.getDate().toPaddedString(2) + 'T' +
    this.getHours().toPaddedString(2) + ':' +
    this.getMinutes().toPaddedString(2) + ':' +
    this.getSeconds().toPaddedString(2) + '"';
};

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;
      }
    }
  }
}
Object.extend(String, {
  interpret: function(value) {
    return value == null ? '' : String(value);
  },
  specialChar: {
    '\b': '\\b',
    '\t': '\\t',
    '\n': '\\n',
    '\f': '\\f',
    '\r': '\\r',
    '\\': '\\\\'
  }
});

Object.extend(String.prototype, {
  gsub: function(pattern, replacement) {
    var result = '', source = this, match;
    replacement = arguments.callee.prepareReplacement(replacement);

    while (source.length > 0) {
      if (match = source.match(pattern)) {
        result += source.slice(0, match.index);
        result += String.interpret(replacement(match));
        source  = source.slice(match.index + match[0].length);
      } else {
        result += source, source = '';
      }
    }
    return result;
  },

  sub: function(pattern, replacement, count) {
    replacement = this.gsub.prepareReplacement(replacement);
    count = count === undefined ? 1 : count;

    return this.gsub(pattern, function(match) {
      if (--count < 0) return match[0];
      return replacement(match);
    });
  },

  scan: function(pattern, iterator) {
    this.gsub(pattern, iterator);
    return 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 self = arguments.callee;
    self.text.data = this;
    return self.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 key = decodeURIComponent(pair.shift());
        var value = pair.length > 1 ? pair.join('=') : pair[0];
        if (value != undefined) value = decodeURIComponent(value);

        if (key in hash) {
          if (hash[key].constructor != Array) hash[key] = [hash[key]];
          hash[key].push(value);
        }
        else hash[key] = value;
      }
      return hash;
    });
  },

  toArray: function() {
    return this.split('');
  },

  succ: function() {
    return this.slice(0, this.length - 1) +
      String.fromCharCode(this.charCodeAt(this.length - 1) + 1);
  },

  times: function(count) {
    var result = '';
    for (var i = 0; i < count; i++) result += this;
    return result;
  },

  camelize: function() {
    var parts = this.split('-'), len = parts.length;
    if (len == 1) return parts[0];

    var camelized = this.charAt(0) == '-'
      ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
      : parts[0];

    for (var i = 1; i < len; i++)
      camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);

    return camelized;
  },

  capitalize: function() {
    return this.charAt(0).toUpperCase() + this.substring(1).toLowerCase();
  },

  underscore: function() {
    return this.gsub(/::/, '/').gsub(/([A-Z]+)([A-Z][a-z])/,'#{1}_#{2}').gsub(/([a-z\d])([A-Z])/,'#{1}_#{2}').gsub(/-/,'_').toLowerCase();
  },

  dasherize: function() {
    return this.gsub(/_/,'-');
  },

  inspect: function(useDoubleQuotes) {
    var escapedString = this.gsub(/[\x00-\x1f\\]/, function(match) {
      var character = String.specialChar[match[0]];
      return character ? character : '\\u00' + match[0].charCodeAt().toPaddedString(2, 16);
    });
    if (useDoubleQuotes) return '"' + escapedString.replace(/"/g, '\\"') + '"';
    return "'" + escapedString.replace(/'/g, '\\\'') + "'";
  },

  toJSON: function() {
    return this.inspect(true);
  },

  unfilterJSON: function(filter) {
    return this.sub(filter || Prototype.JSONFilter, '#{1}');
  },

  isJSON: function() {
    var str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
    return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
  },

  evalJSON: function(sanitize) {
    var json = this.unfilterJSON();
    try {
      if (!sanitize || json.isJSON()) return eval('(' + json + ')');
    } catch (e) { }
    throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
  },

  include: function(pattern) {
    return this.indexOf(pattern) > -1;
  },

  startsWith: function(pattern) {
    return this.indexOf(pattern) === 0;
  },

  endsWith: function(pattern) {
    var d = this.length - pattern.length;
    return d >= 0 && this.lastIndexOf(pattern) === d;
  },

  empty: function() {
    return this == '';
  },

  blank: function() {
    return /^\s*$/.test(this);
  }
});

if (Prototype.Browser.WebKit || Prototype.Browser.IE) Object.extend(String.prototype, {
  escapeHTML: function() {
    return this.replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
  },
  unescapeHTML: function() {
    return this.replace(/&amp;/g,'&').replace(/&lt;/g,'<').replace(/&gt;/g,'>');
  }
});

String.prototype.gsub.prepareReplacement = function(replacement) {
  if (typeof replacement == 'function') return replacement;
  var template = new Template(replacement);
  return function(match) { return template.evaluate(match) };
}

String.prototype.parseQuery = String.prototype.toQueryParams;

Object.extend(String.prototype.escapeHTML, {
  div:  document.createElement('div'),
  text: document.createTextNode('')
});

with (String.prototype.escapeHTML) div.appendChild(text);


var Template = Class.create();
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 = {}, $continue = new Error('"throw $continue" is deprecated, use "return" instead');

var Enumerable = {
  each: function(iterator) {
    var index = 0;
    try {
      this._each(function(value) {
        iterator(value, index++);
      });
    } 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;
  }
}

if (Prototype.Browser.WebKit) {
  $A = Array.from = function(iterable) {
    if (!iterable) return [];
    if (!(typeof iterable == 'function' && iterable == '[object NodeList]') &&
      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(sorted) {
    return this.inject([], function(array, value, index) {
      if (0 == index || (sorted ? array.last() != value : !array.include(value)))
        array.push(value);
      return array;
    });
  },

  clone: function() {
    return [].concat(this);
  },

  size: function() {
    return this.length;
  },

  inspect: function() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  },

  toJSON: function() {
    var results = [];
    this.each(function(object) {
      var value = Object.toJSON(object);
      if (value !== undefined) results.push(value);
    });
    return '[' + results.join(', ') + ']';
  }
});

Array.prototype.toArray = Array.prototype.clone;

function $w(string) {
  string = string.strip();
  return string ? string.split(/\s+/) : [];
}

if (Prototype.Browser.Opera){
  Array.prototype.concat = function() {
    var array = [];
    for (var i = 0, length = this.length; i < length; i++) array.push(this[i]);
    for (var i = 0, length = arguments.length; i < length; i++) {
      if (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(object) {
  if (object instanceof Hash) this.merge(object);
  else Object.extend(this, object || {});
};

Object.extend(Hash, {
  toQueryString: function(obj) {
    var parts = [];
    parts.add = arguments.callee.addPair;

    this.prototype._each.call(obj, function(pair) {
      if (!pair.key) return;
      var value = pair.value;

      if (value && typeof value == 'object') {
        if (value.constructor == Array) value.each(function(value) {
          parts.add(pair.key, value);
        });
        return;
      }
      parts.add(pair.key, value);
    });

    return parts.join('&');
  },

  toJSON: function(object) {
    var results = [];
    this.prototype._each.call(object, function(pair) {
      var value = Object.toJSON(pair.value);
      if (value !== undefined) results.push(pair.key.toJSON() + ': ' + value);
    });
    return '{' + results.join(', ') + '}';
  }
});

Hash.toQueryString.addPair = function(key, value, prefix) {
  key = encodeURIComponent(key);
  if (value === undefined) this.push(key);
  else this.push(key + '=' + (value == null ? '' : encodeURIComponent(value)));
}

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(', ') + '}>';
  },

  toJSON: function() {
    return Hash.toJSON(this);
  }
});

function $H(object) {
  if (object instanceof Hash) return object;
  return new Hash(object);
};

// Safari iterates over shadowed properties
if (function() {
  var i = 0, Test = function(value) { this.key = value };
  Test.prototype.key = 'foo';
  for (var property in new Test('bar')) i++;
  return i > 1;
}()) Hash.prototype._each = function(iterator) {
  var cache = [];
  for (var key in this) {
    var value = this[key];
    if ((value && value == Hash.prototype[key]) || cache.include(key)) continue;
    cache.push(key);
    var pair = [key, value];
    pair.key = key;
    pair.value = value;
    iterator(pair);
  }
};
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 = Object.clone(this.options.parameters);

    if (!['get', 'post'].include(this.method)) {
      // simulate other verbs over post
      params['_method'] = this.method;
      this.method = 'post';
    }

    this.parameters = params;

    if (params = Hash.toQueryString(params)) {
      // when GET, append parameters to URL
      if (this.method == 'get')
        this.url += (this.url.include('?') ? '&' : '?') + params;
      else if (/Konqueror|Safari|KHTML/.test(navigator.userAgent))
        params += '&_=';
    }

    try {
      if (this.options.onCreate) this.options.onCreate(this.transport);
      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();

      this.body = this.method == 'post' ? (this.options.postBody || params) : null;
      this.transport.send(this.body);

      /* Force Firefox to handle ready state 4 for synchronous requests */
      if (!this.options.asynchronous && this.transport.overrideMimeType)
        this.onStateChange();

    }
    catch (e) {
      this.dispatchException(e);
    }
  },

  onStateChange: function() {
    var readyState = this.transport.readyState;
    if (readyState > 1 && !((readyState == 4) && this._complete))
      this.respondToReadyState(this.transport.readyState);
  },

  setRequestHeaders: function() {
    var headers = {
      'X-Requested-With': 'XMLHttpRequest',
      'X-Prototype-Version': Prototype.Version,
      'Accept': 'text/javascript, text/html, application/xml, text/xml, */*'
    };

    if (this.method == 'post') {
      headers['Content-type'] = this.options.contentType +
        (this.options.encoding ? '; charset=' + this.options.encoding : '');

      /* Force "Connection: close" for older Mozilla browsers to work
       * around a bug where XMLHttpRequest sends an incorrect
       * Content-length header. See Mozilla Bugzilla #246651.
       */
      if (this.transport.overrideMimeType &&
          (navigator.userAgent.match(/Gecko\/(\d{4})/) || [0,2005])[1] < 2005)
            headers['Connection'] = 'close';
    }

    // user-defined headers
    if (typeof this.options.requestHeaders == 'object') {
      var extras = this.options.requestHeaders;

      if (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);
      }

      var contentType = this.getHeader('Content-type');
      if (contentType && contentType.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 ? json.evalJSON() : null;
    } catch (e) { return null }
  },

  evalResponse: function() {
    try {
      return eval((this.transport.responseText || '').unfilterJSON());
    } catch (e) {
      this.dispatchException(e);
    }
  },

  dispatchException: function(exception) {
    (this.options.onException || Prototype.emptyFunction)(this, exception);
    Ajax.Responders.dispatch('onException', this, exception);
  }
});

Ajax.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) {
    var q = ".//*[contains(concat(' ', @class, ' '), ' " + className + " ')]";
    return document._getElementsByXPath(q, parentElement);
  }

} else document.getElementsByClassName = function(className, parentElement) {
  var children = ($(parentElement) || document.body).getElementsByTagName('*');
  var elements = [], child, pattern = new RegExp("(^|\\s)" + className + "(\\s|$)");
  for (var i = 0, length = children.length; i < length; i++) {
    child = children[i];
    var elementClassName = child.className;
    if (elementClassName.length == 0) continue;
    if (elementClassName == className || elementClassName.match(pattern))
      elements.push(Element.extend(child));
  }
  return elements;
};

/*--------------------------------------------------------------------------*/

if (!window.Element) var Element = {};

Element.extend = function(element) {
  var F = Prototype.BrowserFeatures;
  if (!element || !element.tagName || element.nodeType == 3 ||
   element._extended || F.SpecificElementExtensions || element == window)
    return element;

  var methods = {}, tagName = element.tagName, cache = Element.extend.cache,
   T = Element.Methods.ByTag;

  // extend methods for all tags (Safari doesn't need this)
  if (!F.ElementExtensions) {
    Object.extend(methods, Element.Methods),
    Object.extend(methods, Element.Methods.Simulated);
  }

  // extend methods for specific tags
  if (T[tagName]) Object.extend(methods, T[tagName]);

  for (var property in methods) {
    var value = methods[property];
    if (typeof value == 'function' && !(property in element))
      element[property] = cache.findOrStore(value);
  }

  element._extended = Prototype.emptyFunction;
  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('*')).each(Element.extend);
  },

  firstDescendant: function(element) {
    element = $(element).firstChild;
    while (element && element.nodeType != 1) element = element.nextSibling;
    return $(element);
  },

  immediateDescendants: function(element) {
    if (!(element = $(element).firstChild)) return [];
    while (element && element.nodeType != 1) element = element.nextSibling;
    if (element) return [element].concat($(element).nextSiblings());
    return [];
  },

  previousSiblings: function(element) {
    return $(element).recursivelyCollect('previousSibling');
  },

  nextSiblings: function(element) {
    return $(element).recursivelyCollect('nextSibling');
  },

  siblings: function(element) {
    element = $(element);
    return element.previousSiblings().reverse().concat(element.nextSiblings());
  },

  match: function(element, selector) {
    if (typeof selector == 'string')
      selector = new Selector(selector);
    return selector.match($(element));
  },

  up: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(element.parentNode);
    var ancestors = element.ancestors();
    return expression ? Selector.findElement(ancestors, expression, index) :
      ancestors[index || 0];
  },

  down: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return element.firstDescendant();
    var descendants = element.descendants();
    return expression ? Selector.findElement(descendants, expression, index) :
      descendants[index || 0];
  },

  previous: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
    var previousSiblings = element.previousSiblings();
    return expression ? Selector.findElement(previousSiblings, expression, index) :
      previousSiblings[index || 0];
  },

  next: function(element, expression, index) {
    element = $(element);
    if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
    var nextSiblings = element.nextSiblings();
    return expression ? Selector.findElement(nextSiblings, expression, index) :
      nextSiblings[index || 0];
  },

  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 (Prototype.Browser.IE) {
      if (!element.attributes) return null;
      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];
      return attribute ? attribute.nodeValue : null;
    }
    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.blank();
  },

  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);
    style = style == 'float' ? 'cssFloat' : style.camelize();
    var value = element.style[style];
    if (!value) {
      var css = document.defaultView.getComputedStyle(element, null);
      value = css ? css[style] : null;
    }
    if (style == 'opacity') return value ? parseFloat(value) : 1.0;
    return value == 'auto' ? null : value;
  },

  getOpacity: function(element) {
    return $(element).getStyle('opacity');
  },

  setStyle: function(element, styles, camelized) {
  	if(element == null) {
  		return;
  	}
    element = $(element);
    var elementStyle = element.style;

    for (var property in styles)
      if (property == 'opacity') element.setOpacity(styles[property])
      else
        elementStyle[(property == 'float' || property == 'cssFloat') ?
          (elementStyle.styleFloat === undefined ? 'cssFloat' : 'styleFloat') :
          (camelized ? property : property.camelize())] = styles[property];

    return element;
  },

  setOpacity: function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1 || value === '') ? '' :
      (value < 0.00001) ? 0 : value;
    return element;
  },

  getDimensions: function(element) {
    element = $(element);
    var display = $(element).getStyle('display');
    if (display != 'none' && display != null) // Safari bug
      return {width: element.offsetWidth, height: element.offsetHeight};

    // All *Width and *Height properties give 0 on elements with display none,
    // so enable the element temporarily
    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    var originalDisplay = els.display;
    els.visibility = 'hidden';
    els.position = 'absolute';
    els.display = 'block';
    var originalWidth = element.clientWidth;
    var originalHeight = element.clientHeight;
    els.display = originalDisplay;
    els.position = originalPosition;
    els.visibility = originalVisibility;
    return {width: originalWidth, height: originalHeight};
  },

  makePositioned: function(element) {
    element = $(element);
    var pos = Element.getStyle(element, 'position');
    if (pos == 'static' || !pos) {
      element._madePositioned = true;
      element.style.position = 'relative';
      // Opera returns the offset relative to the positioning context, when an
      // element is position relative but top and left have not been defined
      if (window.opera) {
        element.style.top = 0;
        element.style.left = 0;
      }
    }
    return element;
  },

  undoPositioned: function(element) {
    element = $(element);
    if (element._madePositioned) {
      element._madePositioned = undefined;
      element.style.position =
        element.style.top =
        element.style.left =
        element.style.bottom =
        element.style.right = '';
    }
    return element;
  },

  makeClipping: function(element) {
    element = $(element);
    if (element._overflow) return element;
    element._overflow = element.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,
  childElements: Element.Methods.immediateDescendants
});

if (Prototype.Browser.Opera) {
  Element.Methods._getStyle = Element.Methods.getStyle;
  Element.Methods.getStyle = function(element, style) {
    switch(style) {
      case 'left':
      case 'top':
      case 'right':
      case 'bottom':
        if (Element._getStyle(element, 'position') == 'static') return null;
      default: return Element._getStyle(element, style);
    }
  };
}
else if (Prototype.Browser.IE) {
  Element.Methods.getStyle = function(element, style) {
    element = $(element);
    style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
    var value = element.style[style];
    if (!value && element.currentStyle) value = element.currentStyle[style];

    if (style == 'opacity') {
      if (value = (element.getStyle('filter') || '').match(/alpha\(opacity=(.*)\)/))
        if (value[1]) return parseFloat(value[1]) / 100;
      return 1.0;
    }

    if (value == 'auto') {
      if ((style == 'width' || style == 'height') && (element.getStyle('display') != 'none'))
        return element['offset'+style.capitalize()] + 'px';
      return null;
    }
    return value;
  };

  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    var filter = element.getStyle('filter'), style = element.style;
    if (value == 1 || value === '') {
      style.filter = filter.replace(/alpha\([^\)]*\)/gi,'');
      return element;
    } else if (value < 0.00001) value = 0;
    style.filter = filter.replace(/alpha\([^\)]*\)/gi, '') +
      'alpha(opacity=' + (value * 100) + ')';
    return element;
  };

  // IE is missing .innerHTML support for TABLE-related elements
  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;
  }
}
else if (Prototype.Browser.Gecko) {
  Element.Methods.setOpacity = function(element, value) {
    element = $(element);
    element.style.opacity = (value == 1) ? 0.999999 :
      (value === '') ? '' : (value < 0.00001) ? 0 : value;
    return element;
  };
}

Element._attributeTranslations = {
  names: {
    colspan:   "colSpan",
    rowspan:   "rowSpan",
    valign:    "vAlign",
    datetime:  "dateTime",
    accesskey: "accessKey",
    tabindex:  "tabIndex",
    enctype:   "encType",
    maxlength: "maxLength",
    readonly:  "readOnly",
    longdesc:  "longDesc"
  },
  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;
    }
  }
};

(function() {
  Object.extend(this, {
    href: this._getAttr,
    src:  this._getAttr,
    type: this._getAttr,
    disabled: this._flag,
    checked:  this._flag,
    readonly: this._flag,
    multiple: this._flag
  });
}).call(Element._attributeTranslations.values);

Element.Methods.Simulated = {
  hasAttribute: function(element, attribute) {
    var t = Element._attributeTranslations, node;
    attribute = t.names[attribute] || attribute;
    node = $(element).getAttributeNode(attribute);
    return node && node.specified;
  }
};

Element.Methods.ByTag = {};

Object.extend(Element, Element.Methods);

if (!Prototype.BrowserFeatures.ElementExtensions &&
 document.createElement('div').__proto__) {
  window.HTMLElement = {};
  window.HTMLElement.prototype = document.createElement('div').__proto__;
  Prototype.BrowserFeatures.ElementExtensions = true;
}

Element.hasAttribute = function(element, attribute) {
  if (element.hasAttribute) return element.hasAttribute(attribute);
  return Element.Methods.Simulated.hasAttribute(element, attribute);
};

Element.addMethods = function(methods) {
  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;

  if (!methods) {
    Object.extend(Form, Form.Methods);
    Object.extend(Form.Element, Form.Element.Methods);
    Object.extend(Element.Methods.ByTag, {
      "FORM":     Object.clone(Form.Methods),
      "INPUT":    Object.clone(Form.Element.Methods),
      "SELECT":   Object.clone(Form.Element.Methods),
      "TEXTAREA": Object.clone(Form.Element.Methods)
    });
  }

  if (arguments.length == 2) {
    var tagName = methods;
    methods = arguments[1];
  }

  if (!tagName) Object.extend(Element.Methods, methods || {});
  else {
    if (tagName.constructor == Array) tagName.each(extend);
    else extend(tagName);
  }

  function extend(tagName) {
    tagName = tagName.toUpperCase();
    if (!Element.Methods.ByTag[tagName])
      Element.Methods.ByTag[tagName] = {};
    Object.extend(Element.Methods.ByTag[tagName], methods);
  }

  function copy(methods, destination, onlyIfAbsent) {
    onlyIfAbsent = onlyIfAbsent || false;
    var cache = Element.extend.cache;
    for (var property in methods) {
      var value = methods[property];
      if (!onlyIfAbsent || !(property in destination))
        destination[property] = cache.findOrStore(value);
    }
  }

  function findDOMClass(tagName) {
    var klass;
    var trans = {
      "OPTGROUP": "OptGroup", "TEXTAREA": "TextArea", "P": "Paragraph",
      "FIELDSET": "FieldSet", "UL": "UList", "OL": "OList", "DL": "DList",
      "DIR": "Directory", "H1": "Heading", "H2": "Heading", "H3": "Heading",
      "H4": "Heading", "H5": "Heading", "H6": "Heading", "Q": "Quote",
      "INS": "Mod", "DEL": "Mod", "A": "Anchor", "IMG": "Image", "CAPTION":
      "TableCaption", "COL": "TableCol", "COLGROUP": "TableCol", "THEAD":
      "TableSection", "TFOOT": "TableSection", "TBODY": "TableSection", "TR":
      "TableRow", "TH": "TableCell", "TD": "TableCell", "FRAMESET":
      "FrameSet", "IFRAME": "IFrame"
    };
    if (trans[tagName]) klass = 'HTML' + trans[tagName] + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName + 'Element';
    if (window[klass]) return window[klass];
    klass = 'HTML' + tagName.capitalize() + 'Element';
    if (window[klass]) return window[klass];

    window[klass] = {};
    window[klass].prototype = document.createElement(tagName).__proto__;
    return window[klass];
  }

  if (F.ElementExtensions) {
    copy(Element.Methods, HTMLElement.prototype);
    copy(Element.Methods.Simulated, HTMLElement.prototype, true);
  }

  if (F.SpecificElementExtensions) {
    for (var tag in Element.Methods.ByTag) {
      var klass = findDOMClass(tag);
      if (typeof klass == "undefined") continue;
      copy(T[tag], klass.prototype);
    }
  }

  Object.extend(Element, Element.Methods);
  delete Element.ByTag;
};

var 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);
/* Portions of the Selector class are derived from Jack Slocum?? DomQuery,
 * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
 * license.  Please see http://www.yui-ext.com/ for more information. */

var Selector = Class.create();

Selector.prototype = {
  initialize: function(expression) {
    this.expression = expression.strip();
    this.compileMatcher();
  },

  compileMatcher: function() {
    // Selectors with namespaced attributes can't use the XPath version
    if (Prototype.BrowserFeatures.XPath && !(/\[[\w-]*?:/).test(this.expression))
      return this.compileXPathMatcher();

    var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
        c = Selector.criteria, le, p, m;

    if (Selector._cache[e]) {
      this.matcher = Selector._cache[e]; return;
    }
    this.matcher = ["this.matcher = function(root) {",
                    "var r = root, h = Selector.handlers, c = false, n;"];

    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        p = ps[i];
        if (m = e.match(p)) {
          this.matcher.push(typeof c[i] == 'function' ? c[i](m) :
    	      new Template(c[i]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.matcher.push("return h.unique(n);\n}");
    eval(this.matcher.join('\n'));
    Selector._cache[this.expression] = this.matcher;
  },

  compileXPathMatcher: function() {
    var e = this.expression, ps = Selector.patterns,
        x = Selector.xpath, le,  m;

    if (Selector._cache[e]) {
      this.xpath = Selector._cache[e]; return;
    }

    this.matcher = ['.//*'];
    while (e && le != e && (/\S/).test(e)) {
      le = e;
      for (var i in ps) {
        if (m = e.match(ps[i])) {
          this.matcher.push(typeof x[i] == 'function' ? x[i](m) :
            new Template(x[i]).evaluate(m));
          e = e.replace(m[0], '');
          break;
        }
      }
    }

    this.xpath = this.matcher.join('');
    Selector._cache[this.expression] = this.xpath;
  },

  findElements: function(root) {
    root = root || document;
    if (this.xpath) return document._getElementsByXPath(this.xpath, root);
    return this.matcher(root);
  },

  match: function(element) {
    return this.findElements(document).include(element);
  },

  toString: function() {
    return this.expression;
  },

  inspect: function() {
    return "#<Selector:" + this.expression.inspect() + ">";
  }
};

Object.extend(Selector, {
  _cache: {},

  xpath: {
    descendant:   "//*",
    child:        "/*",
    adjacent:     "/following-sibling::*[1]",
    laterSibling: '/following-sibling::*',
    tagName:      function(m) {
      if (m[1] == '*') return '';
      return "[local-name()='" + m[1].toLowerCase() +
             "' or local-name()='" + m[1].toUpperCase() + "']";
    },
    className:    "[contains(concat(' ', @class, ' '), ' #{1} ')]",
    id:           "[@id='#{1}']",
    attrPresence: "[@#{1}]",
    attr: function(m) {
      m[3] = m[5] || m[6];
      return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
    },
    pseudo: function(m) {
      var h = Selector.xpath.pseudos[m[1]];
      if (!h) return '';
      if (typeof h === 'function') return h(m);
      return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
    },
    operators: {
      '=':  "[@#{1}='#{3}']",
      '!=': "[@#{1}!='#{3}']",
      '^=': "[starts-with(@#{1}, '#{3}')]",
      '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
      '*=': "[contains(@#{1}, '#{3}')]",
      '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
      '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
    },
    pseudos: {
      'first-child': '[not(preceding-sibling::*)]',
      'last-child':  '[not(following-sibling::*)]',
      'only-child':  '[not(preceding-sibling::* or following-sibling::*)]',
      'empty':       "[count(*) = 0 and (count(text()) = 0 or translate(text(), ' \t\r\n', '') = '')]",
      'checked':     "[@checked]",
      'disabled':    "[@disabled]",
      'enabled':     "[not(@disabled)]",
      'not': function(m) {
        var e = m[6], p = Selector.patterns,
            x = Selector.xpath, le, m, v;

        var exclusion = [];
        while (e && le != e && (/\S/).test(e)) {
          le = e;
          for (var i in p) {
            if (m = e.match(p[i])) {
              v = typeof x[i] == 'function' ? x[i](m) : new Template(x[i]).evaluate(m);
              exclusion.push("(" + v.substring(1, v.length - 1) + ")");
              e = e.replace(m[0], '');
              break;
            }
          }
        }
        return "[not(" + exclusion.join(" and ") + ")]";
      },
      'nth-child':      function(m) {
        return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
      },
      'nth-last-child': function(m) {
        return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
      },
      'nth-of-type':    function(m) {
        return Selector.xpath.pseudos.nth("position() ", m);
      },
      'nth-last-of-type': function(m) {
        return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
      },
      'first-of-type':  function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
      },
      'last-of-type':   function(m) {
        m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
      },
      'only-of-type':   function(m) {
        var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
      },
      nth: function(fragment, m) {
        var mm, formula = m[6], predicate;
        if (formula == 'even') formula = '2n+0';
        if (formula == 'odd')  formula = '2n+1';
        if (mm = formula.match(/^(\d+)$/)) // digit only
          return '[' + fragment + "= " + mm[1] + ']';
        if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
          if (mm[1] == "-") mm[1] = -1;
          var a = mm[1] ? Number(mm[1]) : 1;
          var b = mm[2] ? Number(mm[2]) : 0;
          predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
          "((#{fragment} - #{b}) div #{a} >= 0)]";
          return new Template(predicate).evaluate({
            fragment: fragment, a: a, b: b });
        }
      }
    }
  },

  criteria: {
    tagName:      'n = h.tagName(n, r, "#{1}", c);   c = false;',
    className:    'n = h.className(n, r, "#{1}", c); c = false;',
    id:           'n = h.id(n, r, "#{1}", c);        c = false;',
    attrPresence: 'n = h.attrPresence(n, r, "#{1}"); c = false;',
    attr: function(m) {
      m[3] = (m[5] || m[6]);
      return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}"); c = false;').evaluate(m);
    },
    pseudo:       function(m) {
      if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
      return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
    },
    descendant:   'c = "descendant";',
    child:        'c = "child";',
    adjacent:     'c = "adjacent";',
    laterSibling: 'c = "laterSibling";'
  },

  patterns: {
    // combinators must be listed first
    // (and descendant needs to be last combinator)
    laterSibling: /^\s*~\s*/,
    child:        /^\s*>\s*/,
    adjacent:     /^\s*\+\s*/,
    descendant:   /^\s/,

    // selectors follow
    tagName:      /^\s*(\*|[\w\-]+)(\b|$)?/,
    id:           /^#([\w\-\*]+)(\b|$)/,
    className:    /^\.([\w\-\*]+)(\b|$)/,
    pseudo:       /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|\s|(?=:))/,
    attrPresence: /^\[([\w]+)\]/,
    attr:         /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\]]*?)\4|([^'"][^\]]*?)))?\]/
  },

  handlers: {
    // UTILITY FUNCTIONS
    // joins two collections
    concat: function(a, b) {
      for (var i = 0, node; node = b[i]; i++)
        a.push(node);
      return a;
    },

    // marks an array of nodes for counting
    mark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node._counted = true;
      return nodes;
    },

    unmark: function(nodes) {
      for (var i = 0, node; node = nodes[i]; i++)
        node._counted = undefined;
      return nodes;
    },

    // mark each child node with its position (for nth calls)
    // "ofType" flag indicates whether we're indexing for nth-of-type
    // rather than nth-child
    index: function(parentNode, reverse, ofType) {
      parentNode._counted = true;
      if (reverse) {
        for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
          node = nodes[i];
          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
        }
      } else {
        for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
          if (node.nodeType == 1 && (!ofType || node._counted)) node.nodeIndex = j++;
      }
    },

    // filters out duplicates and extends all nodes
    unique: function(nodes) {
      if (nodes.length == 0) return nodes;
      var results = [], n;
      for (var i = 0, l = nodes.length; i < l; i++)
        if (!(n = nodes[i])._counted) {
          n._counted = true;
          results.push(Element.extend(n));
        }
      return Selector.handlers.unmark(results);
    },

    // COMBINATOR FUNCTIONS
    descendant: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, node.getElementsByTagName('*'));
      return results;
    },

    child: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        for (var j = 0, children = [], child; child = node.childNodes[j]; j++)
          if (child.nodeType == 1 && child.tagName != '!') results.push(child);
      }
      return results;
    },

    adjacent: function(nodes) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        var next = this.nextElementSibling(node);
        if (next) results.push(next);
      }
      return results;
    },

    laterSibling: function(nodes) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        h.concat(results, Element.nextSiblings(node));
      return results;
    },

    nextElementSibling: function(node) {
      while (node = node.nextSibling)
	      if (node.nodeType == 1) return node;
      return null;
    },

    previousElementSibling: function(node) {
      while (node = node.previousSibling)
        if (node.nodeType == 1) return node;
      return null;
    },

    // TOKEN FUNCTIONS
    tagName: function(nodes, root, tagName, combinator) {
      tagName = tagName.toUpperCase();
      var results = [], h = Selector.handlers;
      if (nodes) {
        if (combinator) {
          // fastlane for ordinary descendant combinators
          if (combinator == "descendant") {
            for (var i = 0, node; node = nodes[i]; i++)
              h.concat(results, node.getElementsByTagName(tagName));
            return results;
          } else nodes = this[combinator](nodes);
          if (tagName == "*") return nodes;
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.tagName.toUpperCase() == tagName) results.push(node);
        return results;
      } else return root.getElementsByTagName(tagName);
    },

    id: function(nodes, root, id, combinator) {
      var targetNode = $(id), h = Selector.handlers;
      if (!nodes && root == document) return targetNode ? [targetNode] : [];
      if (nodes) {
        if (combinator) {
          if (combinator == 'child') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (targetNode.parentNode == node) return [targetNode];
          } else if (combinator == 'descendant') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Element.descendantOf(targetNode, node)) return [targetNode];
          } else if (combinator == 'adjacent') {
            for (var i = 0, node; node = nodes[i]; i++)
              if (Selector.handlers.previousElementSibling(targetNode) == node)
                return [targetNode];
          } else nodes = h[combinator](nodes);
        }
        for (var i = 0, node; node = nodes[i]; i++)
          if (node == targetNode) return [targetNode];
        return [];
      }
      return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
    },

    className: function(nodes, root, className, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      return Selector.handlers.byClassName(nodes, root, className);
    },

    byClassName: function(nodes, root, className) {
      if (!nodes) nodes = Selector.handlers.descendant([root]);
      var needle = ' ' + className + ' ';
      for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
        nodeClassName = node.className;
        if (nodeClassName.length == 0) continue;
        if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
          results.push(node);
      }
      return results;
    },

    attrPresence: function(nodes, root, attr) {
      var results = [];
      for (var i = 0, node; node = nodes[i]; i++)
        if (Element.hasAttribute(node, attr)) results.push(node);
      return results;
    },

    attr: function(nodes, root, attr, value, operator) {
      if (!nodes) nodes = root.getElementsByTagName("*");
      var handler = Selector.operators[operator], results = [];
      for (var i = 0, node; node = nodes[i]; i++) {
        var nodeValue = Element.readAttribute(node, attr);
        if (nodeValue === null) continue;
        if (handler(nodeValue, value)) results.push(node);
      }
      return results;
    },

    pseudo: function(nodes, name, value, root, combinator) {
      if (nodes && combinator) nodes = this[combinator](nodes);
      if (!nodes) nodes = root.getElementsByTagName("*");
      return Selector.pseudos[name](nodes, value, root);
    }
  },

  pseudos: {
    'first-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.previousElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'last-child': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        if (Selector.handlers.nextElementSibling(node)) continue;
          results.push(node);
      }
      return results;
    },
    'only-child': function(nodes, value, root) {
      var h = Selector.handlers;
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
          results.push(node);
      return results;
    },
    'nth-child':        function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root);
    },
    'nth-last-child':   function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true);
    },
    'nth-of-type':      function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, false, true);
    },
    'nth-last-of-type': function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, formula, root, true, true);
    },
    'first-of-type':    function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, false, true);
    },
    'last-of-type':     function(nodes, formula, root) {
      return Selector.pseudos.nth(nodes, "1", root, true, true);
    },
    'only-of-type':     function(nodes, formula, root) {
      var p = Selector.pseudos;
      return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
    },

    // handles the an+b logic
    getIndices: function(a, b, total) {
      if (a == 0) return b > 0 ? [b] : [];
      return $R(1, total).inject([], function(memo, i) {
        if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
        return memo;
      });
    },

    // handles nth(-last)-child, nth(-last)-of-type, and (first|last)-of-type
    nth: function(nodes, formula, root, reverse, ofType) {
      if (nodes.length == 0) return [];
      if (formula == 'even') formula = '2n+0';
      if (formula == 'odd')  formula = '2n+1';
      var h = Selector.handlers, results = [], indexed = [], m;
      h.mark(nodes);
      for (var i = 0, node; node = nodes[i]; i++) {
        if (!node.parentNode._counted) {
          h.index(node.parentNode, reverse, ofType);
          indexed.push(node.parentNode);
        }
      }
      if (formula.match(/^\d+$/)) { // just a number
        formula = Number(formula);
        for (var i = 0, node; node = nodes[i]; i++)
          if (node.nodeIndex == formula) results.push(node);
      } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
        if (m[1] == "-") m[1] = -1;
        var a = m[1] ? Number(m[1]) : 1;
        var b = m[2] ? Number(m[2]) : 0;
        var indices = Selector.pseudos.getIndices(a, b, nodes.length);
        for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
          for (var j = 0; j < l; j++)
            if (node.nodeIndex == indices[j]) results.push(node);
        }
      }
      h.unmark(nodes);
      h.unmark(indexed);
      return results;
    },

    'empty': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++) {
        // IE treats comments as element nodes
        if (node.tagName == '!' || (node.firstChild && !node.innerHTML.match(/^\s*$/))) continue;
        results.push(node);
      }
      return results;
    },

    'not': function(nodes, selector, root) {
      var h = Selector.handlers, selectorType, m;
      var exclusions = new Selector(selector).findElements(root);
      h.mark(exclusions);
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node._counted) results.push(node);
      h.unmark(exclusions);
      return results;
    },

    'enabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (!node.disabled) results.push(node);
      return results;
    },

    'disabled': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.disabled) results.push(node);
      return results;
    },

    'checked': function(nodes, value, root) {
      for (var i = 0, results = [], node; node = nodes[i]; i++)
        if (node.checked) results.push(node);
      return results;
    }
  },

  operators: {
    '=':  function(nv, v) { return nv == v; },
    '!=': function(nv, v) { return nv != v; },
    '^=': function(nv, v) { return nv.startsWith(v); },
    '$=': function(nv, v) { return nv.endsWith(v); },
    '*=': function(nv, v) { return nv.include(v); },
    '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
    '|=': function(nv, v) { return ('-' + nv.toUpperCase() + '-').include('-' + v.toUpperCase() + '-'); }
  },

  matchElements: function(elements, expression) {
    var matches = new Selector(expression).findElements(), h = Selector.handlers;
    h.mark(matches);
    for (var i = 0, results = [], element; element = elements[i]; i++)
      if (element._counted) results.push(element);
    h.unmark(matches);
    return results;
  },

  findElement: function(elements, expression, index) {
    if (typeof expression == 'number') {
      index = expression; expression = false;
    }
    return Selector.matchElements(elements, expression || '*')[index || 0];
  },

  findChildElements: function(element, expressions) {
    var exprs = expressions.join(','), expressions = [];
    exprs.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
      expressions.push(m[1].strip());
    });
    var results = [], h = Selector.handlers;
    for (var i = 0, l = expressions.length, selector; i < l; i++) {
      selector = new Selector(expressions[i].strip());
      h.concat(results, selector.findElements(element));
    }
    return (l > 1) ? h.unique(results) : results;
  }
});

function $$() {
  return Selector.findChildElements(document, $A(arguments));
}
var Form = {
  reset: function(form) {
    $(form).reset();
    return form;
  },

  serializeElements: function(elements, getHash) {
    var data = elements.inject({}, function(result, element) {
      if (!element.disabled && element.name) {
        var key = element.name, value = $(element).getValue();
        if (value != null) {
         	if (key in result) {
            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(form).invoke('disable');
    return form;
  },

  enable: function(form) {
    form = $(form);
    Form.getElements(form).invoke('enable');
    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;
  },

  request: function(form, options) {
    form = $(form), options = Object.clone(options || {});

    var params = options.parameters;
    options.parameters = form.serialize(true);

    if (params) {
      if (typeof params == 'string') params = params.toQueryParams();
      Object.extend(options.parameters, params);
    }

    if (form.hasAttribute('method') && !options.method)
      options.method = form.method;

    return new Ajax.Request(form.readAttribute('action'), options);
  }
}

/*--------------------------------------------------------------------------*/

Form.Element = {
  focus: function(element) {
    $(element).focus();
    return element;
  },

  select: function(element) {
    $(element).select();
    return element;
  }
}

Form.Element.Methods = {
  serialize: function(element) {
    element = $(element);
    if (!element.disabled && element.name) {
      var value = element.getValue();
      if (value != undefined) {
        var pair = {};
        pair[element.name] = value;
        return 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);
    try {
      element.focus();
      if (element.select && (element.tagName.toLowerCase() != 'input' ||
        !['button', 'reset', 'submit'].include(element.type)))
        element.select();
    } catch (e) {}
    return element;
  },

  disable: function(element) {
    element = $(element);
    element.blur();
    element.disabled = true;
    return element;
  },

  enable: function(element) {
    element = $(element);
    element.disabled = false;
    return element;
  }
}

/*--------------------------------------------------------------------------*/

var Field = Form.Element;
var $F = Form.Element.Methods.getValue;

/*--------------------------------------------------------------------------*/

Form.Element.Serializers = {
  input: function(element) {
    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' &&
      (Prototype.Browser.WebKit || element.attachEvent))
      name = 'keydown';

    Event._observeAndCache(element, name, observer, useCapture);
  },

  stopObserving: function(element, name, observer, useCapture) {
    element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (Prototype.Browser.WebKit || element.attachEvent))
      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 (Prototype.Browser.IE)
  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 (Prototype.Browser.WebKit) {
  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();

/**
 * SWFObject v1.5: Flash Player detection and embed - http://blog.deconcept.com/swfobject/
 *
 * SWFObject is (c) 2007 Geoff Stearns and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 */
if(typeof deconcept=="undefined"){var deconcept=new Object();}if(typeof deconcept.util=="undefined"){deconcept.util=new Object();}if(typeof deconcept.SWFObjectUtil=="undefined"){deconcept.SWFObjectUtil=new Object();}deconcept.SWFObject=function(_1,id,w,h,_5,c,_7,_8,_9,_a){if(!document.getElementById){return;}this.DETECT_KEY=_a?_a:"detectflash";this.skipDetect=deconcept.util.getRequestParameter(this.DETECT_KEY);this.params=new Object();this.variables=new Object();this.attributes=new Array();if(_1){this.setAttribute("swf",_1);}if(id){this.setAttribute("id",id);}if(w){this.setAttribute("width",w);}if(h){this.setAttribute("height",h);}if(_5){this.setAttribute("version",new deconcept.PlayerVersion(_5.toString().split(".")));}this.installedVer=deconcept.SWFObjectUtil.getPlayerVersion();if(!window.opera&&document.all&&this.installedVer.major>7){deconcept.SWFObject.doPrepUnload=true;}if(c){this.addParam("bgcolor",c);}var q=_7?_7:"high";this.addParam("quality",q);this.setAttribute("useExpressInstall",false);this.setAttribute("doExpressInstall",false);var _c=(_8)?_8:window.location;this.setAttribute("xiRedirectUrl",_c);this.setAttribute("redirectUrl","");if(_9){this.setAttribute("redirectUrl",_9);}};deconcept.SWFObject.prototype={useExpressInstall:function(_d){this.xiSWFPath=!_d?"expressinstall.swf":_d;this.setAttribute("useExpressInstall",true);},setAttribute:function(_e,_f){this.attributes[_e]=_f;},getAttribute:function(_10){return this.attributes[_10];},addParam:function(_11,_12){this.params[_11]=_12;},getParams:function(){return this.params;},addVariable:function(_13,_14){this.variables[_13]=_14;},getVariable:function(_15){return this.variables[_15];},getVariables:function(){return this.variables;},getVariablePairs:function(){var _16=new Array();var key;var _18=this.getVariables();for(key in _18){_16[_16.length]=key+"="+_18[key];}return _16;},getSWFHTML:function(){var _19="";if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length){if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","PlugIn");this.setAttribute("swf",this.xiSWFPath);}_19="<embed type=\"application/x-shockwave-flash\" src=\""+this.getAttribute("swf")+"\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\"";_19+=" id=\""+this.getAttribute("id")+"\" name=\""+this.getAttribute("id")+"\" ";var _1a=this.getParams();for(var key in _1a){_19+=[key]+"=\""+_1a[key]+"\" ";}var _1c=this.getVariablePairs().join("&");if(_1c.length>0){_19+="flashvars=\""+_1c+"\"";}_19+="/>";}else{if(this.getAttribute("doExpressInstall")){this.addVariable("MMplayerType","ActiveX");this.setAttribute("swf",this.xiSWFPath);}_19="<object id=\""+this.getAttribute("id")+"\" classid=\"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000\" width=\""+this.getAttribute("width")+"\" height=\""+this.getAttribute("height")+"\" style=\""+this.getAttribute("style")+"\">";_19+="<param name=\"movie\" value=\""+this.getAttribute("swf")+"\" />";var _1d=this.getParams();for(var key in _1d){_19+="<param name=\""+key+"\" value=\""+_1d[key]+"\" />";}var _1f=this.getVariablePairs().join("&");if(_1f.length>0){_19+="<param name=\"flashvars\" value=\""+_1f+"\" />";}_19+="</object>";}return _19;},write:function(_20){if(this.getAttribute("useExpressInstall")){var _21=new deconcept.PlayerVersion([6,0,65]);if(this.installedVer.versionIsValid(_21)&&!this.installedVer.versionIsValid(this.getAttribute("version"))){this.setAttribute("doExpressInstall",true);this.addVariable("MMredirectURL",escape(this.getAttribute("xiRedirectUrl")));document.title=document.title.slice(0,47)+" - Flash Player Installation";this.addVariable("MMdoctitle",document.title);}}if(this.skipDetect||this.getAttribute("doExpressInstall")||this.installedVer.versionIsValid(this.getAttribute("version"))){var n=(typeof _20=="string")?document.getElementById(_20):_20;n.innerHTML=this.getSWFHTML();return true;}else{if(this.getAttribute("redirectUrl")!=""){document.location.replace(this.getAttribute("redirectUrl"));}}return false;}};deconcept.SWFObjectUtil.getPlayerVersion=function(){var _23=new deconcept.PlayerVersion([0,0,0]);if(navigator.plugins&&navigator.mimeTypes.length){var x=navigator.plugins["Shockwave Flash"];if(x&&x.description){_23=new deconcept.PlayerVersion(x.description.replace(/([a-zA-Z]|\s)+/,"").replace(/(\s+r|\s+b[0-9]+)/,".").split("."));}}else{if(navigator.userAgent&&navigator.userAgent.indexOf("Windows CE")>=0){var axo=1;var _26=3;while(axo){try{_26++;axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash."+_26);_23=new deconcept.PlayerVersion([_26,0,0]);}catch(e){axo=null;}}}else{try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.7");}catch(e){try{var axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash.6");_23=new deconcept.PlayerVersion([6,0,21]);axo.AllowScriptAccess="always";}catch(e){if(_23.major==6){return _23;}}try{axo=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");}catch(e){}}if(axo!=null){_23=new deconcept.PlayerVersion(axo.GetVariable("$version").split(" ")[1].split(","));}}}return _23;};deconcept.PlayerVersion=function(_29){this.major=_29[0]!=null?parseInt(_29[0]):0;this.minor=_29[1]!=null?parseInt(_29[1]):0;this.rev=_29[2]!=null?parseInt(_29[2]):0;};deconcept.PlayerVersion.prototype.versionIsValid=function(fv){if(this.major<fv.major){return false;}if(this.major>fv.major){return true;}if(this.minor<fv.minor){return false;}if(this.minor>fv.minor){return true;}if(this.rev<fv.rev){return false;}return true;};deconcept.util={getRequestParameter:function(_2b){var q=document.location.search||document.location.hash;if(_2b==null){return q;}if(q){var _2d=q.substring(1).split("&");for(var i=0;i<_2d.length;i++){if(_2d[i].substring(0,_2d[i].indexOf("="))==_2b){return _2d[i].substring((_2d[i].indexOf("=")+1));}}}return "";}};deconcept.SWFObjectUtil.cleanupSWFs=function(){var _2f=document.getElementsByTagName("OBJECT");for(var i=_2f.length-1;i>=0;i--){_2f[i].style.display="none";for(var x in _2f[i]){if(typeof _2f[i][x]=="function"){_2f[i][x]=function(){};}}}};if(deconcept.SWFObject.doPrepUnload){if(!deconcept.unloadSet){deconcept.SWFObjectUtil.prepUnload=function(){__flash_unloadHandler=function(){};__flash_savedUnloadHandler=function(){};window.attachEvent("onunload",deconcept.SWFObjectUtil.cleanupSWFs);};window.attachEvent("onbeforeunload",deconcept.SWFObjectUtil.prepUnload);deconcept.unloadSet=true;}}if(!document.getElementById&&document.all){document.getElementById=function(id){return document.all[id];};}var getQueryParamValue=deconcept.util.getRequestParameter;var FlashObject=deconcept.SWFObject;var SWFObject=deconcept.SWFObject;/**
* This file is part of the PHP_Unserialize package (http://www.phpguru.org/)
*
* PHP_Unserialize is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* PHP_Unserialize is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with PHP_Unserialize; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*
* � Copyright 2005 Richard Heyes
*   http://www.phpguru.org/
*/

    /**
    * Unserializes a PHP serialized data type. Currently handles:
    *  o Strings
    *  o Integers
    *  o Doubles
    *  o Arrays
    *  o Booleans
    *  o NULL
    *  o Objects
    *
    * alert()s will be thrown if the function is passed something it
    * can't handle or incorrect data.
    *
    * @param  string input The serialized PHP data
    * @return mixed        The resulting datatype
    */
    function PHP_Unserialize(input)
    {
        var result = PHP_Unserialize_(input);
        return result[0];
    }


    /**
    * Function which performs the actual unserializing
    *
    * @param string input Input to parse
    */
    function PHP_Unserialize_(input)
    {
        var length = 0;

        switch (input.charAt(0)) {
            /**
            * Array
            */
            case 'a':
                length = PHP_Unserialize_GetLength(input);
                input  = input.substr(String(length).length + 4);

                var arr   = new Array();
                var key   = null;
                var value = null;

                for (var i=0; i<length; ++i) {
                    key   = PHP_Unserialize_(input);
                    input = key[1];

                    value = PHP_Unserialize_(input);
                    input = value[1];
                    arr[key[0]] = value[0];
                }
                input = input.substr(1);
                return [arr, input];
                break;

            /**
            * Objects
            */
            case 'O':
                length = PHP_Unserialize_GetLength(input);
                var classname = String(input.substr(String(length).length + 4, length));

                input  = input.substr(String(length).length + 6 + length);
                var numProperties = Number(input.substring(0, input.indexOf(':')))
                input = input.substr(String(numProperties).length + 2);

                var obj      = new Object();
                var property = null;
                var value    = null;

                for (var i=0; i<numProperties; ++i) {
                    key   = PHP_Unserialize_(input);
                    input = key[1];

                    // Handle private/protected
                    key[0] = key[0].replace(new RegExp('^\x00' + classname + '\x00'), '');
                    key[0] = key[0].replace(new RegExp('^\x00\\*\x00'), '');

                    value = PHP_Unserialize_(input);
                    input = value[1];

                    obj[key[0]] = value[0];
                }

                input = input.substr(1);
                return [obj, input];
                break;

            /**
            * Strings
            */
            case 's':
                length = PHP_Unserialize_GetLength(input);
                return [String(input.substr(String(length).length + 4, length)), input.substr(String(length).length + 6 + length)];
                break;

            /**
            * Integers and doubles
            */
            case 'i':
            case 'd':
                var num = Number(input.substring(2, input.indexOf(';')));
                return [num, input.substr(String(num).length + 3)];
                break;

            /**
            * Booleans
            */
            case 'b':
                var bool = (input.substr(2, 1) == 1);
                return [bool, input.substr(4)];
                break;

            /**
            * Null
            */
            case 'N':
                return [null, input.substr(2)];
                break;

            /**
            * Unsupported
            */
            case 'o':
            case 'r':
            case 'C':
            case 'R':
            case 'U':
                alert('Error: Unsupported PHP data type found!');

            /**
            * Error
            */
            default:
                return [null, null];
                break;
        }
    }


    /**
    * Returns length of strings/arrays etc
    *
    * @param string input Input to parse
    */
    function PHP_Unserialize_GetLength(input)
    {
        input = input.substring(2);
        var length = Number(input.substr(0, input.indexOf(':')));
        return length;
    }

if (typeof ViiKii == "undefined") {
    ViiKii = {};
}

ViiKii = {
	Version: '0.1',
	loadedFiles: [],
	windowLoaded: false,
	init: function(dummy) {
		this.onBeforeLoadCallbacks = [];
		this.onLoadCallbacks = [];
		var func = function() { ViiKii.onWindowLoaded(); };
		if (window.addEventListener) {
			window.addEventListener('load', func, false);
		} else if (window.attachEvent) {
			window.attachEvent('onload', func);
		}
	},
	
	onBeforeLoad: function(callback) {
		if (callback) {
			ViiKii.onBeforeLoadCallbacks.push(callback);
		}
	},

	onLoad: function(callback) {
		if (typeof document.onreadystatechange == 'object'){ //IE
			document.onreadystatechange=function(){
				if (document.readyState == "complete") {
					ViiKii.onLoadCallbacks.push(callback);
				}
			};
		} else {
			this.onLoadCallbacks.push(callback);
		}
		if(this.windowLoaded) {
			this.onWindowLoaded();
		}
	},
	
	onWindowLoaded: function() {
		this.windowLoaded = true;
		while (this.onBeforeLoadCallbacks.length > 0) {
			var beforeCallback=this.onBeforeLoadCallbacks.pop();
			if (beforeCallback) {
				beforeCallback();
			}
		}
		while (this.onLoadCallbacks.length > 0) {
			var onLoadCallback=this.onLoadCallbacks.pop();
			if (onLoadCallback) {
				onLoadCallback();
			}
		}
	},

	Updater: function(element, params) {
		new Ajax.Updater(
			element.getAttribute('target'),
			element.getAttribute('url'),
			{ evalScripts:true }
		);
	}
};

ViiKii.UI = {};
ViiKii.Login = {
	_formId: 'form_login',
	_formLayerId: 'form_login_layer',
	_backgroundLayerId: 'form_login_background',
	_tooltipId: 'form_login_tooltip',
	_isAvailableId: false,
	setAvailableId: function(available) {
		this._isAvailableId = available; 
	},
	_createLoginFormLayer: function() {
		var loginForm = document.createElement('div');
		loginForm.id = this._formLayerId;
		var pos = Position.positionedOffset($('login_panel_layer'));
		Element.setStyle(loginForm, {position: 'absolute', 
				left: (pos[0] - 50) + 'px', 
				top:  (pos[1] + 20) + 'px', 
				'z-index': 1000
			});
		document.getElementsByTagName('body')[0].appendChild(loginForm);
		return loginForm;
	},
	_getLoginFormLayer: function() {
		if ( ! $(this._formLayerId)) {
			return this._createLoginFormLayer();
		}
		return $(this._formLayerId);
	},
	_showBackground: function() {
		if ( ! $(this._backgroundLayerId)) {
			var background = document.createElement('div');
			var pos = Position.positionedOffset($('footer'));
			background.id = this._backgroundLayerId;
			var backgroundStyle = {
				'float': 'left', 
				'position': 'absolute', 
				'left': '0px', 
				'top': '0px', 
				'width': '100%', 
//				'height': (pos[1] + $('footer').getHeight() ) + 'px', 
				'height': '5000px', 
				'background': '#000000', 
				'opacity': '0.7', 
				'z-index': 900
			};
			Element.setStyle(background, backgroundStyle);
			document.getElementsByTagName('body')[0].appendChild(background);
		}
	},
	_update: function(url) {
		new Ajax.Updater(this._getLoginFormLayer(), url, {evalScripts: true});
	},
	popUp: function() {
		this.setAvailableId(false);
		this._showBackground();
		this._update('/ci/index.php/users/form_login');
	},
	close: function() {
		Event.stopObserving(document, 'keydown', ViiKii.Login.keyDownObserver);
		$(this._formLayerId).remove();
		$(this._backgroundLayerId).remove();
	},
	popupForgotID: function() {
		Event.stopObserving(document, 'keydown', ViiKii.Login.keyDownObserver);
		this._update('/ci/index.php/users/form_forgot_id');
	},
	popupForgotPassword: function(form) {
		if ( ! $F(form.name).trim().isEmpty()) {
			Event.stopObserving(document, 'keydown', ViiKii.Login.keyDownObserver);
			this._update('/ci/index.php/users/form_forgot_password/' + $F(form.name));
		}
	},
	keyDownObserver: function(e) {
		switch (e.keyCode) {
		case Event.KEY_ESC:
			ViiKii.Login.close();
			return;
		case Event.KEY_RETURN:
			ViiKii.Login.login($(ViiKii.Login._formId));
			return;
		}
	},
	userNameObserver: function (form) {
		ViiKii.Login.setAvailableId(false);
		if ($F(form.name).trim().isEmpty()) {
			ViiKii.Login.tooltip(form.name, 'UnAvailable ViiKii ID!');
		}
		
		new Ajax.Request('/ci/index.php/users/confirm_user_name/' + $F(form.name), {asynchronous: true,
				onComplete: function(transport, response) {
					if ('success' == response.result) {
						ViiKii.Login.setAvailableId(true);
						ViiKii.Login.displayForgotPasswordMessage();
						ViiKii.Login.tooltip($(ViiKii.Login._formId).name, "Available ViiKii ID!");
					} else {
						ViiKii.Login.setAvailableId(false);
						ViiKii.Login.displayForgotIdMessage();
						ViiKii.Login.tooltip($(ViiKii.Login._formId).name, "UnAvailable ViiKii ID!");
					}
				}
			}
		);
	},
	tooltip: function(element, msg) {
		var pos = Position.positionedOffset(element);
		if (pos) {
			$(this._tooltipId).style.left = (pos[0] + 20) + 'px';
			$(this._tooltipId).style.top = (pos[1] - 25) + 'px';
			$('form_login_tooltip_content').update(msg);
			$(this._tooltipId).show();
		}
	},
	closeTooltip: function() {
		$(this._tooltipId).hide();
	},
	login: function(form) {
		if ($F(form.name).trim().isEmpty()) {
			form.name.select();
			this.tooltip(form.name, 'Unavailable ViiKii ID!');
			return;
		} else if ($F(form.password).trim().isEmpty()) {
			form.password.select();
			this.tooltip(form.password, 'Please enter a valid password!');
			return;
		}
		
		this._requestForm(form, function(transport, response){
			if ('success' == response.result) {
				document.location.reload();
				return;
			} else {
				switch (response.field) {
				case 'name':
					ViiKii.Login.displayForgotIdMessage();
					$('form_login').name.select();
					break;
				case 'password':
					ViiKii.Login.displayForgotPasswordMessage();
					$('form_login').password.select();
					break;
				default:
					alert('Unknown Error.');
					break;
				}
				ViiKii.Login.tooltip($(ViiKii.Login._formId)[response.field], response.error);
			}
		});
	},
	confirmEmail: function(form) {
		new Ajax.Request(form.action, {method: form.method, 
				parameters: Form.serialize(form), 
				onComplete: function(transport, response) {
					if ('success' == response.result) {
						var params = $H({'email': response.email}).toQueryString();
						new Ajax.Updater('form_login_layer', '/ci/index.php/users/form_forgot_id_send', {method: 'POST', evalScripts: true, parameters: params});
					} else {
						new Ajax.Updater('form_login_layer', '/ci/index.php/users/form_not_match_email', {method: 'POST', evalScripts: true});
					}
				}
			}
		);
	},
	toggleRemember: function(form, img) {
		if (img.src.include('checkbox_wh.gif')) {
			form.remember.value = 1;
			img.src = 'http://vkcommon.viikii.net/checkbox_ch.gif';
		} else {
			form.remember.value = 0;
			img.src = 'http://vkcommon.viikii.net/checkbox_wh.gif';
		}
	},
	_requestForm: function(form, fn) {
		new Ajax.Request(form.action, {method: form.method, parameters: Form.serialize(form), onComplete: fn});
	},
	sendUserId: function(form) {
		this._requestForm(form, function(transport, response) {
			if ('success' == response.result) {
				alert('Please check your email.\nIt may take up to 10~20 minutes for the email to arrive.');
			} else {
				alert('Error, try again, later.');
			}
			ViiKii.Login.close();
		});
	},
	sendUserPassword: function(form) {
		this._requestForm(form, function(transport, response) {
			if ('success' == response.result) {
				alert("Please check your email.\nIt may take up to 10~20 minutes for the email to arrive.");
			} else {
				alert('Error, try again, later.');
			}
			ViiKii.Login.close();
		});
	},
	onIdFocus: function() {
		this.displayForgotIdMessage();
	},
	onPasswordFocus: function() {
		this.closeTooltip();
		if ( this._isAvailableId ) {
			this.displayForgotPasswordMessage();
		} else {
			this.displayForgotIdMessage();
		}
	},
	displayForgotIdMessage: function() {
		$('form_login_forgot_layer').update($('forgot_id_div').innerHTML);
	},
	displayForgotPasswordMessage: function() {
		$('form_login_forgot_layer').update($('forgot_password_div').innerHTML);
	}
};// Element Extends
Object.extend(Element, {
	create : function(tag, options) {
		var el = document.createElement(tag);
		for (n in options) {
			switch (n) {
			case 'style':
				Element.setStyle(el, options[n]);
				break;
			case 'html':
				if (el.tagName != ('TABLE' || 'THEAD' || 'TR' || 'TFOOT')) {
					el.innerHTML = options[n];
				}
				break;
			case 'classname':
				Element.addClassName(el, options[n]);
				break;
			case 'id':
				el.setAttribute('id', options[n]);
				break;
			// case 'name' : el.setAttribute('name', options[n]); break;
	case 'attribute':
		this.setAttr(el, options[n]);
		break;
	default:
		break;
	}
}
return el;
},

setAttr : function(el, attr) {
for (key in attr) {
	el.setAttribute(key, attr[key]);
}
},

append : function(element, tag, options) {
var el = this.create(tag, options);
element = typeof element == 'string' ? $(element) : element;
// alert('typeof:'+element);
	element.appendChild(el);
	return el;
},

insert : function(element, target, tag, options) {
	var el = this.create(tag, options);
	element = typeof element == 'string' ? $(element) : element;
	element.insertBefore(el, target);
	return el;
}
});

// Event Extends.
Object.extend(Event, {
	wheel : function(event) {
		var delta = 0;
		if (!event) {
			event = window.event;
		}
		if (event.wheelDelta) { /* IE/Opera. */
			delta = event.wheelDelta / 120;
			if (window.opera) {
				delta = delta;
			}
		} else if (event.detail) {
			/** Mozilla case. */
			delta = -event.detail / 3;
		}
		return Math.round(delta); // Safari Round
	}
});

// Position Extends
Object.extend(Position, {
	relativeOffset : function(container, element) {
		if (container == document.body) {
			var cumulativeOffset = Position.cumulativeOffset(element);
			return cumulativeOffset;
		} else {
			var valueT = 0, valueL = 0;
			do {
				valueT += element.offsetTop - element.scrollTop || 0;
				valueL += element.offsetLeft - element.scrollLeft || 0;
				element = element.offsetParent;
				if (element == container) {
					break;
				}
			} while (element);

			pos = Position.cumulativeOffset(container);
			valueL += pos[0];
			valueT += pos[1];
			return [ valueL, valueT ];
		}
	}
});

// // addition, String.prototype Start - for viikii //////////////////
function Selection(textareaElement) {
	this.element = textareaElement;
}
Selection.prototype.create = function() {
	if (document.selection != null && this.element.selectionStart == null) {
		return this._ieGetSelection();
	} else {
		return this._mozillaGetSelection();
	}
};
Selection.prototype._mozillaGetSelection = function() {
	return {
		start : this.element.selectionStart,
		end : this.element.selectionEnd
	};
};
Selection.prototype._ieGetSelection = function() {
	this.element.focus();
	var range = document.selection.createRange();
	var bookmark = range.getBookmark();
	var contents = this.element.value;
	var originalContents = contents;
	var marker = this._createSelectionMarker();
	while (contents.indexOf(marker) != -1) {
		marker = this._createSelectionMarker();
	}
	var parent = range.parentElement();
	if (parent == null || parent.type != "textarea") {
		return {
			start : 0,
			end : 0
		};
	}
	range.text = marker + range.text + marker;
	contents = this.element.value;
	var result = {};
	result.start = contents.indexOf(marker);
	contents = contents.replace(marker, "");
	result.end = contents.indexOf(marker);
	this.element.value = originalContents;
	range.moveToBookmark(bookmark);
	range.collapse(false);
	range.select();
	return result;
};
Selection.prototype._createSelectionMarker = function() {
	return "##SELECTION_MARKER_" + Math.random() + "##";
};

String.prototype.find = function(what) {
	return (this.indexOf(what) >= 0 ? true : false);
};

String.prototype.msg = function() {
	var arg = arguments;
	var __string = this;

	if (arg.length < 2) {
		alert(__string);
		if (typeof arg[0] == 'function') {
			arg[0](arg[2], arg[3], arg[4]);
		}
	} else {
		tmp = confirm(__string) === true ? arg[0](arg[2], arg[3], arg[4])
				: arg[1]();
	}
};

String.prototype.trim = function() {
	return this.replace(/(^\s*)|(\s*$)/g, "");
};

String.prototype.ltrim = function() {
	return this.replace(/(^\s*)/, "");
};

String.prototype.rtrim = function() {
	return this.replace(/(\s*$)/, "");
};

String.prototype.isBlank = function() {
	var str = this.trim();
	for ( var i = 0; i < str.length; i++) {
		if ((str.charAt(i) != "\t") && (str.charAt(i) != "\n")
				&& (str.charAt(i) != "\r")) {
			return false;
		}
	}
	return true;
};

String.prototype.isEmpty = function() {
	return 0 == this.length;
};

String.prototype.isEmail = function() {
	return (/\w+([-+.]\w+)*@\w+([-.]\w+)*\.[a-zA-Z]{2,4}$/).test(this.trim());
};

String.prototype.remove = function(pattern) {
	return (pattern == null) ? this : eval("this.replace(/[" + pattern.meta()
			+ "]/g, \"\")");
};

String.prototype.isNum = function() {
	return (/^[0-9]+$/).test(this.remove(arguments[0])) ? true : false;
};

String.prototype.isAlpha = function() {
	return (/^[a-zA-Z]+$/).test(this.remove(arguments[0])) ? true : false;
};

String.prototype.isAlnum = function() {
	return (/^[0-9a-zA-Z]+$/).test(this.remove(arguments[0])) ? true : false;
};

String.prototype.url = function() {
	return (/(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/)
			.test(this.remove(arguments[0])) ? true : false;
};

String.prototype.isInt = function() {
	if (!isNaN(this) && !isNaN(parseInt(this))) {
		return parseInt(this);
	} else {
		return null;
	}
};

/*
 * String.prototype.isUserName = function() { return
 * (/^[a-zA-z]{1}[0-9a-zA-Z]+$/).test(this.remove(arguments[0])) ? true : false; };
 */

String.prototype.equals = function() {
	return this == arguments[0];
};

String.prototype.replaceAll = function(_findValue, _replaceValue) {
	return this.replace(new RegExp(_findValue, "g"), _replaceValue);
};

String.prototype.getBytes = function() {
	return encodeURIComponent(this).replace(/%../g, 'x').length;
};
// // addition, String.prototype End - for viikii //////////////////

// Page Loading Message Layer.
Ajax.Responders.register( {
	onCreate : function() {
		if (Ajax.activeRequestCount > 0) {
			LoadingMessage.show();
		}
	},
	onComplete : function() {
		if (Ajax.activeRequestCount == 0) {
			setTimeout('LoadingMessage.hide()', 500);
		}
	}
});
LoadingMessage = {
	show : function() {
		if ($('LoadingMsg')) {
			Element.setStyle($('LoadingMsg'), {
				display : 'block'
			});
			var posT = parseInt(Math.abs(Position.page(document.body)[1]), 10) + 10;
			var posL = (Element.getWidth(document.body) - Element
					.getDimensions($('LoadingMsg')).width) / 2;
			Element.setStyle($('LoadingMsg'), {
				display : 'inline-block',
				position : 'absolute',
				top : posT + 'px',
				left : posL + 'px',
				zIndex : 1000
			});
		}
	},

	hide : function() {
		if ($('LoadingMsg')) {
			Element.setStyle($('LoadingMsg'), {
				display : 'none'
			});
		}
	}
};
// Page Loading Message Layer.

Ajax.RequestXML = Class.create();
Object
		.extend(
				Object
						.extend(Ajax.RequestXML.prototype,
								Ajax.Request.prototype),
				{
					initialize : function(url, options) {
						this.transport = Ajax.getTransport();

						this.setOptions(Object.extend( {
							asynchronous : false,
							response : 'json'
						}, options || {}));

						var onComplete = this.options.onComplete
								|| Prototype.emptyFunction;
						this.options.onComplete = ( function(transport, param) {
							this.updateContent();
							// this.responseXML();
							onComplete(transport, param);

						}).bind(this);

						this.request(url);
					},

					updateContent : function() {
						switch (this.options.response) {
						case "xml":
							this.responseValue = this.transport.responseText;
							break;
						case "array":
							this.responseValue = this.xml2array(this.loadDom());
							break;
						case "dom":
							this.responseValue = this.loadDom();
							break;
						case "json":
							this.responseValue = this.xml2json(this.loadDom());
							break;
						}

						if (this.success()) {
							if (this.onComplete) {
								setTimeout(this.onComplete.bind(this), 10);
							}
						}
					},

					loadDom : function() {
						var objXml;
						if (Prototype.Browser.IE) {
							objXml = new ActiveXObject('Microsoft.XMLDOM');
							objXml.async = false;
							objXml.loadXML(this.transport.responseText);
						} else {
							objXml = (new DOMParser()).parseFromString(
									this.transport.responseText, 'text/xml');
						}
						return objXml;
					},

					xml2json : function(xml) {
						var X = {
							toObj : function(xml) {
								var o = {};
								var n;
								if (xml.nodeType == 1) { // element node ..
									if (xml.attributes.length) { // element with attributes  ..
										for ( var i = 0; i < xml.attributes.length; i++) {
											o["@" + xml.attributes[i].nodeName] = (xml.attributes[i].nodeValue || "")
													.toString();
										}
									}

									if (xml.firstChild) { // element has child nodes ..
										var textChild = 0, cdataChild = 0, hasElementChild = false;
										for (n = xml.firstChild; n; n = n.nextSibling) {
											if (n.nodeType == 1) {
												hasElementChild = true;
											} else if (n.nodeType == 3
													&& n.nodeValue
															.match(/[^ \f\n\r\t\v]/)) {
												textChild++;
											} // non-whitespace text
											else if (n.nodeType == 4) {
												cdataChild++;
											} // cdata section node
										}
										if (hasElementChild) {
											if (textChild < 2 && cdataChild < 2) { // structured element with evtl. a single text or/and cdata node ..
												X.removeWhite(xml);
												for (n = xml.firstChild; n; n = n.nextSibling) {
													if (n.nodeType == 3) { // text node
														// o["#text"] =
														// X.escape(n.nodeValue);
														o = X
																.escape(n.nodeValue);
													} else if (n.nodeType == 4) { // cdata node
														// o["#cdata"] =
														// X.escape(n.nodeValue);
														o = X
																.escape(n.nodeValue);
													} else if (o[n.nodeName]) { // multiple occurence of element ..
														if (o[n.nodeName] instanceof Array) {
															o[n.nodeName][o[n.nodeName].length] = X
																	.toObj(n);
														} else {
															o[n.nodeName] = [
																	o[n.nodeName],
																	X.toObj(n) ];
														}
													} else { // first occurence of element..
														o[n.nodeName] = X
																.toObj(n);
													}
												}
											} else { // mixed content
												if (!xml.attributes.length) {
													o = X.escape(X
															.innerXml(xml));
												} else {
													//o["#text"] = X.escape(X.innerXml(xml));
													o = X.escape(X
															.innerXml(xml));
												}
											}
										} else if (textChild) { // pure text
											if (!xml.attributes.length) {
												o = X.escape(X.innerXml(xml));
											} else {
												//o["#text"] = X.escape(X.innerXml(xml));
												o = X.escape(X.innerXml(xml));
											}
										} else if (cdataChild) { // cdata
											if (cdataChild > 1) {
												o = X.escape(X.innerXml(xml));
											} else {
												for (n = xml.firstChild; n; n = n.nextSibling) {
													//o["#cdata"] = X.escape(n.nodeValue);
													o = X.escape(n.nodeValue);
												}
											}
										}
									}
									if (!xml.attributes.length
											&& !xml.firstChild) {
										o = null;
									}
								} else if (xml.nodeType == 9) { // document.node
									o = X.toObj(xml.documentElement);
								} else {
									alert("unhandled node type: "
											+ xml.nodeType);
								}
								return o;
							},
							toJson : function(o, name, ind) {
								var json = name ? ("\"" + name + "\"") : "";
								if (o instanceof Array) {
									for ( var i = 0, n = o.length; i < n; i++) {
										o[i] = X.toJson(o[i], "", ind + "\t");
									}
									json += (name ? ":[" : "[")
											+ (o.length > 1 ? ("\n"
													+ ind
													+ "\t"
													+ o
															.join(",\n" + ind
																	+ "\t")
													+ "\n" + ind) : o.join(""))
											+ "]";
								} else if (o === null) {
									json += (name && ":") + "null";
								} else if (typeof (o) == "object") {
									var arr = [];
									for ( var m in o) {
										arr[arr.length] = X.toJson(o[m], m, ind
												+ "\t");
									}
									json += (name ? ":{" : "{")
											+ (arr.length > 1 ? ("\n"
													+ ind
													+ "\t"
													+ arr.join(",\n" + ind
															+ "\t") + "\n" + ind)
													: arr.join("")) + "}";
								} else if (typeof (o) == "string") {
									json += (name && ":") + "\"" + o.toString()
											+ "\"";
								} else {
									json += (name && ":") + o.toString();
								}
								return json;
							},
							innerXml : function(node) {
								var s = "";
								if ("innerHTML" in node) {
									s = node.innerHTML;
								} else {
									var asXml = function(n) {
										var s = "";
										if (n.nodeType == 1) {
											s += "<" + n.nodeName;
											for ( var i = 0; i < n.attributes.length; i++) {
												s += " "
														+ n.attributes[i].nodeName
														+ "=\""
														+ (n.attributes[i].nodeValue || "")
																.toString()
														+ "\"";
											}
											if (n.firstChild) {
												s += ">";
												for ( var c = n.firstChild; c; c = c.nextSibling) {
													s += asXml(c);
												}
												s += "</" + n.nodeName + ">";
											} else {
												s += "/>";
											}
										} else if (n.nodeType == 3) {
											s += n.nodeValue;
										} else if (n.nodeType == 4) {
											s += "<![CDATA[" + n.nodeValue
													+ "]]>";
										}
										return s;
									};
									for ( var c = node.firstChild; c; c = c.nextSibling) {
										s += asXml(c);
									}
								}
								return s;
							},
							escape : function(txt) {
								return txt.replace(/[\\]/g, "\\\\").replace(
										/[\"]/g, '\\"').replace(/[\n]/g, '\\n')
										.replace(/[\r]/g, '\\r');
							},
							removeWhite : function(e) {
								e.normalize();
								for ( var n = e.firstChild; n;) {
									if (n.nodeType == 3) { // text node
								if (!n.nodeValue.match(/[^ \f\n\r\t\v]/)) { // pure whitespace text node
									var nxt = n.nextSibling;
									e.removeChild(n);
									n = nxt;
								} else {
									n = n.nextSibling;
								}
							} else if (n.nodeType == 1) { // element node
								X.removeWhite(n);
								n = n.nextSibling;
							} else { // any other node
								n = n.nextSibling;
							}
						}
						return e;
					}
						};

						if (xml.nodeType == 9) {
							xml = xml.documentElement;
						} // document node
						var json = X.toJson(X.toObj(X.removeWhite(xml)),
								xml.nodeName, "\t");
						return eval("({" + json.replace(/\t|\n/g, "") + "})");
					},

					xml2array : function(xmlDoc, parent_count) {
						var not_whitespace = new RegExp(/[^\s]/);// This can
																	// be given
																	// inside
																	// the
																	// funciton
																	// - I made
																	// it a
																	// global
																	// variable
																	// to make
																	// the scipt
																	// a little
																	// bit
																	// faster.
					var arr;
					var parent = "";
					this.parent_count = parent_count || {};
					var attribute_inside = 1; /*
												 * :CONFIG: Value - 1 or 0 If 1,
												 * Value and Attribute will be
												 * shown inside the tag - like
												 * this... For the XML string...
												 * <guid
												 * isPermaLink="true">http://www.bin-co.com/</guid>
												 * The resulting array will
												 * be... array['guid']['value'] =
												 * "http://www.bin-co.com/";
												 * array['guid']['attribute_isPermaLink'] =
												 * "true";
												 * 
												 * If 0, the value will be
												 * inside the tag but the
												 * attribute will be outside -
												 * like this... For the same XML
												 * String the resulting array
												 * will be... array['guid'] =
												 * "http://www.bin-co.com/";
												 * array['attribute_guid_isPermaLink'] =
												 * "true";
												 */

					if (xmlDoc.nodeName && xmlDoc.nodeName.charAt(0) != "#") {
						if (xmlDoc.childNodes.length > 1) { //If its a parent
							arr = {};
							parent = xmlDoc.nodeName;
						}
					}

					var value = xmlDoc.nodeValue;
					if (xmlDoc.parentNode && xmlDoc.parentNode.nodeName
							&& value) {
						if (not_whitespace.test(value)) {//If its a child
							arr = {};
							arr[xmlDoc.parentNode.nodeName] = value;
						}
					}

					if (xmlDoc.childNodes.length) {
						if (xmlDoc.childNodes.length == 1) { //Just one item in this tag.
							arr = this.xml2array(xmlDoc.childNodes[0],
									this.parent_count); // :RECURSION:
						} else { //If there is more than one childNodes, go thru them one by one and get their results.
							var index = 0;
							for ( var i = 0; i < xmlDoc.childNodes.length; i++) {//Go thru all the child nodes.
								var temp = this.xml2array(xmlDoc.childNodes[i],
										this.parent_count); // :RECURSION:

								if (temp) {
									var assoc = false;
									var arr_count = 0;
									for (key in temp) {
										if (isNaN(key)) {
											assoc = true;
										}
										arr_count++;
										if (arr_count > 2) {
											break;
										} //We just need to know wether it is a single value array or not
									}

									if (assoc && arr_count == 1) {
										if (arr[key]) { //If another element exists with the same tag name before, put it in a numeric array.
											// Find out how many time this
											// parent made its appearance
											if (!this.parent_count
													|| !this.parent_count[key]) {
												this.parent_count[key] = 0;

												var temp_arr = arr[key];
												arr[key] = {};
												arr[key][0] = temp_arr;
											}
											this.parent_count[key]++;
											arr[key][this.parent_count[key]] = temp[key]; // Members
																							// of
																							// of a
																							// numeric
																							// array
										} else {
											this.parent_count[key] = 0;
											arr[key] = temp[key];
											if (xmlDoc.childNodes[i].attributes.length) {
												for ( var j = 0; j < xmlDoc.childNodes[i].attributes.length; j++) {
													var nname = xmlDoc.childNodes[i].attributes[j].nodeName;
													if (nname) {
														/* Value and Attribute inside the tag */
														if (attribute_inside) {
															temp_arr = arr[key];
															arr[key] = {};
															arr[key]['value'] = temp_arr;
															arr[key]['attribute_' + nname] = xmlDoc.childNodes[i].attributes[j].nodeValue;
														} else {
															/* Value in the tag and Attribute otside the tag(in parent) */
															arr['attribute_'
																	+ key + '_'
																	+ nname] = xmlDoc.childNodes[i].attributes[j].nodeValue;
														}
													}
												} //End of 'for(var j=0; j<xmlDoc. ...'
											} //End of 'if(xmlDoc.childNodes[i] ...'
										}
									} else {
										arr[index] = temp;
										index++;
									}
								} //End of 'if(temp) {'
							} //End of 'for(var i=0; i<xmlDoc. ...'
						}
					}

					if (parent && arr) {
						temp = arr;
						arr = {};

						arr[parent] = temp;
					}
					return arr;
				}
				});

ViiKii.HoverSet = Class.create();
ViiKii.HoverSet.prototype = {
	initialize : function(hoverSet, options) {
		if (typeof hoverSet == 'string') {
			hoverSet = $$(hoverSet);
		}
		this.hoverSet = hoverSet;
		this.options = options || [];
		this.hoverClassName = this.options.hoverClass || 'hover';
		this.hoverNodes = this.options.hoverNodes || function(e) {
			return [ e ];
		};
		this.onHoverHandler = this._onHover.bind(this);
		this.unHoverHandler = this._unHover.bind(this);
		this.hoverSet.each(( function(e) {
			Event.observe(e, "mousemove", new ViiKii.EventWrapper(
					this.onHoverHandler, e).wrapper);
		}).bind(this));
		this.hoverSet.each(( function(e) {
			Event.observe(e, "mouseout", new ViiKii.EventWrapper(
					this.unHoverHandler, e).wrapper);
		}).bind(this));
	},
	over : function(target) {
		this.hoverNodes(target).each(( function(t) {
			Element.classNames(t).add(this.hoverClassName);
		}).bind(this));
	},
	out : function(target) {
		this.hoverNodes(target).each(( function(t) {
			Element.classNames(t).remove(this.hoverClassName);
		}).bind(this));
	},
	_onHover : function(event, target) {
		this.over(target);
	},
	_unHover : function(event, target) {
		this.out(target);
	}
};

ViiKii.SelectionSet = Class.create();
ViiKii.SelectionSet.prototype = {
	initialize : function(selectionSet, options) {
		if (typeof selectionSet == 'string') {
			selectionSet = $$(selectionSet);
		}
		this.selectionSet = selectionSet;
		this.options = options || [];
		this.selectedClassName = this.options.selectedClass || 'selected';
		this.selectedNodes = this.options.selectedNodes || function(e) {
			return e;
		};
		this.clickHandler = this._click.bind(this);
		this.onSelect = this.options.onSelect;
		this.selectionSet.each(( function(e) {
			Event.observe(e, "click", new ViiKii.EventWrapper(
					this.clickHandler, e).wrapper);
		}).bind(this));
		this.selectIndex(this.options.selectedIndex || 0);
	},
	select : function(target) {
		if (this.selected == target) {
			return;
		}
		if (this.selected) {
			var sel_node = new Element.classNames(this
					.selectedNodes(this.selected))
					.remove(this.selectedClassName);
		}

		var index = this.selectionSet.indexOf(target);
		if (this.onSelect) {
			try {
				this.onSelect(target, index);
			} catch (e) {
			}
		}

		this.selected = target;
		sel_node = new Element.classNames(this.selectedNodes(this.selected))
				.add(this.selectedClassName);
	},
	selectIndex : function(index) {
		this.select(this.selectionSet[index]);
	},
	_click : function(event, target) {
		this.select(target);
	}
};

ViiKii.EventWrapper = Class.create();
ViiKii.EventWrapper.prototype = {
	initialize : function(handler, target) {
		this.handler = handler;
		this.target = target;
		this.wrapper = this.wrapperCall.bindAsEventListener(this);
	},
	wrapperCall : function(event) {
		this.handler(event, this.target);
	}
};

ViiKii.Util = {

	_VIIKII_COOKIE_U_KEY : 'ViiKii_USER_',
	_VIIKII_COOKIE_G_KEY : 'ViiKii_GUEST_',
	_VIIKII_COOKIE_VISITOR : 'ViiKii_VISITOR_',

	initialize : function() {
	},
	getVisitorCookie : function(pname) {
		var vcookies = document.cookie.split("; ");
		for (i = 0; i < vcookies.length; i++) {
			vparent = unescape(vcookies[i]).split('=');

			if (vparent[0] == this._VIIKII_COOKIE_VISITOR) {
				var unserialized = this._unserialize(vparent[1]);
				if (Object.isUndefined(unserialized[pname])) {
					return null;
				} else {
					return unserialized[pname];
				}
			}
		}
		return null;
	},
	getDomainCookie : function(pname) {

		var vcookies = document.cookie.split("; ");
		var vitem;
		var value = null;

		var cookie_ = this._VIIKII_COOKIE_G_KEY;
		for ( var i = 0; i < vcookies.length; i++) {
			vparent = unescape(vcookies[i]).split('=');
			if (vparent[0] == this._VIIKII_COOKIE_U_KEY) {
				cookie_ = this._VIIKII_COOKIE_U_KEY;
				break;
			}
		}

		for (i = 0; i < vcookies.length; i++) {
			vparent = unescape(vcookies[i]).split('=');

			if (vparent[0] == cookie_) {
				var unserialized = this._unserialize(vparent[1]);
				if (Object.isUndefined(unserialized[pname])) {
					return null;
				} else {
					return unserialized[pname];
				}
			}
		}
		return null;
	},

	_unserialize : function(input) {
		var result = this._unserialize_(input);
		return result[0];
	},

	_unserialize_ : function(input) {
		var length = 0;
		var rtn, i, value;
		switch (input.charAt(0)) {
		/**
		 * Array
		 */
		case 'a':
			length = this._unserializeGetLength(input);
			input = input.substr(String(length).length + 4);

			var arr = [];
			var key = null;
			value = null;

			for (i = 0; i < length; ++i) {
				key = this._unserialize_(input);
				input = key[1];

				value = this._unserialize_(input);
				input = value[1];
				arr[key[0]] = value[0];
			}
			input = input.substr(1);
			rtn = [ arr, input ];
			break;

		/**
		 * Objects
		 */
		case 'O':
			length = this._unserializeGetLength(input);
			var classname = String(input.substr(String(length).length + 4,
					length));

			input = input.substr(String(length).length + 6 + length);
			var numProperties = Number(input.substring(0, input.indexOf(':')));
			input = input.substr(String(numProperties).length + 2);

			var obj = {};
			var property = null;
			value = null;

			for (i = 0; i < numProperties; ++i) {
				key = new PHP_Unserialize_(input);
				input = key[1];

				// Handle private/protected
				key[0] = key[0].replace(
						new RegExp('^\x00' + classname + '\x00'), '');
				key[0] = key[0].replace(new RegExp('^\x00\\*\x00'), '');

				value = new PHP_Unserialize_(input);
				input = value[1];

				obj[key[0]] = value[0];
			}

			input = input.substr(1);
			rtn = [ obj, input ];
			break;

		/**
		 * Strings
		 */
		case 's':
			length = this._unserializeGetLength(input);
			rtn = [ String(input.substr(String(length).length + 4, length)),
					input.substr(String(length).length + 6 + length) ];
			break;

		/**
		 * Integers and doubles
		 */
		case 'i':
		case 'd':
			var num = Number(input.substring(2, input.indexOf(';')));
			rtn = [ num, input.substr(String(num).length + 3) ];
			break;

		/**
		 * Booleans
		 */
		case 'b':
			var bool = (input.substr(2, 1) == 1);
			rtn = [ bool, input.substr(4) ];
			break;

		/**
		 * Null
		 */
		case 'N':
			rtn = [ null, input.substr(2) ];
			break;

		/**
		 * Unsupported
		 */
		case 'o':
		case 'r':
		case 'C':
		case 'R':
		case 'U':
			alert('Error: Unsupported PHP data type found!');
			break;
		/**
		 * Error
		 */
		default:
			rtn = [ null, null ];
			break;
		}
		return rtn;
	},

	_unserializeGetLength : function(input) {
		input = input.substring(2);
		var length = Number(input.substr(0, input.indexOf(':')));
		return length;
	},

	flashDebug : function(msg) {
		alert(msg);
		// $('msg').innerHTML = msg;
	},
	replaceChar : function(str) {
		str = str.replace(/\\/g, "\\\\");
		str = str.replace(/\'/g, "\\\'");
		return encodeURIComponent(str);
	},

	sleep : function(numberMillis) {
		var now = new Date();
		var exitTime = now.getTime() + numberMillis;

		while (true) {
			now = new Date();
			if (now.getTime() > exitTime) {
				return;
			}
		}
	},
	get : function(obj, id) {
		var id = Object.isNull(obj.objectId) ? id : obj.objectId + "." + id;
		return $(id).value;
	},
	set : function(obj, id, value) {
		var id = Object.isNull(obj.objectId) ? id : obj.objectId + "." + id;
		$(id).value = value;
	},
	onCopyUrl : function() {
		setTimeout(
				function() {
					alert('This URL has been copied to your clipboard. Use Ctrl+V to paste this URL.')
				}, 1);
	}
};

ViiKii.Util.Json = {
	parser : function(xmlcode, ignoretags, debug) {
		if (!ignoretags) {
			ignoretags = ""
		}
		;
		xmlcode = xmlcode.replace(/\s*\/>/g, '/>');
		xmlcode = xmlcode.replace(/<\?[^>]*>/g, "").replace(/<\![^>]*>/g, "");
		if (!ignoretags.sort) {
			ignoretags = ignoretags.split(",")
		}
		;
		var x = this.no_fast_endings(xmlcode);
		x = this.attris_to_tags(x);
		x = escape(x);
		x = x.split("%3C").join("<").split("%3E").join(">").split("%3D").join(
				"=").split("%22").join("\"");
		for ( var i = 0; i < ignoretags.length; i++) {
			x = x.replace(new RegExp("<" + ignoretags[i] + ">", "g"), "*$**"
					+ ignoretags[i] + "**$*");
			x = x.replace(new RegExp("</" + ignoretags[i] + ">", "g"), "*$***"
					+ ignoretags[i] + "**$*")
		}
		;
		x = '<JSONTAGWRAPPER>' + x + '</JSONTAGWRAPPER>';
		this.xmlobject = {};
		var y = this.xml_to_object(x).jsontagwrapper;
		if (debug) {
			y = this.show_json_structure(y, debug)
		}
		;
		return y
	},
	xml_to_object : function(xmlcode) {
		var x = xmlcode.replace(/<\//g, "�");
		x = x.split("<");
		var y = [];
		var level = 0;
		var opentags = [];
		for ( var i = 1; i < x.length; i++) {
			var tagname = x[i].split(">")[0];
			opentags.push(tagname);
			level++
			y.push(level + "<" + x[i].split("�")[0]);
			while (x[i].indexOf("�" + opentags[opentags.length - 1] + ">") >= 0) {
				level--;
				opentags.pop()
			}
		}
		;
		var oldniva = -1;
		var objname = "this.xmlobject";
		for ( var i = 0; i < y.length; i++) {
			var preeval = "";
			var niva = y[i].split("<")[0];
			var tagnamn = y[i].split("<")[1].split(">")[0];
			tagnamn = tagnamn.toLowerCase();
			var rest = y[i].split(">")[1];
			if (niva <= oldniva) {
				var tabort = oldniva - niva + 1;
				for ( var j = 0; j < tabort; j++) {
					objname = objname.substring(0, objname.lastIndexOf("."))
				}
			}
			;
			objname += "." + tagnamn;
			var pobject = objname.substring(0, objname.lastIndexOf("."));
			if (eval("typeof " + pobject) != "object") {
				preeval += pobject + "={value:" + pobject + "};\n"
			}
			;
			var objlast = objname.substring(objname.lastIndexOf(".") + 1);
			var already = false;
			for (k in eval(pobject)) {
				if (k == objlast) {
					already = true
				}
			}
			;
			var onlywhites = true;
			for ( var s = 0; s < rest.length; s += 3) {
				if (rest.charAt(s) != "%") {
					onlywhites = false
				}
			}
			;
			if (rest != "" && !onlywhites) {
				if (rest / 1 != rest) {
					rest = "'" + rest.replace(/\'/g, "\\'") + "'";
					rest = rest.replace(/\*\$\*\*\*/g, "</");
					rest = rest.replace(/\*\$\*\*/g, "<");
					rest = rest.replace(/\*\*\$\*/g, ">")
				}
			} else {
				rest = "{}"
			}
			;
			if (rest.charAt(0) == "'") {
				rest = 'unescape(' + rest + ')'
			}
			;
			if (already && !eval(objname + ".sort")) {
				preeval += objname + "=[" + objname + "];\n"
			}
			;
			var before = "=";
			after = "";
			if (already) {
				before = ".push(";
				after = ")"
			}
			;
			var toeval = preeval + objname + before + rest + after;
			eval(toeval);
			if (eval(objname + ".sort")) {
				objname += "[" + eval(objname + ".length-1") + "]"
			}
			;
			oldniva = niva
		}
		;
		return this.xmlobject
	},
	show_json_structure : function(obj, debug, l) {
		var x = '';
		if (obj.sort) {
			x += "[\n"
		} else {
			x += "{\n"
		}
		;
		for ( var i in obj) {
			if (!obj.sort) {
				x += i + ":"
			}
			;
			if (typeof obj[i] == "object") {
				x += this.show_json_structure(obj[i], false, 1)
			} else {
				if (typeof obj[i] == "function") {
					var v = obj[i] + "";
					// v=v.replace(/\t/g,"");
					x += v
				} else if (typeof obj[i] != "string") {
					x += obj[i] + ",\n"
				} else {
					x += "'"
							+ obj[i].replace(/\'/g, "\\'")
									.replace(/\n/g, "\\n")
									.replace(/\t/g, "\\t")
									.replace(/\r/g, "\\r") + "',\n"
				}
			}
		}
		;
		if (obj.sort) {
			x += "],\n"
		} else {
			x += "},\n"
		}
		;
		if (!l) {
			x = x.substring(0, x.lastIndexOf(","));
			x = x.replace(new RegExp(",\n}", "g"), "\n}");
			x = x.replace(new RegExp(",\n]", "g"), "\n]");
			var y = x.split("\n");
			x = "";
			var lvl = 0;
			for ( var i = 0; i < y.length; i++) {
				if (y[i].indexOf("}") >= 0 || y[i].indexOf("]") >= 0) {
					lvl--
				}
				;
				tabs = "";
				for ( var j = 0; j < lvl; j++) {
					tabs += "\t"
				}
				;
				x += tabs + y[i] + "\n";
				if (y[i].indexOf("{") >= 0 || y[i].indexOf("[") >= 0) {
					lvl++
				}
			}
			;
			if (debug == "html") {
				x = x.replace(/</g, "&lt;").replace(/>/g, "&gt;");
				x = x.replace(/\n/g, "<BR>").replace(/\t/g,
						"&nbsp;&nbsp;&nbsp;&nbsp;")
			}
			;
			if (debug == "compact") {
				x = x.replace(/\n/g, "").replace(/\t/g, "")
			}
		}
		;
		return x
	},
	no_fast_endings : function(x) {
		x = x.split("/>");
		for ( var i = 1; i < x.length; i++) {
			var t = x[i - 1].substring(x[i - 1].lastIndexOf("<") + 1)
					.split(" ")[0];
			x[i] = "></" + t + ">" + x[i]
		}
		;
		x = x.join("");
		return x
	},
	attris_to_tags : function(x) {
		var d = ' ="\''.split("");
		x = x.split(">");
		for ( var i = 0; i < x.length; i++) {
			var temp = x[i].split("<");
			for ( var r = 0; r < 4; r++) {
				temp[0] = temp[0].replace(new RegExp(d[r], "g"),
						"_jsonconvtemp" + r + "_")
			}
			;
			if (temp[1]) {
				temp[1] = temp[1].replace(/'/g, '"');
				temp[1] = temp[1].split('"');
				for ( var j = 1; j < temp[1].length; j += 2) {
					for ( var r = 0; r < 4; r++) {
						temp[1][j] = temp[1][j].replace(new RegExp(d[r], "g"),
								"_jsonconvtemp" + r + "_")
					}
				}
				;
				temp[1] = temp[1].join('"')
			}
			;
			x[i] = temp.join("<")
		}
		;
		x = x.join(">");
		x = x.replace(/ ([^=]*)=([^ |>]*)/g, "><$1>$2</$1");
		x = x.replace(/>"/g, ">").replace(/"</g, "<");
		for ( var r = 0; r < 4; r++) {
			x = x.replace(new RegExp("_jsonconvtemp" + r + "_", "g"), d[r])
		}
		;
		return x
	}
};

function OpenPopup(id, path, options) {
	this.options = {
		width : 200,
		height : 100,
		top : 0,
		left : 0,
		toolbar : 'no',
		scrollbar : 'no',
		location : 'no',
		directiores : 'no',
		resizable : 'no',
		menubar : 'no'
	};
	Object.extend(this.options, options || {});
	this.path = path || 'error_pop.html';
	this.id = id || 'PopupWin';
	window.open(this.path, this.id, Object.serialize(this.options));
}

function OpenLayer(id, templete, options) {
	this.options = {
		width : 200,
		height : 100,
		top : 0,
		left : 0
	};
	Object.extend(this.options, options || {});
	this.templete = templete || '';
	this.id = id || 'Layer_Error';
	// window.open(this.templete, this.id, Object.serialize(this.options));
}

function myViikii(id, callBy) {
	ViiKii.My.Open(id, callBy);
}

/**
 * Function : dump()
 * Arguments: The data - array,hash(associative array),object
 *    The level - OPTIONAL
 * Returns  : The textual representation of the array.
 * This function was inspired by the print_r function of PHP.
 * This will accept some data as the argument and return a
 * text that will be a more readable version of the
 * array/hash/object that is given.
 */
function dump(arr, level) {
	var dumped_text = "";
	if (!level) {
		level = 0;
	}

	//The padding given at the beginning of the line.
	var level_padding = "";
	for ( var j = 0; j < level + 1; j++) {
		level_padding += "    ";
	}

	if (typeof (arr) == 'object') { //Array/Hashes/Objects
		for ( var item in arr) {
			var value = arr[item];

			if (typeof (value) == 'object') { //If it is an array,
				dumped_text += level_padding + "[" + item + "]\n";
				dumped_text += dump(value, level + 1);
			} else {
				dumped_text += level_padding + "[" + item + "] => \"" + value
						+ "\"\n";
			}
		}
	} else { //Stings/Chars/Numbers etc.
		dumped_text = "===>" + arr + "<===(" + typeof (arr) + ")";
	}
	return dumped_text;
}

/*****************************************************************
 * viikiiImageLoader v 0.1
 * 	- require prototype 1.6.2
 *
 *****************************************************************/

var viikiiImagesLoaded = true;
var viikiiImagesDefaultOptions = {
	treshold : 100, // Offset from bottom to start preloading
	extensions : [ 'gif', 'png', 'jpg', 'bmp' ], // Array of extensions
	replaceImage : '/common/blank.gif', // Placeholder image to show instead of the image (best leave unchanged to this blank.gif!)
	loadingImage : '/common/loading.gif', // Loading indicator
	minWidth : 100, // Minimum width of an image
	minHeight : 100
// Minimum height of an image
};

ViiKii.imageLoader = Class.create();
ViiKii.imageLoader.prototype = {
	initialize : function(options) {
		$$('img').each( function(image) {
			var imgloader = new ViiKii.imageLoad(image, options);
		});
	}
};

ViiKii.imageLoad = Class.create();
ViiKii.imageLoad.prototype = {
	options : null,
	element : null,
	loading : false,
	loaded : false,
	position : null,
	viewHeight : 0,
	Scroller : null, // cached bounds function - see http://www.prototypejs.org/api/event/stopObserving

	initialize : function(image, options) {
		this.options = Object.clone(viikiiImagesDefaultOptions);
		Object.extend(this.options, options || {});

		this.element = image;
		this.position = Position.page(this.element);
		this.viewHeight = document.viewport.getHeight();

		if (this.position[1] < (this.viewHeight + this.options.treshold)) {
			this.loading = true;
			this.loaded = true;
		} else {
			// get original source element (for further reference), the filename and the extension.
	this.element.origSrc = this.element.src;
	this.element.fileName = this.element.origSrc.substring(this.element.origSrc
			.lastIndexOf('/') + 1, this.element.origSrc.length);
	this.element.fileType = this.element.fileName.substring(
			this.element.fileName.lastIndexOf('.') + 1,
			this.element.fileName.length);

	// extension not in array; no need
	if (this.options.extensions.indexOf(this.element.fileType) == -1) {
		return;
	}

	// image not large enough
	if ((this.element.width <= parseInt(this.options.minWidth, 10))
			&& (this.element.height <= parseInt(this.options.minHeight, 10))) {
		return;
	}

	// set blank and loading image
	this.element.src = this.options.replaceImage;
	this.element.setStyle( {
		backgroundImage : 'url(' + this.options.loadingImage + ')',
		backgroundPosition : '50% 50%',
		backgroundRepeat : 'no-repeat'
	});

	// observe the page scroll event
	this.Scroller = this.Scroll.bindAsEventListener(this);
	Event.observe(window, 'scroll', this.Scroller.bind(this), false);
}
},

Scroll : function() {
// image not loaded and not loading
	if ((this.loaded === false) && (this.loading !== true)) {
		// image "above the fold" ?
		if ((document.viewport.getScrollOffsets()[1]
				+ document.viewport.getHeight() + parseInt(
				this.options.treshold, 10)) > this.position[1]) {

			this.loading = true;

			// load in the new image
			var newImage = null;
			newImage = new Image();
			newImage.src = this.element.origSrc;

			// image is in cache (IE6 & IE7 ... Firefox can handle the onload
			// well even file was in cache);
			if (newImage.complete) {
				this.element.src = newImage.src;
				this.loaded = true;
				// image not in cache
			} else {
				newImage.onload = function() {
					this.element.src = newImage.src;
					this.loaded = true;
				}.bind(this);
			}

			// stop the observer
			Event.stopObserving(window, 'scroll', this.Scroller);
		}
	}
}
};

/**
 * Hook ImagesLoad to the dom:loaded event
 * -------------------------------------------------------------
 */
function initImagesLoad() {
	var myIL = new ViiKii.imageLoader();
}
if (viikiiImagesLoaded === true) {
	Event.observe(document, 'dom:loaded', initImagesLoad, false);
}

/**
 * References - viikiiMy.js (ViiKii.My)
 * 2008/08/18 Yim.kwangjin.
 * // [[START --
 */
var isOwner = false; // Global Variables

ViiKii.My = {
	isLogin : ViiKii.Util.getDomainCookie('username') == null ? false : true,
	Open : function(username) {
		this.loginname = ViiKii.Util.getDomainCookie('username');
		if (typeof username == 'undefined') {
			username = this.loginname;
		}
		window.open('/my/page/' + username);
	},
	checkUrl: function() {
		var param = new RegExp(/#(.+)/).exec(document.location);
		if(!param) {
			return;
		}
		var command = param[1].split('/');
		if(!command || command.length < 2) {
			return;
		}
		switch(command[0]) {
		case 'TOPIC':
			ViiKii.My.Topic.TopicPage.load(command[1])
			break;
		}
	}
};
ViiKii.My.subtitles = {
	category : 'A',
	user_name : null,
	view_page : 1,
	loaded : false,
	_selectedItems : [],
	_isSelectedAll : false,
	folder_id : 0,

	/* [s] Lists */
	open : function(user_name, category) {
		this.category = category;
		this.user_name = user_name;
		this.view_page = 1;
		this.loaded = true;
		this.folder_id = 0;
		this.list();
	},
	openFolder : function(user_name, folderId, depth) {
		if (1 == depth && $("subfolders_" + folderId) && ! $("subfolders_" + folderId).innerHTML.trim().empty()) {
			if ($("subfolders_" + folderId).visible()) {
				$("my_folder_" + folderId).setStyle({background : 'rgb(128, 128, 128) url(http://vkcommon.viikii.net/bullet003_ss_left.gif) no-repeat 191px center'});
			} else {
				$("my_folder_" + folderId).setStyle({background : 'rgb(128, 128, 128) url(http://vkcommon.viikii.net/bullet003_ss_down.gif) no-repeat 188px center'});
			}
			$("subfolders_" + folderId).toggle();
		}
		
		this.category = 'F';
		this.user_name = user_name;
		this.view_page = 1;
		this.folder_id = folderId;
		this.list();
	},

	reload : function() {
		ViiKii.My.Folder.reloadFolderList(this.user_name, 'SU');
		this.list();
	},

	list : function() {
		var url = '/my_subtitles/open/' + [ this.category, this.user_name,
				this.view_page, this.folder_id ].join('/');
		var res = new Ajax.Updater('my_viikii_content', url, {
			asynchronous : true,
			parameters : null,
			evalScripts : true,
			onFailure : function(e) {
				alert(e.responseText);
			}
		});
	},

	del : function(ele, videoId, segmentId, subtitleId, languageId, sort) {
		if (!this.islogin()) {
			ViiKii.Login.popUp();
			return;
		}
		var position = Position.positionedOffset(ele);

		var str = '<div id="c_msg" style="">'
				+ '	<div style="width:300px; height:15px;"><img src="/common/close.gif" style="cursor:pointer;" border="0" align="right" onClick="ViiKii.My.subtitles.deleteCancel();"></div>'
				+ '	<div style="width:280px; height:15px; padding-left:20px; text-align:left;">You cannot remove your subtitle in your page.</div>'
				+ '	<div style="width:280px; height:3px;"></div>'
				+ '	<div style="width:280px; height:15px; padding-left:20px; text-align:left;">You can only delete your subtitle permanently</div>'
				+ '	<div style="width:280px; height:3px;"></div>'
				+ '	<div style="width:280px; height:15px; padding-left:20px; text-align:left;">and you sure to delete this subtitle permanently?</div>'
				+ '	<div style="width:280px; height:15px;"></div>'
				+ '	<div style="width:300px; height:30px;">'
				+ '		<div style="float:left;height:30px;width:140px;margin:0 12 0 0;text-align:center;"><a href="javascript:ViiKii.My.subtitles.deleteYes('
				+ videoId
				+ ','
				+ segmentId
				+ ','
				+ subtitleId
				+ ',\''
				+ languageId
				+ '\',\''
				+ sort
				+ '\');">yes</a></div>'
				+ '		<div style="float:left;height:30px;width:140px;text-align:left;"><a href="javascript:ViiKii.My.subtitles.deleteCancel();">cancel</a></div>'
				+ '	</div>' + '</div>' + '';

		$('del_msg').innerHTML = str;
		Element.setStyle($('del_msg'), {
			left : position[0] - 300 + 'px',
			top : position[1] + 'px',
			border : '1px solid gray',
			display : 'block'
		});
	},
	deleteYes : function(videoId, segmentId, subtitleId, languageId, sort) {
		if (!this.islogin()) {
			ViiKii.Login.popUp();
			return;
		}
		var url = '/my_subtitles/delete_subtitle/' + videoId + '/' + segmentId
				+ '/' + subtitleId + '/' + languageId + '/' + sort;
		var xml = new Ajax.RequestXML(url, {
			asynchronous : false,
			method : 'get',
			parameters : null
		});
		Element.setStyle($('del_msg'), {
			display : 'none'
		});
		this.onDeleteSuccess(xml.responseValue);
	},
	deleteCancel : function() {
		Element.setStyle($('del_msg'), {
			display : 'none'
		});
	},
	onDeleteSuccess : function(xml) {
		var response = xml.response;
		if (response.status == 'success') {
			this.reload();
			return;
		} else {
			//reponse.error
			switch (response.error) {
			case 'ERR_NOT_VIDEO':
			case 'ERR_NOT_PUBLISHED':
			case 'ERR_NOT_SUBTITLE':
				//todo...
				break;
			}
			alert('error');
		}
	},
	/* [e] Lists */
	/* [s] check */
	_isChecked : function(idx) {
		return -1 != idx;
	},
	_selectAllItems : function(ids, checked) {
		var ico = (checked) ? '/common/checkbox_ch.gif'
				: '/common/checkbox_wh.gif';
		this._isSelectedAll = checked;
		if (checked) {
			this._selectedItems = ids;
		} else {
			this._selectedItems.clear();
		}
		for (num = 0; num < ids.length; num++) {
			$('my_subtitle_chkbox_' + ids[num]).src = ico;
		}
		$('my_subtitle_chkbox_all').src = ico;
	},
	check : function(id) {
		var idx = this._selectedItems.indexOf(id);
		if (this._isChecked(idx)) {
			this._selectedItems.splice(idx, 1);
			$('my_subtitle_chkbox_' + id).src = '/common/checkbox_wh.gif';
		} else {
			this._selectedItems.push(id);
			$('my_subtitle_chkbox_' + id).src = '/common/checkbox_ch.gif';
		}
	},
	checkAll : function(ids) {
		if (ids.length > 0) {
			var checked = (this._isSelectedAll) ? false : true;
			this._selectAllItems(ids, checked);
		}
	},
	copyto : function(user_name) {
		if (!this.islogin()) {
			return;
		}
		if (this._selectedItems.length <= 0) {
			alert('Nothing was selected.');
			return;
		}
		var params = $H( {
			'user_name' : user_name,
			'items' : this._selectedItems.join(',')
		}).toQueryString();

		var res = new Ajax.Updater('target_list', '/my_subtitles/copyto/', {
			asynchronous : false,
			evalScripts : true,
			parameters : params,
			onFailure : function(e) {
				alert(e.responseText);
			}
		/*					,onComplete: function(e){alert(e.responseText);}		*/
		});
		var positions = Position.positionedOffset($('copyto_btn'));
		$('target_list').setStyle( {
			display : 'block',
			left : (positions[0] - 234) + 'px',
			top : positions[1] + 'px'
		});
	},
	unlink : function() {
		if (this._selectedItems.length <= 0) {
			alert('Nothing was selected.');
			return;
		}
		var params = $H( {
			'user_name' : this.user_name,
			'items' : this._selectedItems.join(','),
			'category' : this.category,
			'folder_id' : this.folder_id
		}).toQueryString();

		var url = '/my_subtitles/unlink/';
		var responseXml = new Ajax.RequestXML(url, {
			asynchronous : false,
			evalScripts : true,
			parameters : params,
			onFailure : function(e) {
				alert(e.responseText);
			}
		});
		this.proc_complete(this.user_name, responseXml.responseValue);
	},

	deleteBySuper : function() {
		if (this._selectedItems.length <= 0) {
			alert('Nothing was selected.');
			return;
		}
		var params = $H( {
			'user_name' : this.user_name,
			'items' : this._selectedItems.join(',')
		}).toQueryString();

		var url = '/my_subtitles/deleteBySuperuser/';
		var responseXml = new Ajax.RequestXML(url, {
			asynchronous : false,
			evalScripts : true,
			parameters : params,
			onFailure : function(e) {
				alert(e.responseText);
			}
		/*				,onComplete: function(e) {alert(e.responseText);}	*/
		});
		this.proc_delete(responseXml.responseValue);
	},
	proc_delete : function(xml) {
		var response = xml.response;
		// if (response.status == 'success') {
		this.reload();
		// }
	},

	myscrapto : function(user_name, id) {
		if (!this.islogin()) {
			return;
		}
		if (this._selectedItems.length > 0) {
			this.clearBox();
		}
		this.markingBox(id);

		var params = $H( {
			'user_name' : user_name,
			'items' : id
		}).toQueryString();

		var res = new Ajax.Updater('target_list', '/my_subtitles/copyto/', {
			asynchronous : false,
			evalScripts : true,
			parameters : params,
			onFailure : function(e) {
				alert(e.responseText);
			}
		/*				,onComplete: function(e) {alert(e.responseText);}		*/
		});

		var positions = Position.positionedOffset($('my_scrap_' + id));
		$('target_list').setStyle( {
			display : 'block',
			left : (positions[0] - 234) + 'px',
			top : positions[1] + 'px'
		});
	},

	clearBox : function() {
		for (num = 0; num < this._selectedItems.length; num++) {
			$('my_subtitle_chkbox_' + this._selectedItems[num]).src = '/common/checkbox_wh.gif';
		}
		$('my_subtitle_chkbox_all').src = '/common/checkbox_wh.gif';
		this._selectedItems.clear();
	},

	markingBox : function(id) {
		this._selectedItems.push(id);
		$('my_subtitle_chkbox_' + id).src = '/common/checkbox_ch.gif';
	},

	scrapto : function(ele, user_name, sub_id) {
		ViiKii.Tracker.track("/TRACK/subtitles/scrapto/" + user_name + "/"
				+ sub_id);
		var params = $H( {
			'user_name' : user_name,
			'item' : sub_id
		}).toQueryString();
		var url = '/my_subtitles/scrapto/'
		var res = new Ajax.Updater('popup_subtitle', url, {
			asynchronous : false,
			evalScripts : true,
			parameters : params,
			onFailure : function(e) {
				alert(e.responseText);
			}
		/*				,onComplete: function(e) {alert(e.responseText);}		*/
		});
		var positions = Position.positionedOffset(ele);
		$('popup_subtitle').setStyle( {
			display : 'block',
			left : (positions[0] - 234) + 'px',
			top : positions[1] + 'px'
		});
	},
	initialize_folder : function() {
		this._selectedTargets.clear();
		this._selectedFoldername.clear();
	},

	scrapPopup : function(user_name) {
		$('popup_subtitle').style.display = 'none';
		if (confirm('The subtitle was pasted into your favorite subtitles.\nDo you want to check it out?')) {
			document.location.href = '/my/page/' + user_name;
		}
	},

	nofolder_Popup : function(user_name) {
		if (user_name == this.user_name) {
			alert('You have no folder yet in "your ViiKii". \nYou must create a folder first in which subtitles can be saved.');
		} else {
			$('target_list').style.display = 'none';
			if (confirm('The subtitle was pasted into your favorite subtitles.\nDo you want to check it out?')) {
				document.location.href = '/my/page/' + user_name;
			}
		}
	},

	/* [e] check */
	/* [s] Common */
	govideo : function(video_id) {
		if (!isNaN(video_id)) {
			document.location.href = "/videos/watch/" + video_id;
		} else {
			alert('Invalid Access!')
		}
	},

	gopage : function(page) {
		if (!isNaN(page)) {
			this.view_page = page;
			this.list();
		} else {
			alert('Invalid Access!')
		}
	},
	jumpto : function(video_id, pos) {
		//alert([video_id, pos].join(','));
		this.govideo(video_id);
		return;
	},

	islogin : function() {
		if (ViiKii.Util.getDomainCookie('username') !== null) {
			return true;
		} else {
			ViiKii.Login.popUp();
			return false;
		}
	},
	/* [e] common */
	/* [s] folder */

	_selectedTargets : [],
	_selectedFoldername : [],
	_isSelectedAllTargets : false,
	_isOpenedCopyTargetList : false,

	_selectAllTargets : function(ids, fnames, checked) {
		var ico = (checked) ? '/common/checkbox_ch.gif'
				: '/common/checkbox_wh.gif';
		this._isSelectedAllTargets = checked;
		if (checked) {
			this._selectedTargets = ids;
			this._selectedFoldername = fnames;
		} else {
			this._selectedTargets.clear();
			this._selectedFoldername.clear();
		}
		$$('img.chkfolder').each( function(e) {
			e.src = ico;
		});
		$('target_folder_chkbox_all').src = ico;
	},

	check_target : function(id, fname) {

		var idx = this._selectedTargets.indexOf(id);
		if (this._isChecked(idx)) {
			this._selectedTargets.splice(idx, 1);
			this._selectedFoldername.splice(idx, 1);
			$('target_folder_' + id).src = '/common/checkbox_wh.gif';
		} else {
			this._selectedTargets.push(id);
			this._selectedFoldername.push(fname);
			$('target_folder_' + id).src = '/common/checkbox_ch.gif';
		}
	},

	checkAll_target : function(ids, fnames) {
		if (ids.length > 0) {
			var checked = (this._isSelectedAllTargets) ? false : true;
			this._selectAllTargets(ids, fnames, checked);
		}
	},

	copy2folder : function(user_name) {
		if (this._selectedItems.length <= 0) {
			return;
		}
		if (this.user_name == user_name && this._selectedTargets.length <= 0) {
			alert('You have no folder yet in "your ViiKii". \nYou must create a folder first in which subtitles can be saved.');
			return;
		}

		var params = $H(
				{
					'user_name' : user_name,
					'from_user' : this.user_name,
					'items' : this._selectedItems.join(','),
					'targets' : (this._selectedTargets.length <= 0) ? 0
							: this._selectedTargets.join(',')
				}).toQueryString();
		var url = '/my_subtitles/copy2folder/';
		var responseXml = new Ajax.RequestXML(url, {
			asynchronous : false,
			evalScripts : true,
			parameters : params,
			onFailure : function(e) {
				alert(e.responseText);
			}
		/*				,onComplete: function(e) {alert(e.responseText);}	*/
		});
		this.proc_complete(user_name, responseXml.responseValue);
	},
	proc_complete : function(user_name, xml) {
		var response = xml.response;
		if (response.status == 'success') {
			this.reload();
			if (response.action == 'copy2folder') {
				if (this.user_name == user_name) {
					if (this._selectedTargets.length > 0) {
						alert('The subtitle was copied into [' + this._selectedFoldername + '].');
					}
					this.initialize_folder();
				} else {
					if (this._selectedTargets.length > 0) {
						if (confirm('The subtitle was copied into [' + this._selectedFoldername + '].\nDo you want to check it out?')) {
							document.location.href = '/my/page/' + user_name;
						}
					} else {
						if (confirm('The subtitle was pasted into your favorite subtitles.\nDo you want to check it out?')) {
							document.location.href = '/my/page/' + user_name;
						}
					}
					this.initialize_folder();
				}
			} else if (response.action == 'unlink') {
				alert('removed successfully.');
			}
		} else {
			//alert(response.error);
			switch (response.error) {
			case 'INVALID_IDENTITY':
				document.location = '/';
				break;
			case 'DB_ERROR':
				alert('Fail, to remove subtitle');
				break;
			case 'NOT_EMPTY_CONTENTS':
				alert('This subtitle cannot be deleted because other users already contributed to this subtitle');
				break;
			case 'EXIST_OWNS_DISCUSSION':
				alert('You cannot remove your own subtitle.');
				this.reload();
				break;
			}
		}
	},
	scrap2folder : function(user_name, item) {
		if (this.user_name == user_name && this._selectedTargets.length <= 0) {
			alert('You have no folder yet in "your ViiKii". \nYou must create a folder first in which subtitles can be saved.');
			return;
		}

		var params = $H(
				{
					'user_name' : user_name,
					'from_user' : this.user_name,
					'item' : item,
					'targets' : (this._selectedTargets.length <= 0) ? 0
							: this._selectedTargets.join(',')
				}).toQueryString();

		var url = '/my_subtitles/scrap2folder/';
		var responseXml = new Ajax.RequestXML(url, {
			asynchronous : false,
			evalScripts : true,
			parameters : params,
			onFailure : function(e) {
				alert(e.responseText);
			}
		//				,onComplete: function(e) {alert(e.responseText);}
				});
		this.scrap_complete(user_name, responseXml.responseValue, item);
	},
	scrap_complete : function(user_name, xml, id) {
		//	alert(dump(xml));
	var response = xml.response;
	// alert(dump(response));
	$('popup_subtitle').style.display = 'none';
	if (response.status == 'success') {
		//		alert(response.cnt);
		if (this._selectedTargets.length > 0) {
			if (confirm('The subtitle was copied into [' + this._selectedFoldername + '].\nDo you want to check it out?')) {
				document.location.href = '/my/page/' + user_name;
			} else {
				$('scrapcnt_' + id).innerHTML = response.cnt;
			}
		} else {
			if (confirm('The subtitle was pasted into your favorite subtitles.\nDo you want to check it out?')) {
				document.location.href = '/my/page/' + user_name;
			} else {
				$('scrapcnt_' + id).innerHTML = response.cnt;
			}
		}
		this.initialize_folder();
	} else {
		//alert(response.error);
		switch (response.error) {
		case 'INVALID_IDENTITY':
			document.location = '/';
			break;
		case 'DB_ERROR':
			alert('Fail, to remove subtitle');
			break;
		case 'NOT_EMPTY_CONTENTS':
			alert('This subtitle cannot be deleted because other users already contributed to this subtitle');
			break;
		case 'EXIST_OWNS_DISCUSSION':
			alert('You cannot remove your own subtitle.');
			this.reload();
			break;
		}
	}
}
/* [e] folder */
};
ViiKii.Manage = {};
ViiKii.Manage.Inbox = {
	_ischecked : false,

	sendInbox : function() {
		if (this._ischecked) {
			this.sendAll();
		} else {
			this.sendTo();
		}
	},

	CheckAll : function() {
		if (this._ischecked == false) {
			$('inbox_chkbox').src = '/common/checkbox_ch.gif';
			$('inbox_to_users').value = "";
			this._ischecked = true;
		} else {
			$('inbox_chkbox').src = '/common/checkbox_wh.gif';
			this._ischecked = false;
		}
	},

	sendTo : function() {
		var params = $H( {
			'to_user' : $F('inbox_to_users'),
			'from_user' : $F('inbox_from_user'),
			'content' : $F('inbox_content')
		}).toQueryString();

		var responseXml = new Ajax.RequestXML('/inboxes/sendTo', {
			evalScripts : false,
			parameters : params,
			onComplete : function(transport, response) {
				if ('success' == response.result) {
					alert('send inbox, successfully!');
				} else {
					alert('send inbox, Fail');
				}
			}
		});
	},

	sendAll : function() {
		var params = $H( {
			'user_name' : $('inbox_from_user').value,
			'content' : $('inbox_content').value
		}).toQueryString();

		var responseXml = new Ajax.RequestXML('/inboxes/sendAll', {
			asynchronous : false,
			evalScripts : false,
			parameters : params,
			onComplete : function(transport, response) {
				if ('success' == response.result) {
					alert('send inbox, successfully!');
				} else {
					alert('send inbox, Fail');
				}
			}
		});
	}
};

ViiKii.My.Page = {
	_imgUploadLayerName : 'my_viikii_intro_upload_layer',
	_shadow : null,

	clickOnPage : function(event) {
		if (ViiKii.My.Folder.isOpenContextMenu()) {
			ViiKii.My.Folder.closeContextMenu();
		}

		if (ViiKii.My.Folder.isOpenEditInputBox()) {
			ViiKii.My.Folder.closeEditInputBox();
		}
	},

	uploadProfildImg : function(userName, url) {
		var flashTag = '';
		var src = '/viewer/image_uploader_090116.swf?';
		src += 'url=' + url;
		src += '&type=MYVIIKII_PROFILE';
		src += '&user_name=' + userName;

		src += '&message=*.jpg square image under 1MB only.<br>A 72 X 72 size image would be the best.';
		src += '&success_callback=ViiKii.My.Page.successIntroImageUpload';
		src += '&cancel_callback=ViiKii.My.Page.cancelIntroImageUpload';

		if (Prototype.Browser.IE) {
			flashTag += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="295" height="144" id="ViiKii_Upload_flash" align="middle">';
			flashTag += '<param name="allowScriptAccess" value="sameDomain" />';
			flashTag += '<param name="allowFullScreen" value="false" />';
			flashTag += '<param name="movie" value="' + src + '" />';
			flashTag += '<param name="quality" value="high" />';
			flashTag += '<param name="bgcolor" value="#ffffff" />';
			flashTag += '</object>';
		} else {
			flashTag += '<embed id="ViiKii_Upload_flash" ';
			flashTag += 'src="' + src + '" quality="high" ';
			flashTag += 'bgcolor="#ffffff" width="295" ';
			flashTag += 'height="144" name="ViiKii_Upload_flash" ';
			flashTag += 'align="middle" allowScriptAccess="sameDomain" ';
			flashTag += 'allowFullScreen="false" ';
			flashTag += 'type="application/x-shockwave-flash" ';
			flashTag += 'pluginspage="http://www.macromedia.com/go/getflashplayer" />';
		}

		var htmlTag = "<div style='float:left;width:343px;height:193px;text-align:center;'>";
		htmlTag += "<div id='my_viikii_intro_upload_layer_title' style='float:left;margin-top:2px;width:343px;height:32px;text-align:right;'>";
		htmlTag += "<img src='/common/close.gif' onClick='ViiKii.My.Page.closeImgUploadLayer()'>&nbsp;</div>";
		htmlTag += flashTag + "</div>";
		return htmlTag;
	},

	successIntroImageUpload : function() {
		this.reloadIntroImg();
	},

	cancelIntroImageUpload : function() {
		this.closeImgUploadLayer();
	},

	openProfileImgUploadLayer : function(userName, url) {
		if (!$(this._imgUploadLayerName)) {
			var e = document.createElement('div');
			e.id = this._imgUploadLayerName;
			var styles = {
				position : 'absolute',
				top : '100px',
				left : '100px',
				width : '345px',
				height : '193px',
				backgroundColor : '#FFFFFF'
			};
			Element.setStyle(e, styles);
			e.innerHTML = this.uploadProfildImg(userName, url);
			document.getElementsByTagName('body')[0].appendChild(e);
			ViiKii.UI.Round.init(this._imgUploadLayerName, {
				corners : 'all',
				borderSize : 1
			});

			this._shadow = new ViiKii.UI.Shadow(this._imgUploadLayerName);
			DragHandler.attach(this._shadow.container,
					$('my_viikii_intro_upload_layer_title'));
		}
	},

	closeImgUploadLayer : function() {
		document.getElementsByTagName('body')[0]
				.removeChild($(this._shadow.container));
		this._shadow = null;
	},

	reloadIntroImg : function() {
		document.location.reload();
	}
};

ViiKii.My.Folder = {
	_folderId : 0,
	_depth : 0,
	_oldFolderInnerHTML : '',
	_userName : '',
	_type : '',
	_contextMenuOpened : false,
	_editInputBoxOpened : false,
	
	toggleList: function(title, type) {
		$(type + "_folder_list_wrap").toggle();
		$(type + "_folder_count").toggle();
		if ($(type + "_new_folder")) {
			$(type + "_new_folder").toggle();
		}
		if ($(type + "_folder_list_wrap").visible()) {
			title.style.background = "url(/common/bullet001_s.gif) no-repeat 3px center";
		} else {
			title.style.background = "url(/common/bullet001_s_rotate.gif) no-repeat 5px center";
		}
	},

	isOpenContextMenu : function() {
		return this._contextMenuOpened;
	},

	isOpenEditInputBox : function() {
		return this._editInputBoxOpened;
	},

	onContextMenu : function(event, folderId, depth, locked, type) {
		if ($('folder-context-menu')) {
			if (this.isOpenEditInputBox()) {
				this.closeEditInputBox();
			}
			
			this._folderId = folderId;
			this._depth = depth;
			this._type = type;

			if (2 == depth) {
				$('folder-context-menu-add').hide();
			} else {
				$('folder-context-menu-add').show();
			}
			
			$('folder-context-menu').style.left = Event.pointerX(event) + 'px';
			$('folder-context-menu').style.top = Event.pointerY(event) + 'px';
			$('folder-context-menu').style.display = 'block';
			this._contextMenuOpened = true;
			Event.stop(event); // remove document original contextmenu event
		}
	},
	closeContextMenu : function() {
		$('folder-context-menu').style.display = 'none';
		this._contextMenuOpened = false;
	},
	
	addFolder: function(userName, type) {
//		'VI', 'SU', 'CH', 'FO', 'TP', 'DI'
		var req = new Ajax.Request('/myFolders/addFolder/' + userName + '/' + type, {
			asynchronous : false,
			method : 'post',
			parameter : null,
			onComplete : function(transport, response) {
				if ("success" == response.status) {
					var tag = ViiKii.My.Folder.getDepthOneFolderTag(response.user, response.id, response.folder_name, response.type);
					$(response.type + "_folder_list").update(tag + $(response.type + "_folder_list").innerHTML);
					if ( ! $(response.type + "_folder_list").visible()) {
						$(response.type + "_folder_list").show();
					}
				} else {
					alert('Fail, to add folder');
				}
			}
		});
	},

	addSubFolder : function(event, userName) {
		this.closeContextMenu();
		var req = new Ajax.Request('/my_folders/addSubFolder/' + userName + '/'
				+ this._folderId, {
			asynchronous : false,
			method : 'post',
			parameter : null,
			onComplete : function(transport, response) {
				if ('success' == response.result) {
					var tag = ViiKii.My.Folder.getDepthTwoFolderTag(response.user, response.id, response.folder_name, response.type);
					$('subfolders_' + response.parent_folder_id).update(tag + $('subfolders_' + response.parent_folder_id).innerHTML);
					if ( ! $('subfolders_' + response.parent_folder_id).visible()) {
						$("my_folder_" + response.parent_folder_id).setStyle({background : 'rgb(128, 128, 128) url(/img/common/bullet003_ss_down.gif) no-repeat 188px center'});
						$('subfolders_' + response.parent_folder_id).show();
					}
				} else {
					alert('Fail, to add sub folder');
				}
			}
		});
		Event.stop(event);
	},
	
	getOpenFolderClickFn: function(type, user, folderId, depth) {
		var fn = "";
		switch (type) {
		case "VI":
			fn = "ViiKii.My.videos.openFolder";
			break;
		case "SU":
			fn = "ViiKii.My.subtitles.openFolder";
			break;
		case "DI":
			fn = "ViiKii.My.discussions.openFolder";
			break;
		case "TP":
			return "ViiKii.My.Topic.TopicList.display(\"FO\", " + folderId + ", " + depth + ")";
		}
		return fn + "(\""+user+"\", " + folderId + ", " + depth + ")";
	},
	
	getContextMenuFn: function(folderId, depth, locked, type) {
		return "ViiKii.My.Folder.onContextMenu(event, " + folderId + ", " + depth + ", " + locked + ", \"" + type + "\")";
	},
	
	getDepthOneFolderTag: function(user, folderId, folderName, type) {
		depth = 1;
		locked = 0;
		tag = "<div id='my_folder_" + folderId + "' class='folder' onclick='" + this.getOpenFolderClickFn(type, user, folderId, depth) + "' oncontextmenu='" + this.getContextMenuFn(folderId, depth, locked, type) + "'>";
		tag += "<span id='my_folder_name_" + folderId + "'>" + folderName + "</span> <span>(0)</span>";
		tag += "</div>";
		tag += "<div id='subfolders_" + folderId + "' style='display:none;float:left;width:193px;'></div>";
		return tag;
	},
	
	getDepthTwoFolderTag: function(user, folderId, folderName, type) {
		depth = 2;
		locked = 0;
		var tag = "<div id='my_folder_" + folderId + "' class='sub_folder' onclick='" + this.getOpenFolderClickFn(type, user, folderId, depth) + "' oncontextmenu='" + this.getContextMenuFn(folderId, depth, locked, type) + "'>";
		tag += "- <span id='my_folder_name_" + folderId + "'>" + folderName + "</span> <span>(0)</span>";
		tag += "</div>";
		return tag;
	},
	
	openEditInputBox : function(event, userName) {
		Event.stop(event); // For ViiKii.My.Page.clickOnPage - observer
							// document click event, see also,
							// /views/users/page.thtml
		this.closeContextMenu();

		this._userName = userName;
		this._oldFolderInnerHTML = $('my_folder_' + this._folderId).innerHTML;
		var folderName = $('my_folder_name_' + this._folderId).innerHTML;

		var color = '#ffffff';
		if (2 == this._depth) {
			color = '#808080';
		}

		$('my_folder_' + this._folderId).innerHTML = "<input id='my_folder_"
				+ this._folderId
				+ "_edit' type='text' onKeyDown='ViiKii.My.Folder.onKeyDown(event)' style='width:100%;border:0;background-color:transparent;color:"
				+ color + "' maxlength='80' onclick='Event.stop(event)'>";
		$('my_folder_' + this._folderId + '_edit').value = folderName;
		$('my_folder_' + this._folderId + '_edit').focus();

		this._editInputBoxOpened = true;
	},

	onKeyDown : function(event) {
		switch (event.keyCode) {
		case Event.KEY_RETURN:
			var folderName = $('my_folder_' + this._folderId + '_edit').value;
			this.closeEditInputBox();
			this.rename(this._userName, folderName);
			break;
		case Event.KEY_ESC:
			this.closeEditInputBox();
			break;
		}
	},

	closeEditInputBox : function() {
		$('my_folder_' + this._folderId).innerHTML = this._oldFolderInnerHTML;
		this._editInputBoxOpened = false;
	},

	rename : function(userName, folderName) {
		var params = $H( {
			'userName' : userName,
			'folderId' : this._folderId,
			'folderName' : folderName
		}).toQueryString();
		
		var req = new Ajax.Request("/myFolders/rename/", {
			asynchronous : false,
			method : 'post',
			parameters : params,
			onComplete: function(transport, response) {
				if ("success" == response.status) {
					if ( $("my_folder_name_" + response.folderId)) { 
						$("my_folder_name_" + response.folderId).update(response.folderName);
					}
				} else {
					alert("Fail, to rename folder");
				}
			}
		});
	},
	remove: function(event, userName) {
		this.closeContextMenu();
		var req = new Ajax.Request('/myFolders/remove/' + userName + '/' + this._folderId + '/' + this._type, {
			asynchronous : false,
			method : 'post',
			parameters : null,
			onComplete: function(transport, response) {
				if ("success" == response.status) {
					if ($("my_folder_" + response.folderId)) {
						$("my_folder_" + response.folderId).remove();
					}
					//this condition for only IE browser!!
					if ($("subfolders_" + response.parentFolderId) && $("subfolders_" + response.parentFolderId).innerHTML.trim().empty()) {
						$("subfolders_" + response.parentFolderId).hide();	
					}
					if ($("subfolders_" + response.folderId)) {
						$("subfolders_" + response.folderId).remove();
					}
					if ($(response.type + "_folder_list").innerHTML.trim().empty()) {
						$(response.type + "_folder_list").hide();
					}
				} else {
					alert("Fail, to delete folder");
				}
			}
		});
		Event.stop(event);
	},
	lock : function(userName) {
		this.closeContextMenu();
		var responseXml = new Ajax.RequestXML('/myFolders/lock/' + userName
				+ '/' + this._folderId, {
			asynchronous : false,
			method : 'post',
			parameters : null,
			onFailure : function(transport) {
				alert(transport.responseText);
			}
		});
		this._onLockComplete(responseXml.responseValue, userName, this._type);
	},

	_onLockComplete : function(xml, userName, type) {
		var response = xml.response;
		if (response.status == 'success') {
			this.reloadFolderList(userName, type);
		} else {
			switch (response.error) {
			case 'DB_ERROR':
				alert('Fail, to lock folder');
				break;
			case 'INVALID_IDENTITY':
				document.location = '/';
				break;
			}
		}
		Event.stop(event);
	},

	unlock : function(userName) {
		this.closeContextMenu();
		var responseXml = new Ajax.RequestXML('/myFolders/unlock/' + userName
				+ '/' + this._folderId, {
			asynchronous : false,
			method : 'post',
			parameters : null,
			onFailure : function(transport) {
				alert(transport.responseText);
			}
		});
		this._onUnlockComplete(responseXml.responseValue, userName, this._type);
	},

	_onUnlockComplete : function(xml, userName, type) {
		var response = xml.response;
		if (response.status == 'success') {
			this.reloadFolderList(userName, type);
		} else {
			switch (response.error) {
			case 'DB_ERROR':
				alert('Fail, to unlock folder');
				break;
			case 'INVALID_IDENTITY':
				document.location = '/';
				break;
			}
		}
	},

	reloadFolderList : function(userName, type) {
		return;
//		var url = '';
//		var layer = '';
//		switch (type) {
//		case 'VI':
//			url = '/myFolders/videos/' + userName;
//			layer = 'my_video_folder_list';
//			break;
//		case 'SU':
//			url = '/myFolders/subtitles/' + userName;
//			layer = 'my_subtitle_folder_list';
//			break;
//		case 'DI':
//			url = '/myFolders/discussions/' + userName;
//			layer = 'my_discussion_folder_list';
//			break;
//		case 'CH':
//			url = '/myFolders/channels/' + userName;
//			layer = 'my_channel_folder_list';
//			break;
//		case 'TP':
//			url = '/myFolders/topics/' + userName;
//			layer = 'my_topic_folder_list';
//			break;
//		case 'FO':
//			url = '/myFolders/forums/' + userName;
//			layer = 'my_forum_folder_list';
//			break;
//		}
//
//		var response = new Ajax.Updater(layer, url, {
//			asynchronous : false,
//			evalScripts : true,
//			parameters : null,
//			onFailure : function(transport) {
//				alert(transport.responseText);
//			}
//		});
	},

	clickCopyTargetFolder : function(img, index) {
		var form = $('my_video_list_form');
		if (typeof form == 'undefined') {
			return;
		}
		var list = form['data[targetFolders][]'];
		if (typeof list == 'undefined') {
			return;
		}

		var checkBox = list;
		if (typeof list.length != 'undefined') {
			checkBox = list[index];
		}
		if (checkBox.checked) {
			checkBox.checked = false;
			img.src = '/common/checkbox_wh.gif';
		} else {
			checkBox.checked = true;
			img.src = '/common/checkbox_ch.gif';
		}
	},

	clickScrapTargetFolder : function(img, index) {
		var form = $('my_video_list_form');
		if (typeof form == 'undefined') {
			return;
		}
		var list = form['data[targetFolders][]'];
		if (typeof list == 'undefined') {
			return;
		}

		var checkBox = list;
		if (typeof list.length != 'undefined') {
			checkBox = list[index];
		}
		if (checkBox.checked) {
			checkBox.checked = false;
			img.src = '/common/checkbox_wh.gif';
		} else {
			checkBox.checked = true;
			img.src = '/common/checkbox_ch.gif';
		}
	},
	moveUp : function() {
	},
	moveDown : function() {
	}
};

ViiKii.My.discussions = {
	category : 'Q',
	user_name : null,
	view_page : 1,
	folder_id : 0,
	_selectedItems : [],
	_isSelectedAll : false,

	/* Lists */
	open : function(user_name, category) {
		this.category = category;
		this.user_name = user_name;
		this.view_page = 1;
		this.folder_id = 0;
		this.list();
	},

	openFolder: function(user_name, folderId, depth) {
		if (1 == depth && $("subfolders_" + folderId) && ! $("subfolders_" + folderId).innerHTML.trim().empty()) {
			if ($("subfolders_" + folderId).visible()) {
				$("my_folder_" + folderId).setStyle({background : 'rgb(128, 128, 128) url(http://vkcommon.viikii.net/bullet003_ss_left.gif) no-repeat 191px center'});
			} else {
				$("my_folder_" + folderId).setStyle({background : 'rgb(128, 128, 128) url(http://vkcommon.viikii.net/bullet003_ss_down.gif) no-repeat 188px center'});
			}
			$("subfolders_" + folderId).toggle();
		}
		
		this.category = 'folder';
		this.user_name = user_name;
		this.view_page = 1;
		this.folder_id = folderId;
		this.list();
	},

	reload : function() {
		ViiKii.My.Folder.reloadFolderList(this.user_name, 'DI');
		this.view_page = 1;
		this.list(1);
	},

	list : function(flush) {
		var url = '/myDiscussions/open/' + [ this.category, this.user_name,
				this.view_page, this.folder_id ].join('/');
		if ("undefined" != typeof flush) {
			url += '/1';
		}
		var respons = new Ajax.Updater('my_viikii_content', url, {
			asynchronous : false,
			evalScripts : true,
			parameter : null,
			onFailure : this.onError
		});
	},

	rate : function(thumb, id, cat) { /* successful */
		if (!this.islogin()) {
			return;
		}
		container = cat.toLowerCase() + '_rate_' + id;
		var response = new Ajax.Updater(container, '/boards/thumb/' + cat + '/'
				+ id + '/' + thumb, {
			evalScripts : true
		});
	},

	post : function(video_id, id, cat, type, lang, subtitle_id) {
		if (!this.islogin()) {
			return;
		}
		subtitle_id = (subtitle_id == '') ? 0 : subtitle_id;
		var params = [ video_id, id, cat, type, lang, subtitle_id,
				this.view_page ].join('/');
		var response = new Ajax.Updater('postbox_' + id,
				'/myDiscussions/postbox/' + params, {
					evalScripts : true
				});
		Element.setStyle($('postbox_' + id), {
			display : 'block'
		});
	},

	post_cancel : function(id) {
		$('postbox_' + id).innerHTML = '';
		Element.setStyle($('postbox_' + id), {
			display : 'none'
		});
	},

	add : function(frm, rid, type) {
		var notWhiteSpace = new RegExp(/[^\s]/);
		var quotation = new RegExp(/\'/g);
		var backSlash = new RegExp(/\\/g);
		var urlLink = new RegExp(
				/(http|https|ftp|telnet|news):\/\/([a-z0-9_\-]+\.[][a-zA-Z0-9:;&#@=_~%\?\/\.\,\+\-]+)/g);

		if (type != 'T') {
			if (!notWhiteSpace.test(frm['data[content]'].value)) {
				alert('Type the comment please!!');
				return;
			}
			if (backSlash.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value
						.replace(backSlash, "\\\\");
			}
			if (quotation.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value
						.replace(quotation, "\\\'");
			}
			if (urlLink.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value
						.replace(urlLink,
								"<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>");
			}
		} else {
			if (!notWhiteSpace.test(frm['data[translate]'].value)) {
				alert('Type the comment please!!');
				return;
			}
			if (backSlash.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value
						.replace(backSlash, "\\\\");
			}
			if (quotation.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value
						.replace(quotation, "\\\'");
			}
			if (urlLink.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value
						.replace(urlLink,
								"<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>");
			}
		}

		if (typeof type != 'undefined') {
			frm['data[content_type]'].value = type.toUpperCase();
		}
		var url = '/boards/add/' + (typeof rid == 'undefined' ? '' : rid);
		var param = frm.serialize();
		var response = new Ajax.Request(url, {
			asynchronous : true,
			parameters : param,
			onSuccess : this.onWrite,
			onFailure : this.onError
		});
		this.post_cancel(rid);
	},

	showPost : function(id, cat, item) {
		var paras = $A($$('div._post' + id));
		paras.each( function(ele) {
			Element.setStyle(ele, {
				display : 'none'
			});
		});
		switch (cat) {
		case 'O':
			Element.setStyle($('original_' + id), {
				display : 'block'
			});
			break;
		case 'T':
			Element.setStyle($('translate_' + id + item), {
				display : 'block'
			});
			break;
		}
	},

	inappropriate : function(ele, id, type) {
		if (!this.islogin()) {
			return;
		}
		var position = Position.positionedOffset(ele);
		ViiKii.Inappro.init('C', id, position, type);
	},

	deleteMessage : function(ele, id, type, depth) {
		if (!this.islogin()) {
			return;
		}
		var position = Position.positionedOffset(ele);

		var str = '<div id="c_msg" style="">'
				+ '	<div style="width:300px; height:15px;"><img src="/common/close.gif" style="cursor:pointer;" border="0" align="right" onclick="ViiKii.Board.deleteCancel();"></div>'
				+ '	<div style="width:280px; height:15px; padding-left:20px; text-align:left;">Do you really want to delete this message?</div>'
				+ '	<div style="width:280px; height:15px;"></div>'
				+ '	<div style="width:300px; height:30px;">'
				+ '		<div style="float:left;height:30px;width:140px;margin:0 12 0 0;text-align:center;"><a href="javascript:ViiKii.My.discussions.deleteYes('
				+ id
				+ ', \''
				+ type
				+ '\', '
				+ depth
				+ ');">yes</a></div>'
				+ '		<div style="float:left;height:30px;width:140px;text-align:left;"><a href="javascript:ViiKii.My.discussions.deleteCancel();">cancel</a></div>'
				+ '	</div>' + '</div>' + '';

		$('del_msg').innerHTML = str;
		Element.setStyle($('del_msg'), {
			left : position[0] - 300 + 'px',
			top : position[1] + 'px',
			border : '1px solid gray',
			display : 'block'
		});
	},

	deleteYes : function(rid, type, depth) {
		if (!this.islogin()) {
			return;
		}
		var param = 'data[category]=C&data[page]=' + this.view_page
				+ '&data[video_id]=' + this.video_id;
		var url = '/boards/delete/' + (typeof rid == 'undefined' ? '' : rid)
				+ '/' + type;
		var response = new Ajax.Request(url, {
			asynchronous : false,
			parameters : param,
			onFailure : this.onError
		});
		this.deleteCancel();
		this.reload();
	},

	deleteCancel : function() {
		Element.setStyle($('del_msg'), {
			display : 'none'
		});
	},

	onError : function(trasnport) {
		alert(transport.responseText);
		ViiKii.My.discussions.reload();
	},

	onWrite : function(trasnport) {
		Element.setStyle($('write_wrap'), {
			display : 'none'
		});
		ViiKii.My.discussions.reload();
	},

	onDelete : function(transport) {
		ViiKii.My.discussions.reload();
	},
	/* Lists */

	/* Items Process */
	_isChecked : function(idx) {
		return -1 != idx;
	},

	_selectAllItems : function(ids, checked) {
		var ico = (checked) ? '/common/checkbox_ch.gif'
				: '/common/checkbox_wh.gif';
		this._isSelectedAll = checked;
		if (checked) {
			this._selectedItems = ids;
		} else {
			this._selectedItems.clear();
		}
		$$('img.chkimg').each( function(e) {
			e.src = ico;
		});
		$('my_discussion_chkbox_all').src = ico;
	},

	check : function(id) {
		var idx = this._selectedItems.indexOf(id);
		if (this._isChecked(idx)) {
			this._selectedItems.splice(idx, 1);
			$('my_discussion_chkbox_' + id).src = '/common/checkbox_wh.gif';
		} else {
			this._selectedItems.push(id);
			$('my_discussion_chkbox_' + id).src = '/common/checkbox_ch.gif';
		}
	},

	checkAll : function(ids) {
		if (ids.length > 0) {
			var checked = (this._isSelectedAll) ? false : true;
			this._selectAllItems(ids, checked);
		}
	},

	copyto : function(user_name) {
		if (!this.islogin()) {
			return;
		}
		if (this._selectedItems.length <= 0) {
			alert('Nothing was selected.');
			return;
		}
		var params = $H( {
			'user_name' : user_name,
			'items' : this._selectedItems.join(',')
		}).toQueryString();

		var response = new Ajax.Updater('target_list',
				'/myDiscussions/copyto/' + user_name, {
					asynchronous : false,
					evalScripts : true,
					parameters : params,
					onFailure : function(transport) {
						alert(transport.responseText);
					}
				});
		var positions = Position.positionedOffset($('copyto_btn'));
		$('target_list').setStyle( {
			display : 'block',
			left : (positions[0] - 234) + 'px',
			top : positions[1] + 'px'
		});
	},

	unlink : function() {
		if (this._selectedItems.length <= 0) {
			alert('Nothing was selected.');
			return;
		}
		var params = $H( {
			'user_name' : this.user_name,
			'items' : this._selectedItems.join(','),
			'category' : this.category,
			'folder_id' : this.folder_id
		}).toQueryString();

		var responseXml = new Ajax.RequestXML('/myDiscussions/unlink', {
			asynchronous : false,
			evalScripts : true,
			parameters : params,
			onFailure : function(transport) {
				alert(transport.responseText);
			}
		});
		this.proc_complete(this.user_name, responseXml.responseValue);
	},

	moveto : function() {

	},

	proc_complete : function(user_name, xml) {
		var response = xml.response;
		// $('target_list').style.display='none';
	if (response.status == 'success') {
		this.reload();
		if (response.action == 'copy2folder') {
			if (this.user_name == user_name) {
				alert('clipped successfully.');
			} else {
				if (confirm('Scrapped successfully.\nDo you want to check out your "My ViiKii" now?')) {
					document.location.href = '/my/page/' + user_name;
				}
			}
		} else if (response.action == 'unlink') {
			alert('unlinked successfully.');
		}
	} else {
		//alert(response.error);
		switch (response.error) {
		case 'INVALID_IDENTITY':
			document.location = '/';
			break;
		case 'DB_ERROR':
			alert('Fail, to unlink discussion');
			break;
		case 'NOT_EMPTY_CONTENTS':
			alert('This discussion cannot be deleted because other users already contributed to this discussion');
			break;
		case 'EXIST_OWNS_DISCUSSION':
			alert('You cannot unclip your own discussion.');
			this.reload();
			break;
		}
	}
},
/* Items Process */

/* Common */
govideo : function(video_id) {
	if (!isNaN(video_id)) {
		document.location.href = "/videos/watch/" + video_id;
	} else {
		alert('Invalid Access!')
	}
},

gopage : function(page) {
	if (!isNaN(page)) {
		this.view_page = page;
		this.list();
	} else {
		alert('Invalid Access!')
	}
},

jumpto : function(video_id, pos) {
	//alert([video_id, pos].join(','));
	this.govideo(video_id);
	return;

},

anchor : function(id) {
	location.href = '#a' + id;
},

islogin : function() {
	if (ViiKii.Util.getDomainCookie('username') !== null) {
		return true;
	} else {
		ViiKii.Login.popUp();
		return false;
	}
},

/* used from My.page */
isOpenCopyTargetList : function() {
	var ret = false;
	if ($('target_list')) {
		ret = ($('target_list').getStyle('display') == 'block') ? true : false;
	}
	return ret;
},

closeCopyTargetList : function() {
	if ($('target_list')) {
		$('target_list').style.display = 'none';
	}
},

deleteAll : function(userName) {
	new Ajax.Request('/my_discussions/delete_all_discs/' + userName, {
		onSuccess : this.onDeleteAll.bind(this)
	});
},

onDeleteAll : function(transport, response) {
	//alert(transport.responseText);
	if (response.result == 'SUCCESS') {
		alert('Deleted successfully!');
		document.location.reload();
		return;
	}
	switch (response.error) {
	case 'NOT_ADMIN':
		alert('You are not an administrator');
		break;
	}
}
/* Common */
};

ViiKii.My.videos = {
	_userName : '',
	_category : '',
	_folderId : 0,
	_pageNo : 1,
	_selectedVideos : [],
	_selectedTargets : [],
	_isSelectedAll : false,
	_isSelectedAllTargets : false,
	_isOpenedCopyTargetList : false,

	_isChecked : function(idx) {
		return -1 != idx;
	},

	checked : function(videoId) {
		var idx = this._selectedVideos.indexOf(videoId);
		if (this._isChecked(idx)) {
			this._selectedVideos.splice(idx, 1);
			$('my_video_list_chkbox_' + videoId).src = '/common/checkbox_wh.gif';
		} else {
			this._selectedVideos.push(videoId);
			$('my_video_list_chkbox_' + videoId).src = '/common/checkbox_ch.gif';
		}
	},

	_selectAllVideos : function(videoIds) {
		this._isSelectedAll = true;
		this._selectedVideos = [];
		for ( var i = 0; i < videoIds.length; i++) {
			$('my_video_list_chkbox_' + videoIds[i]).src = '/common/checkbox_ch.gif';
			this._selectedVideos.push(videoIds[i]);
		}
		$('my_video_list_chkbox_all').src = '/common/checkbox_ch.gif';
	},

	_unSelectAllVideos : function(videoIds) {
		this._isSelectedAll = false;
		this._selectedVideos = [];
		for ( var i = 0; i < videoIds.length; i++) {
			$('my_video_list_chkbox_' + videoIds[i]).src = '/common/checkbox_wh.gif';
		}
		$('my_video_list_chkbox_all').src = '/common/checkbox_wh.gif';
	},

	checkedAll : function(videoIds) {
		if (videoIds.length > 0) {
			if (this._isSelectedAll) {
				$('my_video_list_chkbox_all_text').innerHTML = "Select All";
				this._unSelectAllVideos(videoIds);
			} else {
				$('my_video_list_chkbox_all_text').innerHTML = "Unselect All";
				this._selectAllVideos(videoIds);
			}
		}
	},

	unlink : function(userName) {
		if (this._selectedVideos.length <= 0) {
			alert('Nothing was selected.');
			return;
		}

		var params = $H( {
			'user_name' : userName,
			'videos' : this._selectedVideos.join(','),
			'category' : this._category,
			'folderId' : this._folderId
		}).toQueryString();

		var responseXml = new Ajax.RequestXML('/myVideos/unlink', {
			asynchronous : false,
			evalScripts : true,
			parameters : params,
			onFailure : function(transport) {
				alert(transport.responseText);
			}
		});
		this._onUnlinkComplete(userName, responseXml.responseValue);
	},

	_onUnlinkComplete : function(userName, xml) {
		var response = xml.response;
		if (response.status == 'success') {
			ViiKii.My.Folder.reloadFolderList(userName, 'VI');
			this._reload();
		} else {
			switch (response.error) {
			case 'INVALID_IDENTITY':
				document.location = '/';
				break;
			case 'DB_ERROR':
				alert('Fail, to unlink video');
				break;
			case 'EXIST_OWNS_VIDEO':
				alert('You cannot unclip your own video.');
				this._reload();
				ViiKii.My.Folder.reloadFolderList(userName, 'VI');
				break;
			}
		}
	},

	remove : function(videoId, userName) {
		if (confirm('Do you really want to delete this video?')) {
			var responseXml = new Ajax.RequestXML(
					'/myVideos/remove/' + videoId, {
						asynchronous : false,
						method : 'post',
						parameters : null,
						onFailure : function(transport) {
							alert(transport.responesText);
						}
					});
			this._onRemoved(responseXml.responseValue, userName);
		}
	},

	_onRemoved : function(xml, userName) {
		var response = xml.response;
		if (response.status == 'success') {
			ViiKii.My.Folder.reloadFolderList(userName, 'VI');
			this._reload();
		} else {
			switch (response.error) {
			case 'INVALID_IDENTITY':
				document.location = '/';
				break;
			case 'NOT_EMPTY_CONTENTS':
				alert('This video cannot be deleted because other users already contributed to this video');
				break;
			}
		}
	},

	toggleLock : function(userName, videoId) {
		var url = '/myVideos/toggleLock/' + userName + '/' + videoId;
		var res = new Ajax.RequestXML(url, {
			asynchronous : false,
			method : 'post',
			parameters : null,
			onFailure : function(res) {
				alert(res.responseText);
			}
		});

		this._onCompleteToggleLock(videoId, res.responseValue);
	},

	_onCompleteToggleLock : function(videoId, xml) {
		var res = xml.response;
		var imgs = [ '/common/private_open.gif', '/common/private.gif' ];
		if ('success' == res.status) {
			$('my_video_lock_' + videoId).src = imgs[res.success];
		} else {
			switch (res.error) {
			case 'INVALID_IDENTITY':
				document.location = '/';
				break;
			default:
				alert('Fail to lock/unlock video');
				break;
			}
		}
	},

	openAll : function(userName) {
		this.paging(userName, 1, 'AL', 0);
	},

	openMine : function(userName) {
		this.paging(userName, 1, 'MY', 0);
	},

	openFavorites : function(userName) {
		this.paging(userName, 1, 'FA', 0);
	},

	openFolder: function(userName, folderId, depth) {
		if (1 == depth && $("subfolders_" + folderId) && ! $("subfolders_" + folderId).innerHTML.trim().empty()) {
			if ($("subfolders_" + folderId).visible()) {
				$("my_folder_" + folderId).setStyle({background : 'rgb(128, 128, 128) url(http://vkcommon.viikii.net/bullet003_ss_left.gif) no-repeat 191px center'});
			} else {
				$("my_folder_" + folderId).setStyle({background : 'rgb(128, 128, 128) url(http://vkcommon.viikii.net/bullet003_ss_down.gif) no-repeat 188px center'});
			}
			$("subfolders_" + folderId).toggle();
		}
		this.paging(userName, 1, 'FO', folderId);
	},

	_clearSelectedVideos : function() {
		this._isSelectedAll = false;
		this._selectedVideos = [];
	},

	_clearSelectedTargets : function() {
		this._isSelectedAllTargets = false;
		this._selectedTargets = [];
	},

	paging : function(userName, pageNo, category, folderId) {
		this._userName = userName;
		this._category = category;
		this._folderId = folderId;
		this._pageNo = pageNo;
		this._clearSelectedVideos();
		this._clearSelectedTargets();

		var url = '/myVideos/videos/' + userName + '/' + pageNo;
		url += ('' == category) ? '' : '/' + category;
		url += (0 == folderId) ? '' : '/' + folderId;
		var response = new Ajax.Updater('my_viikii_content', url, {
			asynchronous : true,
			evalScripts : true,
			parameter : null,
			onFailure : function(transport) {
				alert(transport.responseText);
			}
		});
	},

	_reload : function() {
		this.paging(this._userName, this._pageNo, this._category,
				this._folderId);
	},

	displayVideosInFolder : function(folderId) {
		var url = '/myVideos/mylist/' + ViiKii.My.username + '/1/' + folderId;
		var response = new Ajax.Updater('my-video-list', url, {
			asynchronous : false,
			evalScripts : true,
			parameter : null,
			onFailure : function(transport) {
				alert(transport.responseText);
			}
		});
	},

	checkedTarget : function(folderId) {
		var idx = this._selectedTargets.indexOf(folderId);
		if (this._isChecked(idx)) {
			this._selectedTargets.splice(idx, 1);
			$('target_folder_' + folderId).src = '/common/checkbox_wh.gif';
		} else {
			this._selectedTargets.push(folderId);
			$('target_folder_' + folderId).src = '/common/checkbox_ch.gif';
		}
	},

	_selectAllTargets : function(folderIds) {
		this._isSelectedAllTargets = true;
		this._selectedTargets = [];
		for ( var i = 0; i < folderIds.length; i++) {
			$('target_folder_' + folderIds[i]).src = '/common/checkbox_ch.gif';
			this._selectedTargets.push(folderIds[i]);
		}
	},

	_unSelectAllTargets : function(folderIds) {
		this._isSelectedAllTargets = false;
		this._selectedTargets = [];
		for ( var i = 0; i < folderIds.length; i++) {
			$('target_folder_' + folderIds[i]).src = '/common/checkbox_wh.gif';
		}
	},

	checkedAllTarget : function(folderIds) {
		if (folderIds.length > 0) {
			if (this._isSelectedAllTargets) {
				this._unSelectAllTargets(folderIds);
			} else {
				this._selectAllTargets(folderIds);
			}
		}
	},

	openCopyTargetList : function(event, userName) {
		Event.stop(event);
		this._clearSelectedTargets();
		if (this._selectedVideos.length <= 0) {
			alert('Nothing was selected.');
			return;
		}

		$('target_folder_list_layer').style.display = 'block';
		new Ajax.Updater(
			'target_folder_list_layer',
			'/myVideos/copyTargets/' + userName, {
				asynchronous : false,
				method : 'post',
				parameters : null,
				onFailure : function(transport) {
					alert(transport.responseText);
				}
			}
		);
		this._isOpenedCopyTargetList = true;
	},

	closeCopyTargetList : function() {
		this._clearSelectedTargets();
		$('target_folder_list_layer').innerHTML = '';
		$('target_folder_list_layer').style.display = 'none';
		this._isOpenedCopyTargetList = false;
	},

	isOpenCopyTargetList : function() {
		return this._isOpenedCopyTargetList;
	},

	copyToFolder : function(userName) {
		if (this._selectedVideos.length <= 0
				|| this._selectedTargets.length <= 0) {
			return;
		}
		var params = $H( {
			'user_name' : userName,
			'videos' : this._selectedVideos.join(','),
			'targets' : this._selectedTargets.join(',')
		}).toQueryString();
		var responseXml = new Ajax.RequestXML('/myVideos/copyToFolder', {
			asynchronous : false,
			parameters : params,
			onFailure : function(res) {
				alert(res.responseText);
			}
		});
		this.onCopyToFolderComplete(userName, responseXml.responseValue);
	},

	onCopyToFolderComplete : function(userName, xml) {
		var response = xml.response;
		if (response.status == 'success') {
			ViiKii.My.Folder.reloadFolderList(userName, 'VI');
			this.closeCopyTargetList();
			this._reload();
		} else {
			alert(response.error);
			switch (response.error) {
			case 'INVALID_IDENTITY':
				document.location = '/';
				break;
			case 'NOT_EMPTY_CONTENTS':
				alert('This video cannot be deleted because other users already contributed to this video');
				break;
			}
			this.closeCopyTargetList();
		}
	},
	merge: function() {
		if (this._selectedVideos.length <= 1) {
			return;	// 두개 이상 선택되어야 한다.
		}
		
		var params = $H({'videos':this._selectedVideos.join(',')}).toQueryString();
		new Ajax.Request("/videos_merge/confirm", {
			asynchronous : false,
			parameters : params,
			onComplete: function(transport, response) {
				if ("success" == response.result) {
					document.location = "/videos_merge/step_one";
				} else {
					alert(response.error);
					return;
				}
			}
		});
	}
};// videos

ViiKii.My.History = {
	del: function(id, username, type) {
		var params = $H({'id':id, 'username':username, 'type':type}).toQueryString();
		new Ajax.Request('/ci/index.php/user_feeds/remove', {
			parameters: params,
			asynchronous : false,
			onComplete: function(transport, response) {
				if (response.result == 'success') {
					url = '/ci/index.php/user_feeds/' + response.type + '/' + response.username + '/1'; 
					new Ajax.Updater('user_feed', url, {
							asynchronous: false,
							evalScripts: true,
							parameters: null
						}
					);
				} else {
					alert(response.error);
				}
			}
		});
	},
//	del : function(pageType, type, time, info_1, info_2, info_3, info_4,
//			userName) {
//		if (!confirm('Do you really want to delete the this ' + pageType + '?')) {
//			return;
//		}
//		var ajax = new Ajax.RequestXML('/my/delete_history/' + type + '/'
//				+ time + '/' + info_1 + '/' + info_2 + '/' + info_3 + '/'
//				+ info_4, {
//			method : 'get',
//			asynchronous : false
//		});
//		this.onDeleteHistory(ajax, pageType, userName);
//	},
	onDeleteHistory : function(ajax, pageType, userName) {
		var response = ajax.responseValue.response;
		if (response.result == 'SUCCESS') {
			this.showList(1, pageType, userName);
			return;
		}
		switch (response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'DB_ERROR':
			alert('Fail to delete the ' + pageType + '! Please try again.');
			break;
		}
	},
	showList : function(page, type, userName) {
		var requestUrl = "/my/history/" + userName + "/" + type + "/" + page;
		var response = new Ajax.Updater("my_viikii_history_list", requestUrl, {
			asynchronous : true,
			method : "get"
		});
	},
	openSetting : function(userName) {
		document.location = '/my/config/' + userName;
	}
};

ViiKii.My.channels = {
	_userName : null,
	_type : null,
	_pageNo : 1,
	init : function() {
	},

	_openChannels : function(userName, type, pageNo) {
		this._userName = userName;
		this._type = type;
		this._pageNo = pageNo;
		var res = new Ajax.Updater('my_viikii_content', '/myChannels/' + type
				+ '/' + userName + '/' + pageNo, {
			asynchronous : false,
			evalScripts : true,
			parameters : null,
			onFailure : function(transport) {
				alert(transport.responseText);
			}
		});
	},

	openAllChannels : function(userName) {
		this._openChannels(userName, 'all', 1);
	},

	openMyChannels : function(userName) {
		this._openChannels(userName, 'my', 1);
	},

	openSubscribedChannels : function(userName) {
		this._openChannels(userName, 'subscribed', 1);
	},

	paging : function(pageNo, userName, type) {
		this._openChannels(userName, type, pageNo);
	},
	del : function(userName, channelId) {
		if (!confirm('Are you sure to delete this channel?\nOnce you delete it you cannot restore the channel and the data belonged to it.')) {
			return;
		}
		var ajax = new Ajax.RequestXML('/channels/delete_channel/' + channelId,
				{
					method : 'get',
					asynchronous : false
				});
		this.onSuccessDelete(ajax, userName);
	},
	onSuccessDelete : function(ajax, userName) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if (response.result == 'SUCCESS') {
			alert("Success to delete the channel");
			this._reload();
			ViiKii.My.Folder.reloadFolderList(userName, 'CH');
			return;
		}
		switch (response.error) {
		case 'INVALID_CHANNEL':
			alert("The channel is already deleted");
			return;
		case 'NOT_OWNER':
			alert("You are not the owner of the channel");
			return;
		case 'HAS_MIRROR':
			alert("You cannot delete a channel that has a  mirrored channel.");
			return;
		case 'DB_ERROR':
			alert("Fail to delete a channel! Please try again.");
			return;
		case 'UNABLE_TO_DELETE':
			alert("You can't delete the channel.\n\nIf you want to transfer the manager's rights to another user, contact viikiihelper.");
			return;
		}
	},
	_reload : function() {
		this._openChannels(this._userName, this._type, this._pageNo);
	}
};

ViiKii.My.Topic = {
	_folderListOpened : false,
	_ownerName : '',
	_folderListOpened : false,
	toggleFolderList : function(userName) {
		this._ownerName = userName;
		if (this._folderListOpened) {
			this.closeFolderList();
		} else {
			this.openFolderList();
		}
	},
	openFolderList : function() {
		if (this._ownerName == ViiKii.Util.getDomainCookie('username')) {
			$('new_topic_folder_menu').style.display = 'block';
		}
		$('my_topic_folder_bullet').src = '/common/bullet001_s.gif';
		$('my_topic_folder_list_popup').style.display = 'block';
		this._folderListOpened = true;
	},
	closeFolderList : function() {
		if (this._ownerName == ViiKii.Util.getDomainCookie('username')) {
			$('new_topic_folder_menu').style.display = 'none';
		}
		$('my_topic_folder_bullet').src = '/common/bullet001_s_rotate.gif';
		$('my_topic_folder_list_popup').style.display = 'none';
		this._folderListOpened = false;
	},
	displayFolderList : function() {
		if (this._folderListOpened) {
			this.openFolderList();
		} else {
			this.closeFolderList();
		}
	}
};

ViiKii.My.Topic.TopicList = {
	objectId : 'ViiKii.My.Topic.TopicList',
	isSelectAll : true,
	topics : {},
	init : function() {
		this.topics = {};
		this.isSelectAll = true;
	},
	addTopic : function(topicId) {
		this.topics[topicId] = false;
	},
	check : function(topicId) {
		this.changeCheck(topicId, !this.topics[topicId]);
	},
	checkAll : function() {
		for ( var topic in this.topics) {
			if (this.topics[topic] != this.isSelectAll) {
				this.changeCheck(topic, this.isSelectAll);
			}
		}
		this.changeCheckAll(!this.isSelectAll);
	},
	changeCheckAll : function(checked) {
		this.isSelectAll = checked;
		this.changeCheckImage(this.objectId + ".checkAll", !checked);
		if (checked) {
			$(this.objectId + ".checkAllText").innerHTML = "Select All";
		} else {
			$(this.objectId + ".checkAllText").innerHTML = "Unselect All";
		}
	},
	changeCheck : function(topicId, checked) {
		this.topics[topicId] = checked;
		this.changeCheckImage('topic_checkbox_' + topicId, checked);
	},
	changeCheckImage : function(id, checked) {
		var src = "";
		if (checked) {
			src = "/common/checkbox_ch.gif";
		} else {
			src = "/common/checkbox_wh.gif";
		}
		$(id).src = src;
	},
	getTopics : function() {
		var result = [];
		for ( var topic in this.topics) {
			if (this.topics[topic]) {
				result.push(topic);
			}
		}
		return result;
	},
	remove : function() {
		if (!this.topicSelected()) {
			alert("Select available topics first.");
			return;
		}
		if (!confirm('Do you really want to remove the topics from this folder?')) {
			return;
		}
		var params = $H( {
			'topics' : this.getTopics().join(",")
		}).toQueryString();
		new Ajax.Request('/my_topics/remove/'
				+ ViiKii.Util.get(this, 'ownerName') + '/'
				+ ViiKii.Util.get(this, 'folder'), {
			parameters : params,
			onSuccess : this.onRemove.bind(this)
		});
	},
	onRemove : function(transport, response) {
		//alert(transport.responseText);
		if (response.result == 'SUCCESS') {
			alert('Successfully removed.');
			this.loadPage(1);
			ViiKii.My.Folder.reloadFolderList(ViiKii.Util
					.get(this, 'ownerName'), 'TP');
			return;
		}
		switch (response.error) {
		case 'NOT_OWNER':
			alert('You are not the owner of this page');
			break;
		case 'EMPTY_TOPICS':
			alert('Select available topics first.');
			break;
		}
	},
	topicSelected : function() {
		return this.getTopics().length > 0;
	},
	display: function(type, folderId, depth) {
		if (1 == depth && $("subfolders_" + folderId) && ! $("subfolders_" + folderId).innerHTML.trim().empty()) {
			if ($("subfolders_" + folderId).visible()) {
				$("my_folder_" + folderId).setStyle({background : 'rgb(128, 128, 128) url(http://vkcommon.viikii.net/bullet003_ss_left.gif) no-repeat 191px center'});
			} else {
				$("my_folder_" + folderId).setStyle({background : 'rgb(128, 128, 128) url(http://vkcommon.viikii.net/bullet003_ss_down.gif) no-repeat 188px center'});
			}
			$("subfolders_" + folderId).toggle();
		}
		
		if (folderId == null) {
			folderId = '0';
		}
		new Ajax.Updater('my_viikii_content', '/my_topics/topics/'
				+ ViiKii.Util.get(this, 'ownerName') + '/1/' + type + '/'
				+ folderId, {
			evalScripts : true
		})
	},
	loadPage : function(curPage) {
		ViiKii.Util.set(this, 'curPage', curPage);
		this.refresh();
	},
	refresh : function() {
		new Ajax.Updater('my_viikii_content', '/my_topics/topics/'
				+ ViiKii.Util.get(this, 'ownerName') + '/'
				+ ViiKii.Util.get(this, 'curPage') + '/'
				+ ViiKii.Util.get(this, 'type') + '/'
				+ ViiKii.Util.get(this, 'folder'), {
			evalScripts : true
		})
	}
};
ViiKii.My.Topic.TopicList.MoveToPopup = {
	objectId : 'ViiKii.My.Topic.TopicList',
	folders : {},
	open : function() {
		new Ajax.Updater('ViiKii.My.Topic.TopicList.moveTo',
				'/my_topics/move_to/' + ViiKii.Util.get(this, 'ownerName')
						+ '/' + ViiKii.Util.get(this, 'folder'), {
					method : 'get',
					evalScripts : true
				});
		Element.show('ViiKii.My.Topic.TopicList.moveTo');
	},
	close : function() {
		Element.hide('ViiKii.My.Topic.TopicList.moveTo');
	},
	init : function() {
		this.folders = {};
	},
	addFolder : function(folderId) {
		this.folders[folderId] = false;
	},
	check : function(folderId) {
		this.uncheckAll();
		this.changeCheck(folderId, !this.folders[folderId]);
	},
	uncheckAll : function() {
		for ( var folder in this.folders) {
			if (this.folders[folder]) {
				this.changeCheck(folder, false);
			}
		}
	},
	changeCheck : function(folderId, checked) {
		this.folders[folderId] = checked;
		this.changeCheckImage('folder_checkbox_' + folderId, checked);
	},
	changeCheckImage : function(id, checked) {
		var src = "";
		if (checked) {
			src = "/common/checkbox_ch.gif";
		} else {
			src = "/common/checkbox_wh.gif";
		}
		$(id).src = src;
	},
	getFolders : function() {
		var result = [];
		for ( var folder in this.folders) {
			if (this.folders[folder]) {
				result.push(folder);
			}
		}
		return result;
	},
	ok : function() {
		ViiKii.My.Topic.TopicList.getTopics.bind(ViiKii.My.Topic.TopicList);
		if (ViiKii.My.Topic.TopicList.getTopics().length == 0) {
			alert("Select available topics first.");
			return;
		}
		if (this.getFolders().length == 0) {
			alert("Select available folder first.");
			return;
		}
		var params = $H( {
			'topics' : ViiKii.My.Topic.TopicList.getTopics().join(","),
			'folder' : this.getFolders()[0]
		}).toQueryString();
		new Ajax.Request('/my_topics/move_topics_to/' + ViiKii.Util.get(this,
				'ownerName'), {
			parameters : params,
			onSuccess : this.onOk.bind(this)
		});
	},
	onOk : function(transport, response) {
		//alert(transport.responseText);
	if (response.result == 'SUCCESS') {
		alert('Topics are moved successfully!');
		this.close();
		ViiKii.My.Topic.TopicList.refresh.bind(ViiKii.My.Topic.TopicList);
		ViiKii.My.Topic.TopicList.refresh();
		ViiKii.My.Folder.reloadFolderList(ViiKii.Util.get(this, 'ownerName'),
				'TP');
		return;
	}
	switch (response.error) {
	case 'NOW_OWNER':
		alert("You are not the owner of this page");
		return;
	case 'EMPTY_TOPIC':
		alert("Select available topics first.");
		return;
	case 'EMPTY_FOLDER':
		alert("Select available folder first.");
		return;
	case 'INVALID_FOLDER':
		alert("The folder is deleted.");
		ViiKii.My.Topic.TopicList.MoveToPopup.open();
		return;
	}
}
};
ViiKii.My.Topic.TopicPage = {
	load: function(topicId) {
		new Ajax.Updater(
			'my_viikii_content',
			'/my_topics/topic/'+$('owner_name').value+'/'+topicId,
			{
				evalScripts: true
			}
		);
	}
};

ViiKii.My.inbox = {
	goPage : function(pageNo) {
		var url = '/inboxes/listing/' + ViiKii.My.username + '/' + pageNo;
		var response = new Ajax.Updater('my_viikii_content', url, {
			asynchronous : false,
			evalScripts : true,
			parameters : null,
			onFailure : function(transport) {
				alert(transport.responseText);
			}
		});
	},

	imageToggle : function(id) {
		inputId = 'shared';
		imgId = 'imgShared';
		if (typeof id != 'undefined') {
			inputId += id;
			imgId += id;
		}

		var shared = $(inputId).value;
		if (shared == '1') {
			$(imgId).src = '/common/private.gif';
			$(inputId).value = '0';
		} else {
			$(imgId).src = '/common/private_open.gif';
			$(inputId).value = '1';
		}
	},

	checkBox : function(id) {
		var checked = $('inbox_notify_' + id).value;

		if (checked == '0') {
			$('inbox_checkbox_' + id).src = '/common/checkbox_ch.gif';
			$('inbox_notify_' + id).value = 1;
		}
		if (checked == '1') {
			$('inbox_checkbox_' + id).src = '/common/checkbox_wh.gif';
			$('inbox_notify_' + id).value = 0;
		}
	},

	submit : function() {
		var notWhiteSpace = new RegExp(/[^\s]/);
		var leftBracket = new RegExp(/\</g);
		var rightBracket = new RegExp(/\>/g);

		if (notWhiteSpace.test($('inbox_content').value)
				&& $('inbox_content').value != ' Leave your message here.') {
			if (leftBracket.test($('inbox_content').value)) {
				$('inbox_content').value = $('inbox_content').value.replace(
						leftBracket, "&lt;");
			}
			if (rightBracket.test($('inbox_content').value)) {
				$('inbox_content').value = $('inbox_content').value.replace(
						rightBracket, "&gt;");
			}
			var param = 'data[Inbox][content]='
					+ encodeURIComponent($('inbox_content').value)
					+ '&data[Inbox][shared]=' + $('shared').value
					+ '&data[Inbox][owner_name]=' + $('ownername').value;
			var url = "/inboxes/add/" + this.pageNo;
			var response = new Ajax.Request(url, {
				asynchronous : true,
				parameters : param,
				onComplete : function(transport, response) {
					if ('success' == response.result) {
						new Ajax.Updater('my_viikii_content',
								'/inboxes/listing/' + response.user + '/'
										+ response.page, {
									evalScripts : true
								});
					}
				}
			});
			$('inbox_content').value = '';
		} else {
			alert('Type the text!!');
			$('inbox_content').value = '';
			$('inbox_content').focus();
		}
	},

	callback : function(transport) {
		if ($('my_viikii_content')) {
			var url = '/inboxes/listing/' + ViiKii.My.username + '/'
					+ transport.responseText;
			var response = new Ajax.Updater('my_viikii_content', url, {
				asynchronous : false,
				evalScripts : true,
				parameters : null,
				onFailure : function(transport) {
					alert(transport.responseText);
				}
			});
		} else {
			ViiKii.My.inbox.main(transport.responseText);
		}
	},

	onError : function() {
	},

	cancelCotent : function() {
		$('inbox_content').value = '';
	},

	save : function(id) {
		var checked = $('inbox_notify_' + id).value;
		var shared = $('shared' + id).value;
		var notWhiteSpace = new RegExp(/[^\s]/);
		var leftBracket = new RegExp(/\</g);
		var rightBracket = new RegExp(/\>/g);
		if (notWhiteSpace.test($('inbox_comment_' + id).value)
				&& $('inbox_comment_' + id).value != ' Leave your reply here.') {
			if (leftBracket.test($('inbox_comment_' + id).value)) {
				$('inbox_comment_' + id).value = $('inbox_comment_' + id).value
						.replace(leftBracket, "&lt;");
			}
			if (rightBracket.test($('inbox_comment_' + id).value)) {
				$('inbox_comment_' + id).value = $('inbox_comment_' + id).value
						.replace(rightBracket, "&gt;");
			}
			var params = $H( {
				'comment' : $('inbox_comment_' + id).value,
				'shared' : $('shared' + id).value,
				'owner_name' : $('ownername').value,
				'id' : id
			}).toQueryString();
			var response = new Ajax.Request('/inboxes/addcomment/' + checked
					+ '/' + this.pageNo, {
				asynchronous : true,
				parameters : params,
				onComplete : function(transport, response) {
					if ('success' == response.result) {
						new Ajax.Updater('my_viikii_content',
								'/inboxes/listing/' + response.user + '/'
										+ response.page, {
									evalScripts : true
								});
					}
				}
			});
			$('inbox_comment_' + id).value = '';
		} else {
			alert('Type the text!!');
			$('inbox_comment_' + id).value = '';
			$('inbox_comment_' + id).focus();
		}
	},

	cancelComment : function(id) {
		$('inbox_comment_' + id).value = '';
	},

	deleteItem : function(cat, commentid) {
		if (this.deleteId == null) {
			return;
		}

		var checked = '0';
		if (cat == 'R' && parseInt(commentid, 10) != -1) {
			checked = $('inbox_notify_r').value;
		}
		var param = 'data[Inbox][id]=' + this.deleteId
				+ '&data[Inbox][owner_name]=' + ViiKii.My.username
				+ '&data[Inbox][cat]=' + cat + '&data[Inbox][comment_id]='
				+ commentid;
		this.deleteId = null;
		var url = "/inboxes/delete/" + checked + '/' + this.pageNo;
		var response = new Ajax.Request(url, {
			asynchronous : true,
			parameters : param,
			onSuccess : this.callback,
			onFailure : this.onError
		});
	},

	updateItem : function(id, name, shared) {
		var param = 'data[Inbox][id]=' + id + '&data[Inbox][owner_name]='
				+ name + '&data[Inbox][shared]=' + shared;
		var url = "/inboxes/update/" + this.pageNo;
		var response = new Ajax.Request(url, {
			asynchronous : true,
			parameters : param,
			onSuccess : this.callback,
			onFailure : this.onError
		});
	},

	createLayer : function(id, cat, commentid, username) {
		this.deleteId = id;
		this.category = cat;
		this.username = username;

		var str = '	<div style="height:18px;"><img src="/common/close.gif" style="cursor:pointer;" border="0" align="right" onclick="ViiKii.My.inbox.closeLayer();"></div>\n' + '	<div style="height:18px; margin-left:15px;">Do you really want to delete this message?</div>\n';
		if (cat == 'R' && parseInt(commentid, 10) != -1) {
			str += '	<div style="height:18px; margin-left:15px;">\n'
					+ '		<input type="hidden" id="inbox_notify_r" name="inapp" value="0">'
					+ '		<img id="inbox_checkbox_r" src="/common/checkbox_wh.gif" style="cursor:pointer; padding-right:5px;" align="absmiddle" onclick="ViiKii.My.inbox.checkBox(\'r\')">'
					+ '		<label> I want to delete this message on ' + username
					+ '\'s Inbox too.</label>' + '	</div>\n';
		}

		str += '	<div style="height:18px; margin-left:15px;"></div>\n'
				+ '	<div style="height:18px;">\n'
				+ '		<div style="float:left; height:18px;width:140px;margin:0 12 0 0;text-align:center;"><a href="javascript:ViiKii.My.inbox.yesLayer(\''
				+ cat
				+ '\', '
				+ commentid
				+ ');">yes</a></div>\n'
				+ '		<div style="float:left; height:18px;width:140px;text-align:left;"><a href="javascript:ViiKii.My.inbox.closeLayer();">cancel</a></div>\n'
				+ '	</div>\n'
				+ '	<div style="height:18px; margin-left:15px;"></div>\n' + '';

		$('inbox_delmsg').innerHTML = str;

		if ($('my_viikii_content')) { // in myviikii page
			var position = Position.positionedOffset($('inbox_list' + id));
			var xpos = (position[0] + 140) + 'px';
			var ypos = (position[1] + 20) + 'px';
			Element.setStyle($('inbox_delmsg'), {
				left : xpos,
				top : ypos,
				border : '1px solid #888888',
				display : 'block'
			});
		} else {
			Element.setStyle($('inbox_delmsg'), {
				left : '150px',
				top : '150px',
				border : '1px solid #888888',
				display : 'block'
			});
		}
	},

	closeLayer : function() {
		Element.setStyle($('inbox_delmsg'), {
			display : 'none'
		});
	},

	yesLayer : function(cat, commentid) {
		this.closeLayer();
		this.deleteItem(cat, commentid);
	}
};// ViiKii.My.inbox

ViiKii.My.Editor = {};
ViiKii.My.Editor.Introduction = {
	open : function(userName, uploadUrl) {
		this.showEditor(uploadUrl);
		Element.show('ViiKii.My.Editor.Introduction.editor');
		Element.hide('ViiKii.My.Editor.Introduction.boundary');
	},
	save : function(userName) {
		var params = $H( {
			'introduction' : this.getContent()
		}).toQueryString();
		var ajax = new Ajax.RequestXML('/my/edit_introduction/' + userName, {
			asynchronous : false,
			parameters : params
		});
		this.onSuccessSave(ajax, userName);
	},
	onSuccessSave : function(ajax, userName) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if (response.result == 'SUCCESS') {
			this.closeEditor();
			this.update(userName);
			return;
		}
		switch (response.error) {
		case 'INVALID_USER_NAME':
			alert("Invalid user name.");
			document.location = '/';
			return;
		case 'NOT_OWNER':
			alert("You are not the owner of this page.");
			this.update(userName);
			return;
		case 'EMPTY_INPUT':
			alert("Insert available content first!");
			return;
		case 'DB_ERROR':
			alert("Fail to edit page banner. Please try again!");
			return;
		case 'OUT_OF_LENGTH':
			alert("The content is out of length.");
			return;
		}
	},
	update : function(userName) {
		new Ajax.Updater('ViiKii.My.introduction',
				'/my/introduction/' + userName, {
					method : 'get'
				});
	},
	discard : function() {
		this.closeEditor();
		Element.hide('ViiKii.My.Editor.Introduction.editor');
		Element.show('ViiKii.My.Editor.Introduction.boundary');
	},
	showEditor : function(uploadUrl) {
		var uploadUrl = uploadUrl + '?type=MY_INTRODUCTION&user_name='
				+ ViiKii.Util.getDomainCookie('username');
		ViiKii.Editor.openEditor('ViiKii.My.Editor.Introduction.editorContent',
				this.getContentHeight(), '', uploadUrl);
		var content = $('ViiKii.My.Editor.Introduction.content').innerHTML;
		ViiKii.Editor.setContent(content);
	},
	getContent : function() {
		return ViiKii.Editor.getEditorContent();
	},
	getContentHeight : function() {
		var contentHeight = Element
				.getHeight('ViiKii.My.Editor.Introduction.content');
		if (contentHeight < 36) {
			return 36;
		}
		return contentHeight;
	},
	closeEditor : function() {
		ViiKii.Editor.closeEditor();
	}
};
ViiKii.My.Embeds = {
	objectId : 'ViiKii.My.Embeds',
	click : function(embedId) {
		//alert("click embed: "+embedId);
		new Ajax.Updater('my_viikii_content',
				'/my_embeds/show_embed/' + embedId, {
					evalScripts : true,
					method : 'get'
				});
	},
	edit : function(embedId) {
		//alert("edit embed: "+embedId);
		new Ajax.Updater('my_viikii_content',
				'/my_embeds/edit_embed/' + embedId, {
					evalScripts : true,
					method : 'get'
				});
	},
	del : function(embedId) {
		new Ajax.Request('/my_embeds/delete_embed/' + embedId, {
			onComplete : this.onDel.bind(this)
		});
	},
	onDel : function(transport, response) {
		//alert(transport.responseText);
		if (response.result == 'SUCCESS') {
			alert('Deleted successfully.');
			document.location = '/my/page/' + response.user_name;
			return;
		}
		switch (response.error) {
		case 'NOT_OWNER':
			alert('You are not the owner of this page.');
			return;
		}
	},
	changeOrder : function(embedId, type) {
		//alert("change order: "+embedId+" "+type);
		new Ajax.Request('/my_embeds/change_order/' + embedId + '/' + type, {
			onComplete : this.onChangeOrder.bind(this)
		});
	},
	onChangeOrder : function(transport, response) {
		//alert(transport.responseText);
		if (response.result == 'SUCCESS') {
			this.refresh();
			return;
		}
		switch (response.error) {
		case 'NOT_OWNER':
			alert('You are not the owner of this page.');
			return;
		case 'INVALID_EMBED':
			alert('The embed stuff is deleted.');
			this.refresh();
			return;
		case 'DB_ERROR':
			alert('Fail to change orders. Please try again.');
			return;
		}
	},
	makeNew : function() {
		new Ajax.Updater('my_viikii_content',
				'/my_embeds/new_embed/' + ViiKii.Util.get(this, 'userName'), {
					evalScripts : true
				});
	},
	refresh : function() {
		new Ajax.Updater('ViiKii.My.Embeds.layer', '/my/embeds/' + ViiKii.Util
				.get(this, 'userName'), {
			evalScripts : true
		});
	}
};

ViiKii.My.Embeds.New = {
	objectId : 'ViiKii.My.Embeds.New',
	save : function() {
		var title = $('ViiKii.My.Embeds.New.title').value.trim();
		var code = $('ViiKii.My.Embeds.New.code').value.trim();
		if (title == '') {
			alert('Insert available title first.');
			return;
		}
		if (code == '') {
			alert('Insert available embed code first.');
			return;
		}
		var params = $H( {
			'title' : title,
			'code' : code
		}).toQueryString();
		new Ajax.Request('/my_embeds/save_new_embed/' + ViiKii.Util.get(this,
				'userName'), {
			parameters : params,
			onComplete : this.onSave.bind(this)
		});
	},
	onSave : function(trasnport, response) {
		//alert(trasnport.responseText);
	if (response.result == 'SUCCESS') {
		alert('Added successfully.');
		ViiKii.My.Embeds.refresh.bind(ViiKii.My.Embeds);
		ViiKii.My.Embeds.refresh();
		ViiKii.My.Embeds.click(response.embed_id);
		return;
	}
	switch (response.error) {
	case 'NOT_LOG_IN':
		ViiKii.Login.popUp();
		break;
	case 'NOT_OWNER':
		alert('You are not the owner of this page.');
		document.location = '/my/page/' + ViiKii.Util.get(this, 'userName');
		break;
	case 'EMPTY_TITLE':
		alert('Insert available title first.');
		break;
	case 'EMPTY_TITLE':
		alert('Insert available embed code first.');
		break;
	case 'DB_ERROR':
		alert('Fail to add embed stuff. Please try again.');
		break;
	}
},
cancel : function() {
	document.location = '/my/page/' + ViiKii.Util.get(this, 'userName');
}
};
ViiKii.My.Embeds.Edit = {
	objectId : 'ViiKii.My.Embeds.Edit',
	save : function() {
		var title = $('ViiKii.My.Embeds.Edit.title').value.trim();
		var code = $('ViiKii.My.Embeds.Edit.code').value.trim();
		if (title == '') {
			alert('Insert available title first.');
			return;
		}
		if (code == '') {
			alert('Insert available embed code first.');
			return;
		}
		var params = $H( {
			'title' : title,
			'code' : code
		}).toQueryString();
		new Ajax.Request('/my_embeds/save_edit_embed/' + ViiKii.Util.get(this,
				'embedId'), {
			parameters : params,
			onComplete : this.onSave.bind(this)
		});
	},
	onSave : function(transport, response) {
		//alert(transport.responseText);
	if (response.result == 'SUCCESS') {
		alert('Edited successfully.');
		ViiKii.My.Embeds.refresh.bind(ViiKii.My.Embeds);
		ViiKii.My.Embeds.refresh();
		ViiKii.My.Embeds.click(ViiKii.Util.get(this, 'embedId'));
		return;
	}
	switch (response.error) {
	case 'INVALID_EMBED':
		alert("This embed is deleted.");
		document.location = '/my/page/' + ViiKii.Util.get(this, 'userName');
		return;
	case 'NOT_OWNER':
		alert('You are not the owner of this page.');
		document.location = '/my/page/' + ViiKii.Util.get(this, 'userName');
		return;
	case 'EMPTY_TITLE':
		alert('Insert available title first.');
		return;
	case 'EMPTY_TITLE':
		alert('Insert available embed code first.');
		return;
	}
},
cancel : function() {
	document.location = '/my/page/' + ViiKii.Util.get(this, 'userName');
}
};
var message = {
	show : function(msg) {
		$('Message').innerHTML = msg + this.defaultValue();
		$('Message').style.display = 'block';
	},
	hide : function() {
		$('Message').innerHTML = '';
		$('Message').style.display = 'none';
	},
	defaultValue : function() {
		return '<p><input type="button" style="width:100px" onclick="message.hide();" value="OK"></p>';
	}
};

ViiKii.Languages = {

	_observers : [],
	interestedLanguages : [],
	uiLanguage : 'en',
	availableUILanguages : [],

	init : function(e) {
	},

	attach : function(observer) {
		for (i = 0; i < this._observers.length; i++) {
			if (this._observers[i] == observer) {
				return;
			}
		}

		if (Object.isObject(observer) || Object.isFunction(observer)) {
			this._observers.push(observer);
		} else {
			alert('Error-Observer must implete update method:' + observer);
		}
	},

	detach : function(observer) {
		for (i = 0; i < this._observers.length; i++) {
			if (this._observers[i] == observer) {
				this._observers.splice(i, 1);
				return;
			}
		}
	},

	changed : function() {
		for ( var i = 0; i < this._observers.length; i++) {
			if (Object.isObject(this._observers[i])) {
				this._observers[i].update();
			} else {
				this._observers[i]();
			}
		}
	},
	toggle : function(language, isOn) {
		var userLanguages = ViiKii.Languages.getInterestedLanguageCodes();
		var activeUserLanguages = ViiKii.Languages
				.getActiveInterestedLanguageCodes();

		var languageIndex = activeUserLanguages.indexOf(language);
		if (isOn && languageIndex == -1) {
			activeUserLanguages.push(language);
		} else if (!isOn && languageIndex != -1) {
			activeUserLanguages.splice(languageIndex, 1);
		}
		ViiKii.Languages.setInterestedLanguages(userLanguages,
				activeUserLanguages);
	},

	toggleByPlayer : function(language) {
		var userLanguages = ViiKii.Languages.getInterestedLanguageCodes();
		var activeUserLanguages = ViiKii.Languages
				.getActiveInterestedLanguageCodes();

		var languageIndex = activeUserLanguages.indexOf(language);
		if (languageIndex == -1) {
			activeUserLanguages.push(language);
		}
		ViiKii.Languages.setInterestedLanguages(userLanguages,
				activeUserLanguages);
		$(ViiKii.Video.Player._id).changeSubtitleLanguage(language);
	},

	// used by top.thtml
	setInterestedLanguage : function(interestedLanguages) {
		this.interestedLanguages = interestedLanguages;
	},
	setUILanguage : function(uiLanguage) {
		this.uiLanguage = uiLanguage;
		if ($("ViiKii.Languages.UI.layer")) {
			$("ViiKii.Languages.UI.layer").innerHTML = ViiKii.Languages.SelectBox
					.convertToName(uiLanguage);
		}
	},
	setAvailableUILanguages : function(languages) {
		this.availableUILanguages = languages.split(",");
	},
	getAvilableUILanguages : function() {
		return this.availableUILanguages;
	},
	getInterestedLanguage : function() {
		return this.interestedLanguages;
	},
	getToggleOnLanguageNumber : function() {
		var interestedLanguages = this.getActiveInterestedLanguageCodes();
		return interestedLanguages.length;
	},
	getActiveInterestedLanguageCodes : function() {
		var languages = [];
		var interested = this.getInterestedLanguage();
		for ( var language in interested) {
			if (interested[language]['used'] == 1) {
				languages.push(language);
			}
		}
		return languages;
	},
	getInterestedLanguageCodes : function() {
		var languages = [];
		var interestedLanguages = this.getInterestedLanguage();
		for ( var language in interestedLanguages) {
			languages.push(language);
		}
		return languages;
	},
	changeInterstedLanguages : function(newLanguages) {
		if (newLanguages.length == 0) {
			alert("empty languages");
			return;
		}
		var userLanguages = ViiKii.Languages.getInterestedLanguageCodes();
		var userActiveLanguages = ViiKii.Languages
				.getActiveInterestedLanguageCodes();
		var newActiveLanguages = [];
		for ( var i = 0; i < newLanguages.length; i++) {
			var language = newLanguages[i];
			if (userActiveLanguages.indexOf(language) != -1
					|| userLanguages.indexOf(language) == -1) {
				newActiveLanguages.push(language);
			}
		}
		if (newActiveLanguages.length == 0) {
			newActiveLanguages.push(newLanguages[0]);
		}
		this.setInterestedLanguages(newLanguages, newActiveLanguages);
	},
	setInterestedLanguages : function(languages, activeLanguages, autoRefresh) {
		if (autoRefresh == null) {
			autoRefresh = true;
		}
		var ajax = new Ajax.RequestXML('/my/set_interested_languages/'
				+ languages + '/' + activeLanguages, {
			method : 'get',
			asynchronous : false
		});
		this.onSetIntestedLanguages(ajax, autoRefresh);
	},
	onSetIntestedLanguages : function(ajax, autoRefresh) {
		//alert(ajax.transport.responseText);
	var response = ajax.responseValue.response;
	if (response.result == 'SUCCESS') {
		var userLanguages = response.languages.split(",");
		var activeUserLanguages = [];
		if (response.active != null) {
			activeUserLanguages = response.active.split(",");
		}
		var newLanguages = {};
		for ( var i = 0; i < userLanguages.length; i++) {
			var language = userLanguages[i];
			newLanguages[language] = {};
			newLanguages[language]["name"] = ViiKii.Languages.SelectBox
					.convertToName(language);
			if (activeUserLanguages.indexOf(language) != -1) {
				newLanguages[language]["used"] = "1";
			} else {
				newLanguages[language]["used"] = "0";
			}
		}
		this.setInterestedLanguage(newLanguages);
		if (autoRefresh) {
			ViiKii.Languages.changed();
		}
	}
},
getUILanguage : function() {
	return this.uiLanguage;
},

getActiveInterestedLanguage : function() {
	var ret = {};
	var interested = this.getInterestedLanguage();
	for ( var key in interested) {
		if (interested[key]['used'] == 1) {
			ret[key] = {};
			ret[key]['name'] = interested[key]['name'];
			ret[key]['used'] = interested[key]['used'];
		}
	}
	return ret;
}
};// ViiKii.Languages

/**
 * open/close language select panel
 * 
 * use state pattern
 * 
 * @see ViiKii.Languages.SelectBox.UIState
 * @see ViiKii.Languages.SelectBox.InterestedState
 * @see ViiKii.Languages.SelectBox.LoginedInterestedState
 * @see ViiKii.Languages.SelectBox.UserChooseState
 */
ViiKii.Languages.SelectBox = {
	_languageId : [ 'ab', 'aa', 'af', 'ak', 'sq', 'al', 'am', 'ag', 'ar', 'an',
			'hy', 'ra', 'as', 'at', 'av', 'ay', 'az', 'bm', 'ba', 'eu', 'be',
			'bn', 'bh', 'bi', 'bs', 'br', 'bg', 'my', 'km', 'ca', 'ch', 'ce',
			'zh', 'kw', 'co', 'cr', 'hr', 'cs', 'da', 'dv', 'nl', 'dz', 'en',
			'eo', 'et', 'fo', 'fj', 'fi', 'fr', 'gl', 'ka', 'de', 'el', 'kl',
			'gn', 'gu', 'ha', 'he', 'hi', 'hm', 'hu', 'is', 'io', 'id', 'ia',
			'ie', 'iu', 'ik', 'ga', 'it', 'ja', 'jv', 'kn', 'ks', 'cb', 'kk',
			'ky', 'rn', 'tm', 'ko', 'ku', 'lo', 'la', 'lv', 'li', 'ln', 'lt',
			'jb', 'nd', 'lb', 'mk', 'mg', 'ms', 'ml', 'mt', 'gv', 'mi', 'mr',
			'mh', 'zm', 'mo', 'mn', 'nh', 'na', 'no', 'ne', 'om', 'oc', 'or',
			'nn', 'pi', 'pa', 'ps', 'fa', 'pl', 'pt', 'qu', 'ru', 'ro', 'rm',
			'rw', 'sm', 'sg', 'sa', 'sh', 'sn', 'sr', 'sc', 'tn', 'gd', 'sb',
			'sk', 'sd', 'si', 'se', 'sl', 'so', 'su', 'es', 'st', 'sw', 'ss',
			'sv', 'tl', 'tg', 'ta', 'tt', 'te', 'th', 'bo', 'ti', 'tp', 'tq',
			'to', 'ts', 'tr', 'tk', 'tw', 'uk', 'ur', 'ug', 'uz', 'wa', 'vo',
			'vi', 'cy', 'fy', 'wo', 'xh', 'yi', 'yo', 'za', 'zu' ],
	_language : [ 'Abkhazian', 'Afar', 'Afrikaans', 'Akan', 'Albanian',
			'Alemannic', 'Amharic', 'Anglo-Saxon', 'Arabic', 'Aragonese',
			'Armenian', 'Aromanian', 'Assamese', 'Asturian', 'Avar', 'Aymara',
			'Azeri', 'Bambara', 'Bashkir', 'Basque', 'Belarusian', 'Bengali',
			'Bihari', 'Bislama', 'Bosnian', 'Breton', 'Bulgarian', 'Burmese',
			'Cambodian', 'Catalan', 'Chamorro', 'Cherokee', 'Chinese',
			'Cornish', 'Corsican', 'Cree', 'Croatian', 'Czech', 'Danish',
			'Divehi', 'Dutch', 'Dzongkha', 'English', 'Esperanto', 'Estonian',
			'Faroese', 'Fijian', 'Finnish', 'French', 'Galician', 'Georgian',
			'German', 'Greek', 'Greenlandic', 'Guarani', 'Gujarati', 'Hausa',
			'Hebrew', 'Hindi', 'Hmong', 'Hungarian', 'Icelandic', 'Ido',
			'Indonesian', 'Interlingua', 'Interlingue', 'Inuktitut', 'Inupiak',
			'Irish', 'Italian', 'Japanese', 'Javanese', 'Kannada', 'Kashmiri',
			'Kashubian', 'Kazakh', 'Kirghiz', 'Kirundi', 'Klingon', 'Korean',
			'Kurdish', 'Lao', 'Latin', 'Latvian', 'Limburgian', 'Lingala',
			'Lithuanian', 'Lojban', 'Low Saxon', 'Luxembourgish', 'Macedonian',
			'Malagasy', 'Malay', 'Malayalam', 'Maltese', 'Manx', 'Maori',
			'Marathi', 'Marshallese', 'Min Nan', 'Moldovan', 'Mongolian',
			'Nahuatl', 'Nauruan', 'Norwegian (BokmÃ¥l)', 'Nepali', 'Oromo',
			'Occitan', 'Oriya', 'Norwegian (Nynorsk)', 'Pali', 'Punjabi',
			'Pashto', 'Persian', 'Polish', 'Portuguese', 'Quechua', 'Russian',
			'Romanian', 'Raeto Romance', 'Rwandi', 'Samoan', 'Sango',
			'Sanskrit', 'Serbo-Croatian', 'Shona', 'Serbian', 'Sardinian',
			'Setswana', 'Scottish Gaelic', 'Sicilian', 'Slovak', 'Sindhi',
			'Sinhalese', 'Simple English', 'Slovenian', 'Somali', 'Sundanese',
			'Spanish', 'Southern Sotho', 'Swahili', 'Swati', 'Swedish',
			'Tagalog', 'Tajik', 'Tamil', 'Tatar', 'Telugu', 'Thai', 'Tibetan',
			'Tigrinya', 'Tok Pisin', 'Tokipona', 'Tongan', 'Tsonga', 'Turkish',
			'Turkmen', 'Twi', 'Ukrainian', 'Urdu', 'Uyghur', 'Uzbek',
			'Walloon', 'VolapÃ¼k', 'Vietnamese', 'Welsh', 'West Frisian',
			'Wolof', 'Xhosan', 'Yiddish', 'Yoruba', 'Zhuang', 'Zulu' ],
	_activation : [],
	_state : null,
	_container : null,
	_containerLayerName : 'LanguageBoxPanel',
	_selectedItem : [],
	_uiState : null,
	_interestedState : null,
	_loginedInterestedState : null,
	_userChooseState : null,
	_videoChooseState : null,
	_manageChooseState : null,

	_setState : function(state) {
		this._state = state;
	},

	_display : function(left, top) {
		var show = Element.getStyle(this._container, 'display');
		var styles = {
			left : left + 'px',
			top : top + 'px',
			display : 'block',
			"z-index" : 10
		};
		Element.setStyle(this._container, styles);
		return;
	},

	_createContainer : function() {
		var styles;
		this._container = document.createElement('div');
		this._container.id = this._containerLayerName;
		styles = {
			position : 'absolute',
			width : '520px',
			height : '560px',
			backgroundColor : '#ffffff',
			border : 'solid 1px #000000',
			display : 'none'
		};

		Element.setStyle(this._container, styles);
		document.getElementsByTagName('body')[0].appendChild(this._container);

		this.listEle = document.createElement('div');
		this.listEle.id = 'Language_Lists';
		Element.setStyle(this.listEle, {
			margin : '10px 0 0 5px'
		});

		var btnEle = document.createElement('div');
		styles = {
			position : 'absolute',
			bottom : '10px',
			right : '10px'
		};
		Element.setStyle(btnEle, styles);

		btnEle.innerHTML = ''
				+ '<div style="float:left;margin:0 5px 0 0;cursor:pointer;" OnClick="ViiKii.Languages.SelectBox.apply();">'
				+ '	<div style="float:left;background:url(\'/common/btn_left.gif\');width:3px;height:18px;"></div>'
				+ '	<div style="float:left;background:url(\'/common/btn_middle.gif\');height:18px;">Save</div>'
				+ '	<div style="float:left;background:url(\'/common/btn_right.gif\');width:3px;height:18px;"></div>'
				+ '</div>'
				+ '<div style="float:left;cursor:pointer;" OnClick="ViiKii.Languages.SelectBox.close();">'
				+ '	<div style="float:left;background:url(\'/common/btn_left.gif\');width:3px;height:18px;"></div>'
				+ '	<div style="float:left;background:url(\'/common/btn_middle.gif\');height:18px;">Cancel</div>'
				+ '	<div style="float:left;background:url(\'/common/btn_right.gif\');width:3px;height:18px;"></div>'
				+ '</div>';

		this._container.appendChild(this.listEle);
		this._container.appendChild(btnEle);

	},

	_resetLanguage : function() {
		this._selectedItem = [];
		for ( var i = 0, len = this['_languageId'].length; i < len; i++) {
			this['_activation'][i] = 0;
		}
	},

	_setLanguage : function(event) {
		var e = Event.element(event);
		var idx = parseInt(e.id.replace('lang', ''), 10);
		var _activation = this['_activation'][idx];

		this._state.toggle(idx, _activation);
	},
	_getAvailable : function(idx) {
		if (!Object.isFunction(this._state.getAvailable)) {
			return true;
		}
		var languageId = this['_languageId'][idx];
		if (this._state.getAvailable().indexOf(languageId) != -1) {
			return true;
		}
		return false;
	},
	_getSelected : function() {
		ret = this._state.getSelected();

		if (ret != '') {
			this._selectedItem = ret;
			for ( var i = 0; i < this._selectedItem.length; i++) {
				this['_activation'][this['_languageId']
						.indexOf(this._selectedItem[i])] = 1;
			}
		} else {
//			this._selectedItem = [ 'en' ];
//			this['_activation'][this['_languageId'].indexOf('en')] = 1;
		}
		return ret;
	},

	_createElement : function() {
		var el = document.createElement('ul');
		return el;
	},

	_renderElement : function(n) {
		var e = document.createElement('li');
		e.id = 'lang' + n;
		if (this['_activation'][n] == 1) {
			e.style.listStyleImage = 'url(\'/common/bullet_on.gif\')';
		}
		e.innerHTML = this['_language'][n];
		if (this._getAvailable(n)) {
			Event.observe(e, "click", this._setLanguage
					.bindAsEventListener(this));
			e.style.color = "#808080";
			e.style.cursor = "pointer";
		} else {
			e.style.color = "#CCCCCC";
			e.style.cursor = "default";
		}
		return e;
	},

	_isDuplicatedToggleOn : function(index) {
		return this._selectedItem.indexOf(this._languageId[index]) != -1;
	},

	init : function() {
		this._uiState = new ViiKii.Languages.SelectBox.UIState(this);
		this._interestedState = new ViiKii.Languages.SelectBox.InterestedState(this);
		this._loginedInterestedState = new ViiKii.Languages.SelectBox.LoginedInterestedState(this);
		this._userChooseState = new ViiKii.Languages.SelectBox.UserChooseState(this);
		this._videoChooseState = new ViiKii.Languages.SelectBox.Video(this);
		this._manageChooseState = new ViiKii.Languages.SelectBox.ManageChooseState(this);
		this._channelChooseState = new ViiKii.Languages.SelectBox.Channel(this);
		this._channelMirrorChooseState = new ViiKii.Languages.SelectBox.ChannelMirror(this);
		//this._subtitleLockState = new ViiKii.Languages.SelectBox.SubtitleLock(this);
	},

	getUIState : function() {
		return this._uiState;
	},

	getInterestedState : function() {
		return this._interestedState;
	},

	getLoginedInterestedState : function() {
		return this._loginedInterestedState;
	},
	getSubtitleLockState: function(videoId, masterVideoId) {
//		return this._subtitleLockState;
		return new ViiKii.Languages.SelectBox.SubtitleLock(this, videoId, masterVideoId);
	},

	getUserChooseState : function() {
		return this._userChooseState;
	},

	getVideoChooseState : function() {
		return this._videoChooseState;
	},

	getManageChooseState : function() {
		return this._manageChooseState;
	},

	getChannelChooseState : function() {
		return this._channelChooseState;
	},

	getChannelMirrorChooseState : function() {
		return this._channelMirrorChooseState;
	},

	apply : function() {
		this._state.apply();
	},

	close : function() {
		Element.setStyle(this._container, {
			display : 'none'
		});
	},

	open : function(left, top, state) {

		this._setState(state);

		if (!$(this._containerLayerName)) {
			this._createContainer();
		}
		this._display(left, top);

		this._resetLanguage();
		var rtn = this._getSelected();
		if (!rtn) {
			return;
		}

		this.listEle.innerHTML = '';
		for ( var i = 0; i < 5; i++) {
			var el = this._createElement();
			for ( var j = 0, n = Math.ceil(this['_language'].length / 5); j < n; j++) {
				if (this['_language'].length > 5 * j + i) {
					el.appendChild(this._renderElement(5 * j + i));
				}
			}
			this.listEle.appendChild(el);
		}
	},

	getLastSelectedIndex : function() {
		var last_selectedItem = this._selectedItem[(this._selectedItem.length - 1)];
		return this._languageId.indexOf(last_selectedItem);
	},

	toggleOff : function(index) {
		this._activation[index] = 0;
		var clone_selectedItem = this._selectedItem;
		for ( var i = 0; i < clone_selectedItem.length; i++) {
			if (clone_selectedItem[i] == this._languageId[index]) {
				this._selectedItem.splice(i, 1);
			}
		}
		var element = $('lang' + index);
		element.style.listStyleImage = 'url(\'/common/bullet_off.gif\')';
	},

	toggleOn : function(index) {

		if (this._isDuplicatedToggleOn(index)) {
			return;
		}

		this._activation[index] = 1;
		this._selectedItem.push(this._languageId[index]);

		element = $('lang' + index);
		element.style.listStyleImage = 'url(\'/common/bullet_on.gif\')';
	},

	getSelectedItemCount : function() {
		return this._selectedItem.length;
	},

	getSelectedItem : function() {
		return this._selectedItem;
	},

	findSelectedItemIndex : function(key) {
		return this._selectedItem.indexOf(key);
	},

	getLanguageId : function(index) {
		return this._languageId[index];
	},

	getLanguageName : function(index) {
		return this._language[index];
	},

	convertToName : function(languageId) {
		var index = this._languageId.indexOf(languageId);
		if (index == -1) {
			return "";
		}
		return this._language[index];
	}

};// ViiKii.Languages.SelectBox

ViiKii.Languages.SelectBox.State = Class.create();
ViiKii.Languages.SelectBox.State.prototype = {
	initialize : function() {
	},
	getSelected : function() {
	},
	toggle : function(index, activate) {
	},
	apply : function() {
	}
};// ViiKii.Languages.State

ViiKii.Languages.SelectBox.UserChooseState = Class.create();
ViiKii.Languages.SelectBox.UserChooseState.prototype = Object.extend(new ViiKii.Languages.SelectBox.State(),
{
	_selectBox : null,
	initialize : function(selectBox) {
		this._selectBox = selectBox;
	},
	getSelected : function() {
		return [ ViiKii.Languages.getUILanguage() ];
	},
	toggle : function(index, activated) {
		if (index < 0 || this._selectBox.getLastSelectedIndex() == index) {
			return;
		}
		languageId = this._selectBox.getLanguageId(index);
		languageName = this._selectBox.getLanguageName(index);
		var selectedIds = ViiKii.User.Form
				.getSelectedLanguages();
		for ( var i = 0; i < selectedIds.length; i++) {
			if (selectedIds[i].equals(languageId)) {
				alert(languageName + ' is already selected');
				return;
			}
		}

		this._selectBox.toggleOff(this._selectBox
				.getLastSelectedIndex());
		this._selectBox.toggleOn(index);
	},
	apply : function() {
		var languageId = this._selectBox.getLanguageId(this._selectBox.getLastSelectedIndex());
		var languageName = this._selectBox.getLanguageName(this._selectBox.getLastSelectedIndex());
		var selectedIds = ViiKii.User.Form.getSelectedLanguages();
		for ( var i = 0; i < selectedIds.length; i++) {
			if (selectedIds[i].equals(languageId)) {
				alert(languageName + ' is already selected');
				return;
			}
		}
		ViiKii.User.Form.setLanguage(languageId, languageName);
		this._selectBox.close();
	}
});
ViiKii.Languages.SelectBox.SubtitleLock = Class.create();
ViiKii.Languages.SelectBox.SubtitleLock.prototype = Object.extend(new ViiKii.Languages.SelectBox.State(),
{
	_selectBox: null,
	_videoId: 0,
	_masterVideoId: 0,
	initialize: function(selectBox, videoId, masterVideoId) {
		this._selectBox = selectBox;
		this._videoId = videoId;
		this._masterVideoId = masterVideoId;
	},
	getSelected : function() {
		var languages = [];
		new Ajax.Request('/subtitles/get_locked_languages/' + this._masterVideoId, {
			asynchronous: false,
			onComplete: function(transport, response) {
				if ( ! response.languages.empty()) {
					languages =  response.languages.split(',');
				}
			}
		});
		return languages;
	},
	toggle: function(index, activated) {
		if (activated) {
			this._selectBox.toggleOff(index);
		} else {
			this._selectBox.toggleOn(index);
		}
	},
	apply: function() {
		var res = null;
		languages = this._selectBox.getSelectedItem();
		var params = $H({'master_video_id':this._masterVideoId, 'video_id':this._videoId, 'languages':this._selectBox.getSelectedItem().join(',')}).toQueryString();
		new Ajax.Request('/subtitles/save_lock_langauges', {
			parameters: params,
			asynchronous: false,
			onComplete: function(transport, response) {
				res = response;
			}
		});
		
		if (res.result == 'success') {
			this._selectBox.close();
			return;
		}
		alert(res.error);
	}
});
ViiKii.Languages.SelectBox.Video = Class.create();
ViiKii.Languages.SelectBox.Video.prototype = Object.extend(new ViiKii.Languages.SelectBox.State(),
{
	_selectBox : null,
	initialize : function(selectBox) {
		this._selectBox = selectBox;
	},
	getSelected : function() {
		return [ ViiKii.Languages.getUILanguage() ];
	},
	toggle : function(index, activated) {
		if (index < 0 || this._selectBox.getLastSelectedIndex() == index) {
			return;
		}
		this._selectBox.toggleOff(this._selectBox.getLastSelectedIndex());
		this._selectBox.toggleOn(index);
	},
	apply : function() {
		var languageId = this._selectBox.getLanguageId(this._selectBox.getLastSelectedIndex());
		var languageName = this._selectBox.getLanguageName(this._selectBox.getLastSelectedIndex());
		ViiKii.VideoForm.setLanguage(languageId, languageName);
		this._selectBox.close();
	}
});// ViiKii.Languages.SelectBox.UserChooseState

ViiKii.Languages.SelectBox.Channel = Class.create();
ViiKii.Languages.SelectBox.Channel.prototype = Object.extend(new ViiKii.Languages.SelectBox.State(),
{
	_selectBox : null,
	initialize : function(selectBox) {
		this._selectBox = selectBox;
	},
	getSelected : function() {
		return [ ViiKii.Languages.getUILanguage() ];
	},
	toggle : function(index, activated) {
		if (index < 0 || this._selectBox.getLastSelectedIndex() == index) {
			return;
		}
		this._selectBox.toggleOff(this._selectBox.getLastSelectedIndex());
		this._selectBox.toggleOn(index);
	},
	apply : function() {
		var languageId = this._selectBox.getLanguageId(this._selectBox.getLastSelectedIndex());
		var languageName = this._selectBox.getLanguageName(this._selectBox.getLastSelectedIndex());
		ViiKii.Channel.AddForm.setLanguage(languageId,languageName);
		this._selectBox.close();
	}
});// ViiKii.Languages.SelectBox.UserChooseState

ViiKii.Languages.SelectBox.ChannelMirror = Class.create();
ViiKii.Languages.SelectBox.ChannelMirror.prototype = Object.extend(new ViiKii.Languages.SelectBox.State(),
{
	_selectBox : null,
	_callback : null,
	initialize : function(selectBox) {
		this._selectBox = selectBox;
	},
	getSelected : function() {
		return [ ViiKii.Languages.getUILanguage() ];
	},
	toggle : function(index, activated) {

		if (index < 0
				|| this._selectBox.getLastSelectedIndex() == index) {
			return;
		}

		this._selectBox.toggleOff(this._selectBox
				.getLastSelectedIndex());
		this._selectBox.toggleOn(index);
	},
	apply : function() {
		var languageId = this._selectBox.getLanguageId(this._selectBox.getLastSelectedIndex());
		var languageName = this._selectBox.getLanguageName(this._selectBox.getLastSelectedIndex());
		this._callback(languageId, languageName);
		this._selectBox.close();
	},
	setCallback : function(callback) {
		this._callback = callback;
	}
});// ViiKii.Languages.SelectBox.UserChooseState

ViiKii.Languages.SelectBox.ManageChooseState = Class.create();
ViiKii.Languages.SelectBox.ManageChooseState.prototype = Object.extend(new ViiKii.Languages.SelectBox.State(),
{
	_selectBox : null,
	_selectedLanguage : null,
	_callback : null,
	initialize : function(selectBox) {
		this._selectBox = selectBox;
	},
	getSelected : function() {
		if (this._selectedLanguage != null) {
			return [ this._selectedLanguage ];
		}
		return [];
	},
	setSelectd : function(language) {
		this._selectedLanguage = language;
	},
	setCallback : function(callback) {
		this._callback = callback;
	},
	toggle : function(index, activated) {
		if (index < 0 || this._selectBox.getLastSelectedIndex() == index) {
			return;
		}
		this._selectBox.toggleOff(this._selectBox.getLastSelectedIndex());
		this._selectBox.toggleOn(index);
	},
	apply : function() {
		var languageId = this._selectBox.getLanguageId(this._selectBox.getLastSelectedIndex());
		var languageName = this._selectBox.getLanguageName(this._selectBox.getLastSelectedIndex());
		if (this._callback != null) {
			this._callback(languageId, languageName);
		}
		this._selectedLanguage = languageId;
		this._selectBox.close();
	}
});

ViiKii.Languages.SelectBox.UIState = Class.create();
ViiKii.Languages.SelectBox.UIState.prototype = Object.extend(
		new ViiKii.Languages.SelectBox.State(), {
			_selectBox : null,

			initialize : function(selectBox) {
				this._selectBox = selectBox;
			},

			getSelected : function() {
				return [ ViiKii.Languages.getUILanguage() ];
			},

			toggle : function(index, activate) {

				if (index < 0 || this._selectBox.getLastSelectedIndex() == index) {
					return;
				}

				this._selectBox.toggleOff(this._selectBox.getLastSelectedIndex());
				this._selectBox.toggleOn(index);

			},
			getAvailable : function() {
				return ViiKii.Languages.getAvilableUILanguages();
			},
			apply : function() {
				ViiKii.Languages.SelectBox.close();
				ViiKii.Languages.setUILanguage(this._selectBox
						.getSelectedItem());
				var response = new Ajax.Request("/my/set_ui_language/"
						+ this._selectBox.getSelectedItem(), {
					method : "get",
					onSuccess : function(transport) {
						document.location.reload();
					}
				});
			}
		});// ViiKii.Languages.SelectBox.UIState

ViiKii.Languages.SelectBox.InterestedState = Class.create();
ViiKii.Languages.SelectBox.InterestedState.prototype = Object
		.extend(
				new ViiKii.Languages.SelectBox.State(),
				{
					_selectBox : null,

					initialize : function(selectBox) {
						this._selectBox = selectBox;
					},

					getSelected : function() {
						return ViiKii.Languages.getInterestedLanguageCodes();
					},

					toggle : function(index, activate) {
						if (index < 0 
								|| (this._selectBox.getSelectedItemCount() >= 5 && !activate)
								|| (this._selectBox.getSelectedItemCount() <= 2 && activate)) {
							return;
						}

						if (activate) {
							this._selectBox.toggleOff(index);
						} else {
							this._selectBox.toggleOn(index);
						}
					},

					apply : function() {
						ViiKii.Languages.SelectBox.close();
						ViiKii.Languages.changeInterstedLanguages(this._selectBox.getSelectedItem());
					}
				});// ViiKii.Languages.SelectBox.InterestedState

ViiKii.Languages.SelectBox.LoginedInterestedState = Class.create();
ViiKii.Languages.SelectBox.LoginedInterestedState.prototype = Object
		.extend(
				new ViiKii.Languages.SelectBox.State(),
				{
					_selectBox : null,
					initialize : function(selectBox) {
						this._selectBox = selectBox;
					},
					getSelected : function() {
						return ViiKii.Languages.getInterestedLanguageCodes();
					},
					toggle : function(index, activate) {
						if (index < 0
								|| (this._selectBox.getSelectedItemCount() >= 5 && !activate)
								|| (this._selectBox.getSelectedItemCount() <= 2 && activate)) {
							return;
						}

						var foundItemIndex = this._selectBox.findSelectedItemIndex(this._selectBox.getLanguageId(index));
						if (activate) {// remove element.
							this._selectBox.toggleOff(index);
						} else {
							this._selectBox.toggleOn(index);
						}
					},
					apply : function() {
						ViiKii.Languages.SelectBox.close();
						ViiKii.Languages.changeInterstedLanguages(this._selectBox.getSelectedItem());
					}
				});// ViiKii.Languages.SelectBox.LoginedInterestedState

ViiKii.InterestedLanguagePanel = {
	_target : 'interested-panel',
	_subject : null,

	attach : function(subject) {
		this._subject = subject;
		this._subject.attach(this);
	},

	detach : function() {
		this._subject.detach(this);
	},

	update : function() {
		var userLanguages = ViiKii.Languages.getInterestedLanguageCodes();
		var activeUserLanguages = ViiKii.Languages
				.getActiveInterestedLanguageCodes();
		var tag = "";
		for ( var i = 0; i < userLanguages.length; i++) {
			var language = userLanguages[i];
			var languageName = ViiKii.Languages.SelectBox
					.convertToName(language);
			if (activeUserLanguages.indexOf(language) != -1) {
				tag += '<div style="float:left;margin:0 2px 0 0;cursor:pointer;" OnClick="ViiKii.Languages.toggle(\''
						+ language
						+ '\', false);">'
						+ '<div style="float:left;background:url(\'/common/lang_left.gif\');width:4px;height:18px;"></div>'
						+ '<div style="float:left;background:#cccccc;height:18px;">'
						+ languageName
						+ '</div>'
						+ '<div style="float:left;background:url(\'/common/lang_right.gif\');width:4px;height:18px;"></div>'
						+ '</div>';
			} else {
				tag += '<div style="float:left;margin:0 2px 0 0;cursor:pointer;" OnClick="ViiKii.Languages.toggle(\''
						+ language
						+ '\', true);">'
						+ '<div style="float:left;width:4px;height:18px;"></div>'
						+ '<div style="float:left;height:18px;">'
						+ languageName
						+ '</div>'
						+ '<div style="float:left;width:4px;height:18px;"></div>'
						+ '</div>';
			}
		}
		$('interested-panel').update(tag);

	}
};

ViiKii.UILanguagePanel = {
	_target : 'ui-panel',
	_subject : null,

	attach : function(subject) {
		this._subject = subject;
		this._subject.attach(subject);
	},

	detach : function() {
		this._subject.detach(this);
	},

	update : function() {
		$(this._target).innerHTML = ViiKii.Languages.getUILanguage();
	}
};

ViiKii.Help = {
	update : function() {
		this.refresh();
	},
	refresh : function() {
		document.location = '/helps/manage_help';
	},
	editTitle : function(helpId, language) {
		var title = $('help_title_' + helpId + '_' + language).value;
		title = title.trim();
		if (title === '') {
			alert('Insert available help first!');
			return;
		}

		var params = $H( {
			title : title
		}).toQueryString();

		var xml = new Ajax.RequestXML('/helps/edit_help_title/' + helpId + '/'
				+ language, {
			asynchronous : false,
			parameters : params
		});
		this.onEditTitle(xml);
	},
	onEditTitle : function(xml) {
		//alert(xml.transport.responseText);
		var response = xml.responseValue.response;
		if (response.result == 'SUCCESS') {
			alert('Saved Successfully!');
			return;
		}
		switch (response.error) {
		case 'NOT_ADMIN':
			document.location = '/';
			break;
		case 'EMPTY_DATA':
			alert('Insert available help first!!');
			break;
		case 'DB_ERROR':
			alert("Fail to edit help");
		}
	},
	editUrl : function(helpId) {
		var url = $('help_url_' + helpId).value;
		url = url.trim();
		if (url === '') {
			alert('Insert available url first!');
			return;
		}
	
		var params = $H( {
			url : url
		}).toQueryString();
	
		var xml = new Ajax.RequestXML('/helps/edit_help_url/' + helpId, {
			asynchronous : false,
			parameters : params
		});
		this.onEditUrl(xml);
	},
	onEditUrl : function(xml) {
		//alert(xml.transport.responseText);
		var response = xml.responseValue.response;
		if (response.result == 'SUCCESS') {
			alert('Saved Successfully!');
			return;
		}
		switch (response.error) {
		case 'NOT_ADMIN':
			document.location = '/';
			break;
		case 'EMPTY_DATA':
			alert('Insert available url first!!');
			break;
		case 'INVALID_HELP':
			alert('Invalid help url');
			this.refresh();
			break;
		case 'DB_ERROR':
			alert("Fail to edit help");
			break;
		}
	},
	deleteUrl : function(helpId) {
		if (!confirm('Do you really want to delete this help?')) {
			return;
		}
		var xml = new Ajax.RequestXML('/helps/delete_url/' + helpId, {
			asynchronous : false,
			method : 'get'
		});
		this.onDeleteUrl(xml);
	},
	onDeleteUrl : function(xml) {
		//alert(xml.transport.responseText);
		var response = xml.responseValue.response;
		if (response.result == 'SUCCESS') {
			this.refresh();
			return;
		}
		switch (response.error) {
		case 'NOT_ADMIN':
			document.location = '/';
			break;
		case 'DB_ERROR':
			alert("Fail to edit help");
		}
	},
	addUrl : function(type) {
		var xml = new Ajax.RequestXML('/helps/add_url/' + type, {
			asynchronous : false,
			method : 'get'
		});
		this.onAddUrl(xml);
	},
	onAddUrl : function(xml) {
		//alert(xml.transport.responseText);
		var response = xml.responseValue.response;
		if (response.result == 'SUCCESS') {
			this.refresh();
			return;
		}
		switch (response.error) {
		case 'NOT_ADMIN':
			document.location = '/';
			break;
		case 'DB_ERROR':
			alert("Fail to edit help");
		}
	}
};

ViiKii.My.Account = {
	click: function() {
		ViiKii.UI.Folder.toggle('my_viikii_account_folder');
	},
	openDonate: function() {
		new Ajax.Updater(
			'my_viikii_content',
			'/my/payment_history/'+$('owner_name').value,
			 { evalScripts : true }
		);
	}
};
ViiKii.My.Account.History = {
	loadPage : function(page) {
		new Ajax.Updater(
			'my_viikii_content',
			'/my_accounts/history/'+$('owner_name').value+'/'+page,
			{ evalScripts: true}
		);
	}
};
ViiKii.Tracker = {
	track : function(page) {
		if (typeof pageTracker == "undefined"
				&& location.href.indexOf('www.viikii.net') == -1) {
			// alert("track: "+page);
		} else {
			pageTracker._trackPageview(page);
		}
	}
};

/* select box event */
function sbtoggle(header, e) {
	options = $(header).next();
	if (Element.visible(options)) {
		options.hide();
	} else {
		sbblur(e);
		options.show();
		Event.stop(e);
	}
}
function sbclick(sd, fn, v, e) {
	Event.stop(e);
	header = $(sd.href.substr(sd.href.indexOf("#") + 1));
	header.update(sd.innerHTML);
	$(sd).up().up().toggle();
	fn(v);
}
function sbblur(e) {
	var tmp = $$('.divsbox');
	for (i = 0; i < tmp.length; i++) {
		Element.setStyle(tmp[i].down().next(), {
			display : 'none'
		});
	}
}
/**
 * ViiKii UI - RoundContainer ver 0.1
 *
 * @category	UI
 * @package		ViiKii
 * @author		kyungseok.oh <leveess@gmail.com>
 * @author
 * @copyright	Copyright (c) 2007-2008, ViiKii
 * @see
 * @since		Class available since Release 05.08.08
 * @reference
 *
 * @Example
 * 	ViiKii.UI.RoundContainer.init('element', 'options');
 *
 * 	'element' : object
 * 	'options' : corners : 'all',
 * 				radius : 5,
 * 				color : 'fromElement',
 * 				bgColor : 'fromParent',
 * 				borderSize : 0,
 * 				borderColor : '#000'
 *
 **/

ViiKii.UI.RoundContainer = {
	init: function(elements, options) {
		this.options = Object.extend({
            corners : 'all',
            radius : 5,
			bgColor : 'transparent',
			borderColor : '#000',
			borderWidth : 0,
			adjust: true
        }, options || {});
		if(this.options.borderWidth===0) { this.options.borderColor = this.options.bgColor; this.options.borderWidth = 1; }

        if ($(elements) == null) {
            this.element = elements.split(',');
            this.element.type = 'class';
            for (var i = 0, len = this.element.length; i < len; i++) {
                this.round(this.element[i]);
            }
        }
        else {
            this.element = $(elements);
            this.element.type = 'id';
            this.round(this.element);
        }
    },

    round: function(element){
        if (this.element.type == 'class') {
            var el = $$(element);
            for (var i = 0, len = el.length; i < len; i++) {
                this._renderBorder(el[i]);
                if (this._isTopRounded()) { this._render(el[i], 'top'); }
				if (this._isBottomRounded()) { this._render(el[i], 'bottom'); }
            }
        }
        else {
            this._renderBorder(element);
            if (this._isTopRounded()) { this._render(element, 'top'); }
        	if (this._isBottomRounded()) { this._render(element, 'bottom'); }
        }
    },

    _renderBorder: function(element) {
		Element.setStyle(element, Element.getStyle(element, 'position') != 'static' || {position:'relative'});

		var rect = element.getDimensions();
		var styles = {
			height: rect.height - (this._isTopRounded()?this.options.radius:0) - (this._isBottomRounded()?this.options.radius:0) + 'px',
			width: rect.width - (this.options.borderWidth * 2) + 'px',
            borderLeft: parseInt(this.options.borderWidth,10) + "px solid " + this.options.borderColor,
            borderRight: parseInt(this.options.borderWidth,10) + "px solid " + this.options.borderColor,
			backgroundColor: this.options.bgColor
		};

		var source = element.innerHTML;
		element.innerHTML = '';
		Element.append(element, 'DIV', {style:styles, html:(!this.options.adjust?source:'')});
		if (this.options.adjust) {
			Element.append(element, 'DIV', {id:element.id+'_content', style:{position:'absolute',width:'100%',height:'100%',top:'0px',left:'0px',padding:element.getStyle('padding')}, html:source});
		}
    },

    _render: function(element, position) {
        if (!position) { return; }

		var rect = element.getDimensions();
		var margin = this._getMargin(this.options.radius, (this.options.borderWidth < 1 ? 1 : this.options.borderWidth));
        var positions = this._whichSide(position);
        var eleStyles = {borderStyle:"solid", borderWidth:"0px", borderColor:this.options.borderColor, display:"block", overflow:"hidden", margin:"0px", height:"1px"};
		var boxStyles = {width:'100%', height:this.options.radius+'px', margin:'0px'};
		var elem = (position=='top') ? Element.insert(element, element.firstChild, 'DIV', {style:boxStyles}) : Element.append(element, 'DIV', {style:boxStyles});

		for (var i=0,len=margin.length; i<len; i++) {
			marginLeft = this.options.radius + this.options.borderWidth - margin[i][1] - 2;
			borderWidth = margin[i][1] - margin[i][0] + 1;
			Object.extend(eleStyles, {margin:'0 '+marginLeft+'px', borderLeftWidth:borderWidth+'px', borderRightWidth:borderWidth+'px',backgroundColor:(margin[i][0]==0?this.options.borderColor:this.options.bgColor)});
			(position != 'bottom' ?  Element.append(elem, 'DIV', {style:eleStyles}) : Element.insert(elem, elem.firstChild, 'DIV', {style:eleStyles}));
		}
    },

	_getMargin: function(ratio, border) {
		var rtn;
		if (border==1) {
			switch (ratio) {
				case 5 :
					rtn = [[0,0],[1,2],[3,3],[3,3],[4,4]];
					break;
				case 4 :
					rtn = [[0,0],[1,1],[1,1],[3,3]];
					break;
				case 3 :
					rtn = [[0,0],[1,1],[2,2]];
					break;
				case 2 :
					rtn = [[0,0],[1,1]];
					break;
				default :
					rtn = this._margin(ratio, border);
					break;
			}
			return rtn;
		}
		else {
			return this._margin(ratio, border);
		}
	},

	_margin: function(ratio, border, rtn) {
		var x,y,th;
		if(ratio===0) { return [0, 0]; }
		if(!rtn) {
			rtn = [];
			for(var i=0, k=(ratio+border-2); i<=k; i++) { rtn[i] = [1000, 0]; }
		}
		y = ratio - 1;
		th = -3 - (ratio*2);
		for(x = 0; x < y; x++) {
			if(th < 0) { th += 6 + (x << 2); }
			else { th += 10+((x-y) << 2); y--; }
			rtn = this._border(rtn, x, ratio+border-y-2);
			rtn = this._border(rtn, y, ratio+border-x-2);
		}
		border--;
		if(border > 0) { this._margin(ratio+1,border,rtn); }
		return rtn;
	},

    _whichSide: function(side) {
        if (side == 'top') {
            if (this._hasString(this.options.corners, 'all', 'top')) { return ''; }
            if (this.options.corners.indexOf('tl') >= 0 && this.options.corners.indexOf('tr') >= 0) { return ''; }
        	if (this.options.corners.indexOf('tl') >= 0) { return 'left'; }
            else if(this.options.corners.indexOf('tr') >= 0) { return 'right'; }
            return '';
        }
        else if (side == 'bottom') {
            if (this._hasString(this.options.corners, 'all', 'bottom')) { return ''; }
            if (this.options.corners.indexOf('bl') >= 0 && this.options.corners.indexOf('br') >= 0) { return ''; }
        	if (this.options.corners.indexOf('bl') >= 0) {return 'left'; }
            else if(this.options.corners.indexOf('br') >= 0) { return 'right'; }
            return '';
        }
        else {
            return '';
        }
    },

	_border: function(rtn, x, y) {
		if(!rtn[y]) { rtn[y] = [0, 0]; }
		if(rtn[y][0] > x) { rtn[y][0] = x; }
		if(rtn[y][1] < x) { rtn[y][1] = x; }
		return rtn;
	},


    _hasString: function(str) {
        for(var i=1 ; i<arguments.length ; i++) {
        	if (str.indexOf(arguments[i]) >= 0) {
        		return true;
        	}
        }
        return false;
    },

    _isTopRounded: function() {
        return this._hasString(this.options.corners, 'all', 'top', 'tl', 'tr');
    },

    _isBottomRounded: function() {
        return this._hasString(this.options.corners, 'all', 'bottom', 'bl', 'br');
    }
};


/**
 * ViiKii UI - Round ver 0.1
 *
 * @category	UI
 * @package		ViiKii
 * @author		kyungseok.oh <leveess@gmail.com>
 * @author
 * @copyright	Copyright (c) 2007-2008, ViiKii
 * @see
 * @since		Class available since Release 01.01.08
 * @reference
 *
 * @Example
 * 	ViiKii.UI.round.init('element', 'options');
 *
 * 	'element' : object
 * 	'options' : corners : 'all',
 * 				radius : 5,
 * 				color : 'fromElement',
 * 				bgColor : 'fromParent',
 * 				borderSize : 0,
 * 				borderColor : '#000'
 *
 **/

ViiKii.UI.Round = {
    _setOptions: function(options) {
        this.options = {
            corners : 'all',
            radius : 5,
            color : 'fromElement',
			fontColor: '#000',
            bgColor : 'fromParent',
            borderSize : 0,
            borderColor : '#000'
            //transition : Effect.Transitions.circIn
        };
        Object.extend(this.options, options || {});
        if (this.options.radius < 2) {this.options.radius = 2;}
        if (this.options.borderSize > 1) {this.options.borderSize = 1;}
    },

    init: function(elements, options) {
        this._setOptions(options);
        if ($(elements) == null) {
            this.element = elements.split(',');
            this.element.type = 'class';
            for (var i = 0, len = this.element.length; i < len; i++) {
                this.round(this.element[i]);
            }
        }
        else {
            this.element = $(elements);
            this.element.type = 'id';
            this.round(this.element);
        }
    },

    round: function(element){
        if (this.element.type == 'class') {
            var el = $$(element);
            for (var i = 0, len = el.length; i < len; i++) {
                this._renderBorder(el[i]);
                if (this._isTopRounded()) {this._render(el[i], 'top');}
                if (this._isBottomRounded()) {this._render(el[i], 'bottom');}
            }
        }
        else {
            this._renderBorder(element);
            if (this._isTopRounded()) {this._render(element, 'top');}
            if (this._isBottomRounded()) {this._render(element, 'bottom');}
        }
    },

    _renderBorder: function(element) {
		Element.setStyle(element, Element.getStyle(element, 'position') != 'static' || {position:'relative'});

        var defValue = element.innerHTML;
        element.innerHTML = '';
        var e = document.createElement('div');
        var styles = {
            display: 'block',
			color: this.options.fontColor,
			height:'100%',
			clear: 'both',
            borderLeft: (this.options.borderSize > 0 ? parseInt(this.options.borderSize,10) + "px solid " + this.options.borderColor : ''),
            borderRight: (this.options.borderSize > 0 ? parseInt(this.options.borderSize,10) + "px solid " + this.options.borderColor : '')
        };
        //tmpH = parseInt(element.getStyle('height')) - (this._isTopRounded() ? this.options.radius : 0) - (this._isBottomRounded() ? this.options.radius : 0);
        e.innerHTML = defValue;
        Element.setStyle(e, styles);
        element.appendChild(e);
    },

    _render: function(element, position) {
        if (!position) {return;}
        var e = document.createElement('div');
        var styles = {
            position: 'absolute',
            display: 'block',
			left: '0px',
			width: '100%',
            borderColor: '',
            backgroundColor: ''
        };

        var color = this._background(e);
        var borderColor = this._background(element.parentNode);
        var margin = this._getMargin(this.options.radius, (this.options.borderSize < 1 ? 1 : this.options.borderSize));
        var border = this.options.borderSize;
        var corners = {
            element: element,
            position: position,
            borderColor: this._background(element.parentNode)
        };

        var pos = this.options.radius;
        var borderSpace = 0;
        var borderSize = this.options.borderSize - 1;
        for (var i = 0; i < margin.length; i++) {
            if (i >= this.options.borderSize - 1 && this.options.borderSize > 0) {
                borderSpace = pos - (this.options.radius-margin[i][0]);
                pos = this.options.radius - margin[i][0];
                borderSpace = borderSpace===0?1+borderSize:borderSpace+borderSize;
            }
            el = this._createCorner(corners, margin[i], borderSpace, i);
            (position != 'bottom' ? e.appendChild(el) : e.insertBefore(el, e.firstChild));
        }
        if (position != 'bottom') {
 			Element.setStyle(e, Object.extend(styles, {marginTop:'0px', top:'0px'}));
            element.insertBefore(e, element.firstChild);
        }
        else {
 			Element.setStyle(e, Object.extend(styles, {marginBottom:'0px', bottom:'0px', clear:'both'}));
            element.appendChild(e);
        }
    },

    _createCorner: function(corners, margin, borderSpace, n) {
        var e = document.createElement('div');
        var borderWidth = parseInt(this.options.radius - margin[0], 10);
        var styles = {
			borderStyle: 'solid',
            borderWidth: '0px',
            display: 'block',
            overflow: 'hidden',
            margin: '0px ' + parseInt(Element.getStyle(corners.element, 'Right'),10) + 'px 0px ' + parseInt(Element.getStyle(corners.element, 'Left'),10) + 'px',
            height: '1px',
            borderColor: corners.borderColor,
            backgroundColor: 'transparent'
        };
        var positions = this._whichSide(corners.position);
        switch (positions) {
            case 'left'  : Object.extend(styles, {borderLeftWidth: borderWidth + 'px', borderRightWidth: '0px'}); break;
            case 'right' : Object.extend(styles, {borderLeftWidth: '0px', borderRightWidth: borderWidth + 'px'}); break;
            default      : Object.extend(styles, {borderLeftWidth: borderWidth + 'px', borderRightWidth: borderWidth + 'px'}); break;
        }
        Element.setStyle(e, styles);

        if (this.options.borderSize > 0) {
            var bgColor = (n < this.options.borderSize) ? this.options.borderColor : 'transparent';
            var el = '<b style="border-style:solid; border-color:' + this.options.borderColor + '; border-width:0px ' + borderSpace + 'px; margin: 0px; overflow: hidden; display: block; height: 1px; background-color:' + bgColor + ';"></b>';
            e.innerHTML = el;
        }
        return e;
    },

    _borderColor : function(color, bgColor) {
        return (!color ? this.options.color : color);
    },

    _background: function(element) {
        try {
            var actualColor = Element.getStyle(element, "backgroundColor");
            if ( actualColor.match(/^(transparent|rgba\(0,\s*0,\s*0,\s*0\))$/i) && element.parentNode ) {
                return this._background(element.parentNode);
            }
            if ( actualColor === null ) { return '#FFFFFF'; }
            else { return actualColor; }
        } catch(err){
        	return '#FFFFFF';
        }
    },

    _whichSide: function(side) {
        if (side == 'top') {
            if (this._hasString(this.options.corners, 'all', 'top')) { return ''; }
            if (this.options.corners.indexOf('tl') >= 0 && this.options.corners.indexOf('tr') >= 0) { return ''; }
            if (this.options.corners.indexOf('tl') >= 0) { return 'left'; }
            else if(this.options.corners.indexOf('tr') >= 0) { return 'right'; }
            return '';
        }
        else if (side == 'bottom') {
            if (this._hasString(this.options.corners, 'all', 'bottom')) { return ''; }
            if (this.options.corners.indexOf('bl') >= 0 && this.options.corners.indexOf('br') >= 0) { return ''; }
        	if (this.options.corners.indexOf('bl') >= 0) { return 'left'; }
            else if(this.options.corners.indexOf('br') >= 0) { return 'right'; }
            return '';
        }
        else {
            return '';
        }
    },

    _getMargin: function(ratio, border, rtn) {
        var x,y,th;
        if(ratio == 0) {
        	return [0, 0];
        }
        if(!rtn) {
            rtn = [];
            for(var i=0, k=(ratio+border-2); i<=k; i++) { rtn[i] = [1000, 0]; }
        }
        y = ratio - 1;
        th = -3 - (ratio*2);
        for(x = 0; x < y; x++) {
            if(th < 0) { th += 6 + (x << 2); }
            else { th += 10+((x-y) << 2); y--; }
            rtn = this._border(rtn, x, ratio+border-y-2);
            rtn = this._border(rtn, y, ratio+border-x-2);
        }
        border--;
        if(border > 0) {
        	this._getMargin(ratio+1,border,rtn);
        }
        return rtn;
    },

    _border: function(rtn, x, y) {
        if(!rtn[y]) { rtn[y] = [0, 0]; }
        if(rtn[y][0] > x) {rtn[y][0] = x;}
    	if(rtn[y][1] < x) {rtn[y][1] = x;}
        return rtn;
    },

    _hasString: function(str) {
        for(var i=1 ; i<arguments.length ; i++) {
            if (str.indexOf(arguments[i]) >= 0) {
                return true;
            }
        }
        return false;
    },

    _isTopRounded: function() {
        return this._hasString(this.options.corners, 'all', 'top', 'tl', 'tr');
    },

    _isBottomRounded: function() {
        return this._hasString(this.options.corners, 'all', 'bottom', 'bl', 'br');
    }
};


/**
 * ViiKii UI - ScrollBar ver 0.1
 *
 * @category	UI
 * @package		ViiKii
 * @author		kyungseok.oh <leveess@gmail.com>
 * @author
 * @copyright	Copyright (c) 2007-2008, ViiKii
 * @see
 * @since		Class available since Release 23.01.08
 * @reference
 *
 * @Example
 * 	ViiKii.UI.ScrollBar.init('element', 'options');
 *
 * 	'element' : object
 * 	'options' : wheelSize: 20,
 * 				scrWidth: 11,
 * 				btnHeight: 11,
 * 				scrBGColor: '#EFEFEF',
 * 				scrBarColor: 'darkblue',
 * 				img: {
 * 					track: '/common/scrtrack.gif',
 * 					up: '/common/scrupbtn.gif',
 * 					down: '/common/scrdownbtn.gif',
 * 					bar_t: '/common/scrbar_t.gif',
 * 					bar_b: '/common/scrbar_b.gif',
 * 					bar : '/common/scrbar.gif'
 *				}
 *
 **/

ViiKii.UI.ScrollBar = Class.create();
ViiKii.UI.ScrollBar.prototype = {
	version: '0.1',
	name: 'ViiKii.ScrollBar',
	initialize: function(element, options) {
		if (typeof element == 'string') { element = $(element); }
		this.element = element;

		this.scrDragable = false;
		this.scrDragStart = 0;
		this.setOptions(options);
		this.createScroll();

		this.mouseDown  = this._mouseDown.bindAsEventListener(this);
		this.mouseMove  = this._mouseMove.bindAsEventListener(this);
		this.mouseUp    = this._mouseUp.bindAsEventListener(this);
		this.mouseWheel = this._mouseWheel.bindAsEventListener(this);

		//Event.observe(document, 'selectstart', function(){ return false; });
		Event.observe(this.element, 'mousedown', this.mouseDown);
		Event.observe(this.element, 'mousemove', this.mouseMove);
		Event.observe(document, 'mouseup', this.mouseUp);
		Event.observe(this.element, 'mousewheel', this.mouseWheel);
		if (this.element.addEventListener) { Event.observe(this.element, 'DOMMouseScroll', this.mouseWheel); }
	},

	createScroll: function() {
		/* contents section */
		var opt = {
			id: 'scrContent',
			style: {
				position: 'absolute',
				left: '0px',
				top: '0px',
				width: parseInt(Element.getDimensions(this.element).width,10) - this.options.scrWidth + 'px',
				height: '100%', //Element.getStyle(this.element, 'height'),
				overflow: 'hidden'
			},
			html: this.element.innerHTML
		};

		/* Scroll Bar */
		var tmpTrack = parseInt(this.element.offsetHeight,10) - this.options.btnHeight * 2;
		var tmpBar = Math.ceil(tmpTrack * parseInt(this.element.offsetHeight,10) / parseInt(this.element.scrollHeight,10));
		this.Rect = {
			content: parseInt(this.element.scrollHeight,10),
			scroll: parseInt(this.element.offsetHeight,10),
			track: tmpTrack,
			bar:tmpBar,
			limit: tmpTrack - tmpBar
		};

		this.element.innerHTML = '';
		this.scrContent = Element.create('div', opt);
		this.element.appendChild(this.scrContent);
		this.scrContent.scrollTop = 0;

		/* scrollbar BG */
		opt = {
			id: 'scrBG',
			style: {
				position: 'absolute',
				top: '0px',
				right: '0px',
				height: Element.getStyle(this.element, 'height'),
				width: this.options.scrWidth + 'px',
				display: this._isScroll(this.scrContent) ? 'block' : 'none'
			}
		};
		this.scr = Element.create('div', opt);
		this.element.appendChild(this.scr);

		/* Up, Down Button. */
		var btnStyles = {
			position: 'absolute',
			width: this.options.scrWidth + 'px',
			height: this.options.btnHeight + 'px',
			cursor: 'pointer',
			fontSize: '12px',
			textAlign: 'center'
		};

		opt = {
			id: 'scrUpBtn',
			style: Object.extend(Object.clone(btnStyles), {top: '0px', backgroundImage:'url('+this.options.img.up+')', backgroundPosition:'top', backgroundRepeat:'no-repeat'}),
			html: ''
		};
		this.scrUpBtn = Element.create('div', opt);
		this.scr.appendChild(this.scrUpBtn);

		opt = {
			id: 'scrTrack',
			style: Object.extend(Object.clone(btnStyles), {top:btnStyles.height, height:this.Rect.track+'px', backgroundImage:'url('+this.options.img.track+')'})
		};
		this.scrTrack = Element.create('div', opt);
		this.scr.appendChild(this.scrTrack);

		opt = {
			id: 'scrDnBtn',
			style: Object.extend(Object.clone(btnStyles), {bottom: '0px', backgroundImage:'url('+this.options.img.down+')', backgroundPosition:'bottom', backgroundRepeat:'no-repeat'}),
			html: ''
		};
		this.scrDnBtn = Element.create('div', opt);
		this.scr.appendChild(this.scrDnBtn);

		opt = {
			id: 'scrBar',
			style: Object.extend(Object.clone(btnStyles), {left:'0px', height: this.Rect.bar+'px', backgroundImage:'url('+this.options.img.bar+')'}),
			html: '<img src="'+this.options.img.bar_t+'" height="3" width="13" border="0" style="position:absolute; top:0px; left:0px;">'
			    + '<img src="'+this.options.img.bar_b+'" height="3" width="13" border="0" style="position:absolute; bottom:0px; left:0px;">'
		};
		this.scrBar = Element.create('div', opt);
		this.scrTrack.appendChild(this.scrBar);
	},

	update: function() {
		var tmpTrack = parseInt(this.element.offsetHeight,10) - this.options.btnHeight * 2;
		var tmpBar = Math.ceil(tmpTrack * parseInt(this.element.offsetHeight,10) / parseInt(this.scrContent.scrollHeight,10));
		this.Rect = {content:parseInt(this.scrContent.scrollHeight,10), scroll: parseInt(this.element.offsetHeight,10), track:tmpTrack, bar:tmpBar, limit:tmpTrack-tmpBar };
		this.scrBar.setStyle({height:tmpBar+'px'});
		this.scr.setStyle({display:this._isScroll(this.scrContent) ? 'block' : 'none'});
	},

	_isScroll: function(element){
		return (parseInt(Element.getStyle(this.element, 'height'),10) >= element.scrollHeight) ? false : true;
	},

	_setScroll: function() {
		var scrValue = arguments[0];
		var trkValue = arguments[1];
		//alert(scrValue);
		this.scrContent.scrollTop = scrValue;
		Element.setStyle(this.scrBar, {top: trkValue + 'px'});
	},

	_resize: function() {
		/*
		var tmpTrack = parseInt(this.element.offsetHeight) - this.options.btnHeight * 2;
		var tmpBar = Math.ceil(tmpTrack * parseInt(this.element.offsetHeight) / parseInt(this.element.scrollHeight));
		this.Rect = {content:parseInt(this.element.scrollHeight), scroll: parseInt(this.element.offsetHeight), track:tmpTrack, bar:tmpBar, limit:tmpTrack-tmpBar };

		this.element.innerHTML = '';
		this.scrContent = Element.create('div', opt);
		this.element.appendChild(this.scrContent);
		this.scrContent.scrollTop = 0;
		*/
	},

	_mouseDown: function(event) {
		var scrValue, trkValue;
		var el = $(Event.element(event));
		switch (el.id) {
			case 'scrUpBtn' :
				if (!Event.isLeftClick(event)) { return; }
				scrValue = this.scrContent.scrollTop - this.options.wheelSize;
				if (scrValue < 0) { scrValue = 0; }
				trkValue = Math.round(scrValue / (this.Rect.content - this.Rect.scroll) * this.Rect.limit);
				if (trkValue >= this.Rect.limit) { trkValue = this.Rect.limit; }
				this._setScroll(scrValue, trkValue);
				break;
			case 'scrDnBtn' :
				if (!Event.isLeftClick(event)) { return; }
				scrValue = this.scrContent.scrollTop + this.options.wheelSize;
				if (scrValue < 0) {scrValue = 0;}
				trkValue = Math.round(scrValue / (this.Rect.content - this.Rect.scroll) * this.Rect.limit);
				if (trkValue >= this.Rect.limit) {trkValue = this.Rect.limit;}
				this._setScroll(scrValue, trkValue);
				break;
			case 'scrBar' :
				if (!Event.isLeftClick(event)) {return;}
				this.scrDragable = true;
				this.startDragY = parseInt(Event.pointerY(event),10);
				this.startPosY = Position.positionedOffset(Event.element(event),10)[1];
				break;
		}
	},

	_mouseMove: function(event) {
		if (this.scrDragable) {
			var dragY = this.startPosY + parseInt(Event.pointerY(event),10) - this.startDragY;
			if (dragY < 0) {dragY = 0;}
			if (dragY > this.Rect.limit) {dragY = this.Rect.limit;}
			var per = dragY / this.Rect.limit;
			moveY = Math.floor((this.Rect.content - this.Rect.scroll) * per);
			this._setScroll(moveY, dragY);
		}

	},

	_mouseUp: function(event) {
		this.scrDragable = false;
		Event.stop(event);
	},

	_mouseWheel: function(event) {
		wheel = Event.wheel(event);
		var scrValue = this.scrContent.scrollTop - wheel * this.options.wheelSize;
		if (scrValue < 0) {scrValue = 0;}
		var trkValue = (scrValue / (this.Rect.content - this.Rect.scroll)) * this.Rect.limit;
		if (trkValue >= this.Rect.limit) {trkValue = this.Rect.limit;}
		this._setScroll(scrValue, trkValue);
		Event.stop(event);
	},

	setOptions: function(options) {
		this.options = {
			wheelSize: 20,
			scrWidth: 11,
			btnHeight: 11,
			scrBGColor: '#EFEFEF',
			scrBarColor: 'darkblue',
			img: {
				track: '/common/scrtrack.gif',
				up: '/common/scrupbtn.gif',
				down: '/common/scrdownbtn.gif',
				bar_t: '/common/scrbar_t.gif',
				bar_b: '/common/scrbar_b.gif',
				bar : '/common/scrbar.gif'
			}
		};
		Object.extend(this.options, options || {});
	}
};

Object.extend(Element, {
  	setOption: function(element, index, text) {
		element.list[index].text = text;
		element.list[index].innerHTML = text;
		if (element.selectedIndex == index) { element.root.innerHTML = text; }
	}
});

/**
 * ViiKii UI - Shadow Layer ver 0.1
 *
 * @category	UI
 * @package		ViiKii
 * @author		kyungseok.oh <leveess@gmail.com>
 * @author
 * @copyright	Copyright (c) 2007-2008, ViiKii
 * @see
 * @since		Class available since Release 01.01.08
 * @reference
 *
 * @Example
 * 	new ViiKii.UI.Shadow('element', 'options');
 *
 * 	'element' : element ID
 * 	'options' : options
 *
 **/

ViiKii.UI.Shadow = Class.create();
ViiKii.UI.Shadow.prototype = {
	initialize: function(element, options) {
		if (typeof element == 'string') { element = $(element); }
		this.element = element;

		this.options = Object.extend({
			shadow : 3,
			color  : '#000000',
			opacity: 0.2,
			round  : {radius:5}
		}, options || {});
		//alert(this.options.round.radius);
		//alert(dump(this.options));
		var rect = Element.getDimensions(this.element);
		this.width  = rect.width + this.options.shadow;
		this.height = rect.height + this.options.shadow;
		//alert([this.width, this.height].join('\n'));
		this.container = Element.create('DIV', {style:{width:this.width+'px', height:this.height+'px'}});
		if (this.element.getStyle('position')!='static') {
			styles = this.element.style;
			this.container.setStyle({position:styles.position, left:styles.left, top:styles.top});
			this.element.setStyle({left:'0px',top:'0px'});
		}
		var parentNode = this.element.parentNode;
		parentNode.insertBefore(this.container, this.element);
		//parentNode.appendChild(this.container);
		parentNode.removeChild(this.element);
		var shadowLayer = Element.append(this.container, 'DIV', {style:{width:rect.width+'px', height:rect.height+'px',marginTop:this.options.shadow+'px',marginLeft:this.options.shadow+'px',opacity:this.options.opacity}});
		ViiKii.UI.RoundContainer.init(shadowLayer, {radius:this.options.round.radius, bgColor:this.options.color});
		this.container.appendChild(this.element);
		return this.container;
	}

};

/**
 * ViiKii UI - Tab Pannel ver 0.1
 *
 * @category	UI
 * @package		ViiKii
 * @author		kyungseok.oh <leveess@gmail.com>
 * @author
 * @copyright	Copyright (c) 2007-2008, ViiKii
 * @see
 * @since		Class available since Release 01.01.08
 * @reference
 *
 * @Example
 * 	new ViiKii.UI.Tab('headers', 'contents', 'options');
 *
 * 	'headers' : header Class
 *  'contents': content Class
 * 	'options' : options
 *
 **/
ViiKii.UI.Tab = Class.create();
ViiKii.UI.Tab.prototype = {
	initialize: function(headers, contents, options) {
		if (typeof headers == 'string') {headers = $$(headers);}
		if (typeof contents == 'string') {contents = $$(contents);}

		this.headers = headers;
		this.contents = contents;
		this.options = Object.extend ({
			delay: 100,
			opacity: false
		}, options || {});

		//contents.each ( function(e) { if (e) Element.hide(e); } );
		contents.each ( function(e) { if (e) { Element.setStyle(e, {left:'10000px', top:'10000px'}); } } );
		this.hoverSet = new ViiKii.HoverSet(headers, options);
		this.selectionSet = new ViiKii.SelectionSet(headers, Object.extend(this.options, {onSelect: this.onSelect.bind(this)}));
		this.transition(this.selected);
	},
	onSelect: function(header) {
		var callback = header.getAttribute('func');
		if (typeof callback != 'undefined' && callback != 'null') {rtn = eval(callback);}

	  	if (this.selected == this.contentOf(header)) {return;}
		var panel = this.contentOf(header);
		if (this.selected) {
			this.transition(panel);
		}
		else {
			Element.setStyle(panel, {left:'0px', top:'0px'});
		}
			//Element.show(panel);
		this.selected = panel;
		//alert(this.selected.id);
		// 2008-04-15 Add.
		//ViiKii.UI.Round.init($(this.selected.id), {corners:'top', radius:2});
	},
	transition: function(element){
		//if (this.selected) Element.hide(this.selected);
		//Element.show(element);
		if (this.selected) { Element.setStyle(this.selected, {left:'10000px', top:'10000px'}); }
		Element.setStyle(element, {left:'0px', top:'0px'});
	},
	contentOf: function(header){ return this.contents[this.headers.indexOf(header)]; }
};

ViiKii.UI.EditableCell = Class.create();
ViiKii.UI.EditableCell.prototype = {
	_cellId: null,
	_textAreaId: null,
	_txtId: null,
	initialize: function() {
		_cellId = null;
		_textAreaId = null;
		_txtId = null;
	},
	setText: function (txt, revisionId, revision){
		$(this._txtId).innerHTML = txt;
		$(this._cellId).setAttribute("rev", revision);
		//$(this._cellId).setAttribute("tagId", revisionId);
		var textAreaText = txt;
		if(textAreaText == "") {
			textAreaText = "&nbsp;";
		}
		if (revision != 0 && revision != null) {
			textAreaText += "&nbsp;&nbsp;&nbsp;<span id=\"revision_"+revisionId+"\" style=\"cursor:pointer;\" class=\"det_revision\">+" + revision + "</span>";
		}
		textAreaText += "<div id=\""+this._txtId+"\" style=\"display:none;\">"+txt+"</div>";

		$(this._cellId).innerHTML = textAreaText;
		this.selectCell(this._cellId, false);
	},
	cancelEdit: function() {
		this.setText(this.getLastText(), this.getTagId(), this.getRevision());
	},
	selectCell: function(cellId, select) {
		var upperCell = this.getPrevCell(cellId);
		if(select) {
			if(upperCell != null) {
				Element.removeClassName(upperCell, "det_cell_line");
				Element.addClassName(upperCell, "det_cell_upper");
			}
			Element.removeClassName($(cellId), "det_cell_line");
			Element.addClassName($(cellId), "det_cell_select");
		} else {
			if(upperCell != null) {
				Element.removeClassName(upperCell, "det_cell_upper");
				Element.addClassName(upperCell, "det_cell_line");
			}
			Element.removeClassName($(cellId), "det_cell_select");
			Element.addClassName($(cellId), "det_cell_line");
		}
	},
	getPrevCell: function(cellId) {
		var curCellIndex = $(cellId).cellIndex;
		var curRow = $(cellId).parentNode;
		if (curRow.rowIndex <= 1) {
			return null;
		}
		var prevRow = curRow.parentNode.rows[curRow.rowIndex-1];
		var prevCellIndex = curCellIndex;
		if(curRow.cells.length != prevRow.cells.length) {
			prevCellIndex = curCellIndex+1;
		}
		return prevRow.cells[prevCellIndex];
	},
	editCell: function (id) {
		this._cellId = id;
		this._txtId = id.replace("cell", "txt");
		var cellHeight = $(this._cellId).offsetHeight + 18;
		this._textAreaId = id.replace("cell", "edit");
		var saveId = id.replace("cell", "save");
		var cancelId = id.replace("cell", "cancel");
		var cellText = $(this._txtId).innerHTML;
		var cellTag = "<textarea class=\"det_edit_textarea\" id=\""+this._textAreaId+"\" style=\"border:0;background-color:transparent;overflow:hidden;width:100%;height:"+cellHeight+"px\">";
		cellTag += "</textarea>";
		cellTag += "<div style=\"text-align:right;\">";
		cellTag += "<span id=\""+saveId+"\" class=\"det_save\" style=\"cursor:pointer;\">[Save]</span>";
		cellTag += "&nbsp;&nbsp;";
		cellTag += "<span id=\""+cancelId+"\" class=\"det_save\" style=\"cursor:pointer;\">[Cancel]</span>";
		cellTag += "</div>";
		cellTag += "<div id=\""+this._txtId+"\" style=\"display:none;\">"+cellText+"</div>";
		
		$(this._cellId).innerHTML = cellTag;
		$(this._textAreaId).onkeydown = this.onTextAreaKeyDown;
		$(this._textAreaId).editCell = this;

		cellText = cellText.split("<br>").join("\n");
		cellText = cellText.split("&gt;").join(">");
		cellText = cellText.split("&lt;").join("<");
		cellText = cellText.split("&amp;").join("&");

		$(this._textAreaId).value = cellText;
		this.selectCell(this._cellId, true);
		$(this._textAreaId).focus();
	},
	onKeyEnterDown: null,
	onKeyESCDown: null,
	onTextAreaKeyDown: function(event) {
		var keyCode = window.event ? window.event.keyCode : event.which;
		switch(keyCode) {
		case 13:
			if(this.editCell.onKeyEnterDown) {
				eval(this.editCell.onKeyEnterDown);
			}
			break;
		case 27:
			if(this.editCell.onKeyESCDown) {
				eval(this.editCell.onKeyESCDown);
			}
			break;
		}
	},

	getTagId: function() {
		return $(this._cellId).getAttribute("tagId");
	},
	getRevision: function() {
		return $(this._cellId).getAttribute("rev");
	},
	getLastText: function() {
		return $(this._txtId).innerHTML;
	},
	getTextAreaText: function() {
		var textAreaText = $(this._textAreaId).value;
		textAreaText = textAreaText.split("&").join("&amp;");
		textAreaText = textAreaText.split(">").join("&gt;");
		textAreaText = textAreaText.split("<").join("&lt;");
		textAreaText = textAreaText.split("\n").join("<br>");
		return textAreaText;
	},
	getCellId: function() {
		return this._cellId;
	}
};

//ViiKii.UI.Tooltip = {
//	version: '0.2',
//	name: 'ViiKii.Tooltip',
//	container: [],
//	tooltip: [],
//	register: function(container) {
//		if (typeof container == 'undefined') { container = document.body; }
//		else if (typeof container == 'string') { container = $(container); }
//
//		if (this.container.indexOf(container) < 0) {
//			this.container.push(container);
//
//			container.descendants().findAll(function(node) {
//				return node.readAttribute('msg');
//			}).each( function(node) {
//				var tp = new ViiKii.UI.Tooltip.Base(container, node, node.readAttribute('msg'));
//			});
//		}
//	},
//
//	remove: function(container) {
//		this.container.without(container);
//	},
//
//	createLog : function() {
//		logDiag = Element.append(document.body, 'div', {id:'Logging',style:{position:'absolute',top:'200px',backgroundColor:'white', left:'0px',border:'1px solid red', width:'150px',height:'300px'}});
//	}
//};

//ViiKii.UI.Tooltip.Base = Class.create();
//ViiKii.UI.Tooltip.Base.prototype = {
//	initialize: function(container, element, tooltip) {
//		this.container = container;
//		this.element = element;
//		this.options = Object.extend({ posX: 0, posY: -18 }, arguments[3] || {});
//
//		if ($(tooltip)) {
//			this.tooltip = $(tooltip);
//		}
//		else {
//			this.tooltip = Element.append(document.body, 'div', {classname:'tooltip'} );
//			this.Limg    = Element.append(this.tooltip, 'div', {classname:'left'} );
//			this.message = Element.append(this.tooltip, 'div', {classname:'msg'} );
//			this.Rimg    = Element.append(this.tooltip, 'div', {classname:'right'} );
//			this.tail    = Element.append(this.tooltip, 'div', {classname:'tail'} );
//			this.message.appendChild(document.createTextNode(tooltip));
//		}
//	    this.tooltip.hide();
//	    this.hOver = this.showTooltip.bindAsEventListener(this);
//	    this.hOut  = this.hideTooltip.bindAsEventListener(this);
//	    this.registerEvents();
//	},
//
//	destroy: function() {
//	    Event.stopObserving(this.element, "mouseover", this.hOver);
//	    Event.stopObserving(this.element, "mouseout",  this.hOut);
//	},
//
//	registerEvents: function() {
//	    Event.observe(this.element, "mouseover", this.hOver);
//	    Event.observe(this.element, "mouseout",  this.hOut);
//	},
//
//	showTooltip: function(event) {
//		Event.stop(event);
//		var pos = Position.relativeOffset(this.container, this.element);
//		Element.setStyle(this.tooltip, {position:'absolute', left:pos[0]+this.options.posX+'px', top:pos[1]+this.options.posY+'px', display:'block', zIndex:1});
//	},
//
//	hideTooltip: function(event) {
//		var tp_hide = new Element.hide(this.tooltip);
//	}
//};

var DragHandler = {
	_oElem : null,
	attach : function(element, oElem) {
		DragHandler._oElem = element;
		oElem.onmousedown = DragHandler._dragBegin;
		element.dragBegin = new Function();
		element.drag = new Function();
		element.dragEnd = new Function();
		return oElem;
	},

	_dragBegin : function(e) {
		var oElem = DragHandler._oElem;

		if (isNaN(parseInt(oElem.style.left,10))) { oElem.style.left = '0px'; }
		if (isNaN(parseInt(oElem.style.top,10))) { oElem.style.top = '0px'; }

		var x = parseInt(oElem.style.left,10);
		var y = parseInt(oElem.style.top,10);

		e = e ? e : window.event;
		oElem.mouseX = e.clientX;
		oElem.mouseY = e.clientY;

		oElem.dragBegin(oElem, x, y);

		document.onmousemove = DragHandler._drag;
		document.onmouseup = DragHandler._dragEnd;
		return false;
	},

	_drag : function(e) {
		var oElem = DragHandler._oElem;

		var x = parseInt(oElem.style.left,10);
		var y = parseInt(oElem.style.top,10);

		e = e ? e : window.event;
		oElem.style.left = x + (e.clientX - oElem.mouseX) + 'px';
		oElem.style.top = y + (e.clientY - oElem.mouseY) + 'px';

		oElem.mouseX = e.clientX;
		oElem.mouseY = e.clientY;

		oElem.drag(oElem, x, y);

		return false;
	},

	_dragEnd : function() {
		var oElem = DragHandler._oElem;

		var x = parseInt(oElem.style.left,10);
		var y = parseInt(oElem.style.top,10);

		oElem.dragEnd(oElem, x, y);

		document.onmousemove = null;
		document.onmouseup = null;
	}
};

ViiKii.UI.AltPool = {
	_name: 'ViiKii.UI.AltPool',
	_version: '0.1',
	_ids: [],

	create: function() {
		var id = this._ids.length;
		this._ids.push(new ViiKii.UI.Alt(id));
		return this._ids[id];
	},

	clear: function() {
		var len = this._ids.length;
		var alt = null;
		for(var i=0; i < len; i++) {
			alt = this._ids.pop();
			alt.close();
		}
	}
};

ViiKii.UI.Alt = Class.create();
ViiKii.UI.Alt.prototype = {
	_id : '',
	_layerName: '',
	_msg : '',

	initialize: function(id) {
		this._id = id;
		this._layerName = 'alt-' + id;
	},

	alt: function(x, y, msg) {
		var alt = '';
			alt += '<div style="float:left;background:url(\'/common/input_tooltip_left.gif\');width:22px;height:29px;position:"></div>';
			alt += '<div style="float:left;background:url(\'/common/input_tooltip_middle.gif\');height:29px;position:relative;"><div id=\'alt-msg\' style="float:left;position:relative;left:-10px;top:2px;">' + msg + '</div></div>';
			alt += '<div style="float:left;background:url(\'/common/input_tooltip_right.gif\');width:4px;height:29px;position:"></div>';

		var div = null;
		if ($(this._layerName)) {
			div = $(this._layerName);
			div.innerHTML = alt;
		} else {
			div = document.createElement('div');
			div.id = this._layerName;
			document.getElementsByTagName('body')[0].appendChild(div);
		}

		var styles = {
			position: 'absolute',
			left: x + 'px',
			top: y + 'px',
			display: 'block'
		};

		Element.setStyle(div, styles);
		div.innerHTML = alt;
	},

	close: function() {
		if ($(this._layerName)) {
			document.getElementsByTagName('body')[0].removeChild($(this._layerName));
		}
	},

	hidden: function() {
		if ($(this._layerName)) {
			$(this._layerName).style.display = 'none';
		}
	}
};


ViiKii.UI.StarBox = Class.create();
ViiKii.UI.StarBox.prototype = {
	version: '0.1',
	name: 'StarBox',

	_id: '',
	_boxId: '',
	_ptUnit: 50,
	_cellWidth: 7,
	_call: null,
	_params: null,
	_point: 0,
	_starMaxWidth: 70,
	_starFullId: '',
	_starEmptyId: '',
	_starFullWidth: 0,
	_starEmptyWidth: 0,
	_boxWidth: 70,
	_rate: 0,
	_assignedEvent: false,

	initialize: function(id, rate, call, params) {
		this._id = id;
		this._boxId =  this._id + '_starb';
		this._leftMarginId = this.id + '_left_margin';
		this._starFullId = this._boxId + '_full';
		this._starEmptyId = this._boxId + '_empty';
		this._setRate(rate);

		$(id).innerHTML = this._createStarBoxTag();
		this._update();

		if (!Object.isUndefined(call)) {
			this._call = call;
			Event.observe($(this._leftMarginId), 'mouseover', this.onMouseOver.bindAsEventListener(this, this));
			Event.observe($(this._boxId), 'mousemove', this.onMouseMove.bindAsEventListener(this, this));
			Event.observe($(this._boxId), 'mouseout', this.onMouseOut.bindAsEventListener(this, this));
			Event.observe($(this._boxId), 'click', this.onClick.bindAsEventListener(this, this));
		}

		if (!Object.isUndefined(params)) {
			this._params = params;
		}
	},

	updateEvent: function() {
	},

	_setRate: function(rate) {
		this._rate = (rate > 500) ? 500 : (rate < 0) ? 0 : rate;
		this._starFullWidth = this._rateToWidth(this._rate);
		this._starEmptyWidth = this._starMaxWidth - this._starFullWidth;
	},

	set: function(rate) {
		this._setRate(rate);
		this._update();
	},

	_rateToWidth: function(rate) {
		var cell = Math.floor(rate / this._ptUnit);
		if (rate % this._ptUnit > (this._ptUnit/2)) {
			cell++;
		}
		return this._cellWidth * cell;
	},

	_createStarBoxTag: function() {
		var tag = '';
		tag += '<div id="' + this._leftMarginId + '" style="float:left;width:1px;height:15px;"></div><div id="' + this._boxId + '" style="float:left;width:' + this._boxWidth + 'px;height:15px;border:solid 0px blue;">';
		tag += '<div id="' + this._starFullId + '" style="float:left;height:15px;background:url(\'/common/star_full.gif\');background-repeat:repeat-x;border:solid 0px red;"></div>';
		tag += '<div id="' + this._starEmptyId + '" style="float:left;height:15px;background:url(\'/common/star_empty.gif\');background-repeat:repeat-x;"></div>';
		tag += '<div style="clear:both;"></div>';
		tag += '</div>';
		return tag;
	},

	_update: function(width) {
		var tmpwidth = Object.isUndefined(width);
		var fullWidth = (tmpwidth) ? this._starFullWidth : width;
		fullWidth = (fullWidth > this._starMaxWidth) ? this._starMaxWidth : fullWidth;

		$(this._starFullId).style.width = fullWidth + 'px';
		$(this._starEmptyId).style.width = (this._starMaxWidth - fullWidth) + 'px';
		var emptyStarBoxBackPos = (fullWidth % 14 === 0) ? 0 : -7;
		$(this._starEmptyId).style.backgroundPosition = emptyStarBoxBackPos + 'px 0px';
	},

	convertPositionToWidth: function(x) {
		var pos = Position.realOffset($(this._boxId));
		x = x - Position.cumulativeOffset($(this._boxId))[0];
		var cell = parseInt(x/7,10);
		if (x % 7) {
			cell++;
		}
		return (cell*7);
	},

	onMouseOver: function(e, starBox) {
		starBox._update();
	},

	onMouseMove: function(e, starBox) {
		starBox._update(starBox.convertPositionToWidth(Event.pointerX(e)));
	},

	onMouseOut: function(e, starBox) {
		if (!Position.within($(starBox._boxId), Event.pointerX(e), Event.pointerY(e))) {
			starBox._update();
		}
	},

	convertPositionToPoint: function(x) {
		var relativeX = x - Position.cumulativeOffset($(this._boxId))[0];
		var cell = parseInt(relativeX/this._cellWidth,10);
		return (relativeX % this._cellWidth ) ? (cell+1) * 50 : cell * 50;
	},

	onClick: function(e, starBox) {
		var point = starBox.convertPositionToPoint(Event.pointerX(e));
		starBox._setPoint(point);
		starBox._call(starBox, starBox._params);
	},

	callBack: function() {
		this._call(this, this._params);
	},

	_setPoint: function(point) {
		this._point = point;
	},

	getPoint: function() {
		return this._point;
	},

	getRate: function() {
		return this._rate;
	}
};

ViiKii.UI.Util = {
	toggle: function(element) {
		if($(element)) {
			Element.toggle(element);
		}
	}
};

ViiKii.UI.Languages = {};
ViiKii.UI.Languages.CheckBox = {
	getLanguageTag: function(objectId, onclick, languageId, checked) {
		var tag = '';
		tag += "<div style=\"float:left;cursor:pointer;\" onclick=\""+onclick+"('"+objectId+"', '"+languageId+"')\">";
		if(checked) {
			tag += "<div style=\"float:left;\">";
			tag += "<img id='"+objectId+".language_"+languageId+"' src='/common/check18_on.gif'/>";
			tag += "</div>";
		} else {
			tag += "<div style=\"float:left;\">";
			tag += "<img id='"+objectId+".language_"+languageId+"' src='/common/check18_off.gif'/>";
			tag += "</div>";
		}
		tag += "<div class=\"default\" style=\"float:left;\">"+ViiKii.Languages.SelectBox.convertToName(languageId)+"</div>";
		tag += '</div>' 			
		return tag;
	},
	getLanguagesTag: function(objectId, onclick, languages, selectedIndex) {
		var tag = ''
		for(var i=0; i<languages.length; i++) {
			if(i != 0) {
				tag += '<div style="float:left;width:5px;height:18px;"></div>'
			}
			tag += ViiKii.UI.Languages.CheckBox.getLanguageTag(objectId, onclick, languages[i], i==selectedIndex);
		}
		return tag;
	}
};
ViiKii.UI.Folder = {
	toggle: function(folderId) {
		var content = $$("#"+folderId+" .folder_content")[0];
		var subTitle = $$("#"+folderId+" .sub_title")[0];
		var titleArrow = $$("#"+folderId+" .title_arrow")[0];
		if(Element.visible(content)) {
			titleArrow.src = "http://vkcommon.viikii.net/folder_arrow_close.gif";
			Element.hide(content);
			Element.show(subTitle);
		} else {
			titleArrow.src = "http://vkcommon.viikii.net/folder_arrow_open.gif";
			Element.hide(subTitle);
			Element.show(content);
		}
	},
	toggleSubs: function(folderId) {
		var subFolders = $$("#"+folderId+" .sub_folders")[0];
		if(!subFolders) return;
		var parentFolder = $$("#"+folderId+" .parent_folder")[0];
		if(parentFolder.hasClassName('folder_open_subs')) {
			parentFolder.removeClassName('folder_open_subs');
			parentFolder.addClassName('folder_close_subs');
			Element.hide(subFolders);
		} else if(parentFolder.hasClassName('folder_close_subs')) {
			parentFolder.removeClassName('folder_close_subs');
			parentFolder.addClassName('folder_open_subs');
			Element.show(subFolders);
		}
	}
};
ViiKii.UI.Popup = {
	create: function(popupId) {
		if(!$(popupId)) {
			var popup = document.createElement('div');
			popup.id = popupId;
			document.getElementsByTagName('body')[0].appendChild(popup);
			Element.hide(popupId);
		}
		return $(popupId);
	}
};ViiKii.UI.Drag = Class.create();
ViiKii.UI.Drag.prototype = {
	initialize: function(){
		this.select = $A(document.getElementsByTagName('select'));
		for (var i = 0, len = this.select.length; i < len; i++) {
			Element.hide(this.select[i]);
			this.create(i);
		}
	}
};

ViiKii.Board = {
	category: 'C',
	video_id: null,
	view_show: 0,
	view_sort: 'R',
	view_page: 1,
	channel_page: 1,
	
	initialize: function(video_id) {
		if (typeof video_id !== 'undefined') { this.video_id = video_id; }
		else { alert('Video Not Loaded!'); return; }
		
		this.list();
		ViiKii.Languages.attach(ViiKii.Board);
	},

	update: function() {
		this.list();
		//this.channels(this.video_id, this.channel_page);
	},

	attach: function(subject) {
		subject.attach(this);
	},
	
	list: function() {
		//if (!this.isvideo()) { return; }
		var url = '/boards/getlist/C/'+this.view_page+'/'+this.video_id+'/'+this.view_sort+'/'+this.view_show;
		var response = new Ajax.Updater('discussion_wrap', url, {evalScripts:true, onFailure:this.onError} );
	},
	
	sort: function(sort) {
		if (!this.isvideo()) { return; }
		this.view_page = 1;
		this.view_sort = sort;
		this.list();
	},
	
	show: function(category) {
		if (!this.isvideo()) { return; }
		this.view_page = 1;
		this.view_show = category;
		this.list();
	},
	
	clip: function(ele, user_name, id, from_user) {
		if (!this.isvideo() || !this.islogin()) { return; }
		if (user_name==from_user) { alert(''); return; }
		var response = new Ajax.Updater('target_list', '/boards/clip/'+[user_name,id,from_user].join('/'), {
							asynchronous: false,
							evalScripts: true,
							onFailure: function(transport) { alert(transport.responseText); }
						});
		var positions = Position.positionedOffset(ele);
		$('target_list').setStyle({display:'block',left:(positions[0]-210) + 'px',top:positions[1] + 'px'});
	},
	
	rate: function(thumb, id, cat) {
		if (!this.isvideo() || !this.islogin()) { return; }
		container = cat.toLowerCase() + '_rate_' + id;
		var response = new Ajax.Updater(container, '/boards/thumb/'+ cat +'/'+ id +'/'+ thumb, {evalScripts:true});
	},

	write: function() {
		if (!this.isvideo() || !this.islogin()) { return; }
		var response = new Ajax.Updater('write_wrap', '/boards/writebox/'+this.video_id, {evalScripts:true});
		Element.setStyle($('write_wrap'), {display:'block'});
	},
	
	post: function(id, cat, type, lang, subtitle_id) {
		if (!this.isvideo() || !this.islogin()) { return; }
		subtitle_id = (subtitle_id=='') ? 0: subtitle_id;
		var params = [this.video_id,id,cat,type,lang,subtitle_id,this.view_page].join('/');
		var response = new Ajax.Updater('postbox_'+id, '/boards/postbox/'+params, {evalScripts:true});
		Element.setStyle($('postbox_'+id), {display:'block'});
	},
	
	post_cancel: function(id) {
		$('postbox_'+id).innerHTML = '';
		Element.setStyle($('postbox_'+id), {display:'none'});
	},
	
	add: function(frm, rid, type) {
		if (!this.isvideo()) { return; }
		if ($('board_input_btn')) { $('board_input_btn').style.display='none'; }
				
		var notWhiteSpace = new RegExp(/[^\s]/);
		var quotation = new RegExp(/\'/g);
		var backSlash = new RegExp(/\\/g);
		var urlLink	= new RegExp(/(http|https|ftp|telnet|news):\/\/([a-z0-9_\-]+\.[][a-zA-Z0-9:;&#@=_~%\?\/\.\,\+\-]+)/g);

		if (type != 'T') {
			if (!notWhiteSpace.test(frm['data[content]'].value)) { alert('Type the comment please!!'); if ($('board_input_btn')) { $('board_input_btn').style.display='block'; }return; }
			if (backSlash.test(frm['data[content]'].value)) { frm['data[content]'].value = frm['data[content]'].value.replace(backSlash, "\\\\"); }
			if (quotation.test(frm['data[content]'].value)) { frm['data[content]'].value = frm['data[content]'].value.replace(quotation, "\\\'"); }
			if (urlLink.test(frm['data[content]'].value)) { frm['data[content]'].value = frm['data[content]'].value.replace(urlLink, "<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>"); }
		}
		else {
			if (!notWhiteSpace.test(frm['data[translate]'].value)) { alert('Type the comment please!!'); if ($('board_input_btn')) { $('board_input_btn').style.display='block'; }return; }
			if (backSlash.test(frm['data[translate]'].value)) { frm['data[translate]'].value = frm['data[translate]'].value.replace(backSlash, "\\\\"); }
			if (quotation.test(frm['data[translate]'].value)) { frm['data[translate]'].value = frm['data[translate]'].value.replace(quotation, "\\\'"); }
			if (urlLink.test(frm['data[translate]'].value)) { frm['data[translate]'].value = frm['data[translate]'].value.replace(urlLink, "<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>"); }
		}

		if (typeof type != 'undefined') { frm['data[content_type]'].value = type.toUpperCase(); }
		var url = '/boards/add/' + (typeof rid == 'undefined' ? '' : rid);
		var param = frm.serialize();
		var response = new Ajax.RequestXML( url, {
					asynchronous: false,
					parameters: param,
					onSuccess: this.onWrite,
					onFailure: this.onError
				});
		
		var response = response.responseValue.response;
		if ('ERROR' == response.result) {
			switch (response.error) {
			case 'NOT_PERMISSION':
				alert("You don't have permission");
				return;
			}
		}

		if (type == 'T' && rid && this.category == 'C') {
			var language_id = '';
			var ele = frm['data[language_id]'];
			var dequotation = new RegExp(/\\\'/g);
			if (ele.length) {
				for (i = 0; i < ele.length; i++) { if (ele[i].checked) { language_id = ele[i].value; } }
			}
			else {
				language_id = ele.value;
			}

			if (dequotation.test(frm['data[translate]'].value)) { frm['data[translate]'].value = frm['data[translate]'].value.replace(dequotation, "\'"); }
			var translate   = frm['data[translate]'].value;
			ViiKii.Video.Player.javaAddDiscussion(rid, language_id, translate);
			this.post_cancel(rid);
		}
	},

	showPost: function(id, cat, item) {
		var paras = $A($$('div._post'+id));
		paras.each(function(ele){ Element.setStyle(ele, {display:'none'}); });
		switch (cat) {
			case 'O' :
				Element.setStyle($('original_'+id), {display:'block'});
				break;
			case 'T':
				Element.setStyle($('translate_'+id+item), {display:'block'});
				break;
		}
	},

	goPage: function(page) {
		this.view_page = page;
		this.list();
	},
	
	inappropriate: function(ele, id, type) {
		if (!this.isvideo() || !this.islogin()) { return; }
		var position = Position.positionedOffset(ele);
		ViiKii.Inappro.init('C', id, position, type);	
	},

	deleteMessage: function(ele, id, type, depth) {
		if (!this.isvideo() || !this.islogin()) { return; }
		var position = Position.positionedOffset(ele);

		var str = '<div id="c_msg" style="">'
			 + '	<div style="width:300px; height:15px;"><img src="/common/close.gif" style="cursor:pointer;" border="0" align="right" onclick="ViiKii.Board.deleteCancel();"></div>'
			 + '	<div style="width:280px; height:15px; padding-left:20px; text-align:left;">Do you really want to delete this message?</div>'
			 + '	<div style="width:280px; height:15px;"></div>'
			 + '	<div style="width:300px; height:30px;">'
			 + '		<div style="float:left;height:30px;width:140px;margin:0 12 0 0;text-align:center;"><a href="javascript:ViiKii.Board.deleteYes('+ id +', \''+ type +'\', '+ depth +');">yes</a></div>'
			 + '		<div style="float:left;height:30px;width:140px;text-align:left;"><a href="javascript:ViiKii.Board.deleteCancel();">cancel</a></div>'
			 + '	</div>'
			 + '</div>'
			 + '';

		$('del_msg').innerHTML = str;
		Element.setStyle($('del_msg'), {left:position[0]-300+'px', top:position[1]+'px', border:'1px solid gray', display:'block'});
	},

	deleteYes: function(rid, type, depth) {
		if (!this.islogin()) { return; }
		var param = 'data[category]=C&data[page]='+ this.view_page +'&data[video_id]='+ this.video_id;
		var url = '/boards/delete/'+ (typeof rid == 'undefined' ? '' : rid) +'/'+ type;
		var response = new Ajax.Request( url, {
					asynchronous: false,
					parameters: param,
					//onSuccess: this.onDelete,
					onFailure: this.onError
				});

		if (depth == 0 && this.category == 'C') {
			cat = type == 'T' ? 'T' : 'O';
			ViiKii.Video.Player.javaDeleteDiscussion(rid, cat);
		}		
		this.deleteCancel();
		this.list();
	},

	deleteCancel: function() {
		Element.setStyle($('del_msg'), {display:'none'});
	},

	onWrite: function(trasnport) {
		$('write_wrap').hide();
		ViiKii.Board.list();
	},

	onError: function(trasnport) {
		alert(transport.responseText);
		ViiKii.Board.List();
	},
	
	onDelete: function(transport) {
		ViiKii.Board.List();
	},
/* Discussion */

/* Common */
	jumpto: function(videoPosition) {
		videoPosition -= 1000;
		videoPosition = videoPosition<0?0:videoPosition;
		ViiKii.Video.Player.setVideoPosition(videoPosition);
		var position = Position.positionedOffset($('ViiKii.Video.player'));
		window.scrollTo(0, position[1]);
	},
	
	anchor: function(id) { location.href = '#a' + id; },

	reload: function() { this.view_page=1; this.list(); },

	isvideo: function(callback) {
		var xml = new Ajax.Request('/videos/isvideo/'+this.video_id, {asynchronous: false});
		var rtn = xml.transport.responseText;
		if (!rtn) {
			//For Debug. yim.kwangjin 08.10.09
			alert("Debug-viikiiBoard");
			alert('video_id:' + this.video_id);
			alert('return:' + rtn);
			setTimeout(function(){alert("Sorry!\nThis video was deleted while you are watching it."); document.location='/';}, 100);
			return false;
		}
		else {
			return true;
		}
	},

	islogin: function() {
		if (ViiKii.Util.getDomainCookie('username') !== null) {
			return true;
		}
		else {
			ViiKii.Login.popUp();
			return false;
		}
	},
	
	test: function() {}
/* Common */
};
ViiKii.Channel = {};
ViiKii.Channel.Subscribe = {
	isSubscribed :false,
	isLogin : function() {
		return ViiKii.Util.getDomainCookie('username') != null;
	},
	showList : function(channelId, page) {
		document.location = '#SUBSCRIBERS';
		new Ajax.Updater(
			"page_content",
			'/channels/subscribe_list/' + channelId + '/' + page,
			{
				evalScripts :true
			}
		);
	},
	toggleSubscribe : function(channelId) {
		if (!this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}
		this.changeButton(!this.isSubscribed);

		var subscribe = this.isSubscribed ? "T" : "F";
		var xml = new Ajax.RequestXML('/channels/subscribe/' + channelId + '/'
				+ subscribe, {
			asynchronous :false,
			method :'get'
		});
		this.onSuccessSubscribe(xml);
	},
	changeButton : function(subscribe) {
		this.isSubscribed = subscribe;
		if (this.isSubscribed) {
			$('ViiKii.Channel.Subscribe.subscribeText').innerHTML = "Unsubscribe";
			alert("Subscribed successfully!\nNow, you are able to follow this channel's updates.");
		} else {
			$('ViiKii.Channel.Subscribe.subscribeText').innerHTML = "Subscribe";
			alert("Unsubscribed !");
		}
	},
	onSuccessSubscribe : function(xml) {
		var response = xml.responseValue.response;
		if ('SUCCESS' == response.result) {
			return;
		}
		switch (response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		}
	}
};
ViiKii.Channel.Intro = {
	objectId: 'ViiKii.Channel.Intro',
	showLanguage: function(languageId) {
		new Ajax.Updater(
			'ViiKii.Channel.Intro.layer',
			'/channel_intros/intro/'+ViiKii.Util.get(this, 'channelId')+'/'+languageId,
			{ evalScripts: true }
		)
	},
	refresh: function() {
		new Ajax.Updater(
			'ViiKii.Channel.Intro.layer',
			'/channel_intros/intro/'+ViiKii.Util.get(this, 'channelId'),
			{ evalScripts: true }
		)
	},
	edit: function(languageId) {
		new Ajax.Updater(
			'ViiKii.Channel.Intro.layer',
			'/channel_intros/edit/'+ViiKii.Util.get(this, 'channelId')+'/'+languageId,
			{ evalScripts: true }
		)
	},
	discard: function() {
		this.refresh();
	},
	save: function() {
		alert('save intro');
		this.refresh();
	}
};
ViiKii.Channel.FeaturedChannel = {
	layerName :'ViiKii.Channel.FeaturedChannel.layer',
	loadPage : function(page) {
		var response = new Ajax.Updater(this.layerName,
				'/featured_channels/simple/' + page, {
					method :'get'
				});
	},
	update : function() {
		this.loadPage(1);
	}
};
ViiKii.Channel.FeaturedChannel.Manage = {
	editFeaturedList : function(languageId) {
		var params =	$H({
							featured_channels :$('ViiKii.Channel.FeatureChannel.Manage.featuredChannels').value
						}).toQueryString();

		var response = new Ajax.Updater(
			'ViiKii.Channel.FeaturedChannel.Manage.featured',
			'/featureds/manage_edit_featureds/' + languageId,
			{
				asynchronous :true,
				parameters :params,
				evalScripts :true
			}
		);
	},
	cancelEditFeaturedList : function(languageId) {
		new Ajax.Updater(
			'ViiKii.Channel.FeaturedChannel.Manage.featured',
			'/featureds/manage_featureds/' + languageId, {
				asynchronous :true,
				evalScripts :true
			}
		);
	}
};
ViiKii.Channel.PartnerBlogs = {
	isLock :false,
	refresh : function(channelId) {
		if ($('ViiKii.Channel.PartnerBlogs.layer')) {
			var response = new Ajax.Updater(
					'ViiKii.Channel.PartnerBlogs.layer',
					'/channels/partner_blogs/' + channelId, {
						method :'get'
					});
		}
	},
	edit : function(channelId) {
		document.location = '/manage_channels/init/' + channelId;
	},
	toggleLock : function(channelId) {
		this.lockButton(!this.isLock);

		var lock = this.isLock ? 1 : 0;
		var data = new Ajax.RequestXML('/channels/partner_blogs_lock/'
				+ channelId + '/' + lock, {
			asynchronous :false,
			method :'get'
		});
		this.onSuccessLockMirrored(data);
	},
	lockButton : function(lock) {
		this.isLock = lock;
		if (this.isLock) {
			$('ViiKii.Channel.PartnerBlogs.lockImage').src = '/common/private.gif';
		} else {
			$('ViiKii.Channel.PartnerBlogs.lockImage').src = '/common/private_open.gif';
		}
	},
	onSuccessLockMirrored : function(data) {
		var response = data.responseValue.response;
		if ('SUCCESS' == response.result) {
			return;
		}

		switch (response.error) {
		case 'NOT_OWNER':
			alert("You are not the channel owner.");
			break;
		}
	}
};
ViiKii.Channel.PartnerBlogs.Popup = {
	layerName :'ViiKii.Channel.PartnerBlogs.Popup.layer',
	popupUrl :'/channels/partner_popup/',
	channelId :7,
	isLogin : function() {
		return ViiKii.Util.getDomainCookie('username') != null;
	},
	add : function(channelId) {
		if (!this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}
		var partner_url = $('ViiKii.Channel.PartnerBlogs.Popup.url').value;
		var partner_name = $('ViiKii.Channel.PartnerBlogs.Popup.name').value;
		var message = $('ViiKii.Channel.PartnerBlogs.Popup.message').value;

		if (partner_url.trim() == '') {
			alert('Insert available url first.');
			return;
		}
		if (partner_url.indexOf(".") == -1) {
			alert('Insert available url first.');
			return;
		}
		if (partner_name.trim() == '') {
			alert('Insert available link name first.');
			return;
		}

		var params = $H( {
			channel_id :channelId,
			partner_url :partner_url,
			partner_name :partner_name,
			message :message
		}).toQueryString();

		var ajax = new Ajax.RequestXML('/channels/add_partner/', {
			asynchronous :false,
			parameters :params
		});
		this.onAddPartnerSuccess(ajax);
	},
	onAddPartnerSuccess : function(ajax) {
		//alert(ajax.transport.responseText);

		var response = ajax.responseValue.response;
		if (response.result == 'SUCCESS') {
			this.close();
			ViiKii.Channel.PartnerBlogs.refresh(this.channelId);
			return;
		}
		switch (response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'EMPTY_DATA':
			alert('Insert available url and link name first.');
			break;
		case 'INVALID_URL':
		case 'EMPTY_URL':
			alert('Insert available url first.');
			return;
		case 'EMPTY_NAME':
			alert('Insert available link name first.');
			return;
		case 'DB_ERROR':
			alert("Fail to add partner blog");
		}
	},
	open : function(channelId) {
		this.channelId = channelId;
	
		var url = this.popupUrl + channelId;
		var response = new Ajax.Request(url, {
			asynchronous :true,
			evalScripts :true,
			onSuccess :this.onCompletePopUp.bind(this),
			onFailure :this.onErrorPopUp.bind(this)
		});
	},
	onCompletePopUp : function(transport) {
		var posLeft = (document.body.scrollWidth - 618) / 2;
		var posTop = Position.realOffset(document.body)[1] + 150;
	
		var layerName = this.layerName;
		if ($(layerName)) {
			$(layerName).innerHTML = transport.responseText.stripScripts();
			$(layerName).style.display = 'block';
		} else {
			var e = document.createElement('div');
			e.id = layerName;
			var styles = {
				position :'absolute',
				top :posTop + 'px',
				left :posLeft + 'px',
				width :'400px',
				height :'305px',
				backgroundColor :'#FFFFFF'
			};
			Element.setStyle(e, styles);
			e.innerHTML = transport.responseText.stripScripts();
			document.getElementsByTagName('body')[0].appendChild(e);
		}
		ViiKii.UI.Round.init(layerName, {
			corners :'all',
			borderSize :1
		});
		setTimeout( function() {
			transport.responseText.evalScripts();
		}.bind(this), 0);
	},
	onErrorPopUp : function() {
		alert("fail to open popup");
	},
	close : function() {
		$(this.layerName).style.display = 'none';
	}
};
ViiKii.Channel.Comment = {
	objectId: 'ViiKii.Channel.Comment',
	clickInput : function(inputId) {
		if (!this.isModified(inputId)) {
			$(inputId).setAttribute('modified', 'T');
			$(inputId).value = '';
		}
	},
	showLanguage: function(languageId) {
		ViiKii.Util.set(this, 'languageId', languageId);
		this.refreshComments(ViiKii.Util.get(this, 'channelId'), 1);
	},
	isModified : function(inputId) {
		if ($(inputId).getAttribute('modified') == 'T') {
			return true;
		}
		return false;
	},
	isLogin : function() {
		return ViiKii.Util.getDomainCookie('username') != null;
	},
	inappropriate : function(commentId, ele) {
		ViiKii.Inappro.popup('C', commentId, ele);
	},
	showList : function(page, channelId) {
		this.refreshComments(channelId, page);
	},
	del : function(commentId, channelId, curPage) {
		if (!this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}
		if (!confirm('Are you sure to delete this comment?')) {
			return;
		}
		var xml = new Ajax.RequestXML(
				'/channel_comments/delete_comment/' + commentId, {
					asynchronous :false,
					method :'get'
				});
		this.onDeleteCommentSuccess(xml, channelId, curPage);
	},
	onDeleteCommentSuccess : function(xml, channelId, curPage) {
		//alert(xml.transport.responseText);
		var response = xml.responseValue.response;
		if (response.result == 'SUCCESS') {
			this.refreshComments(channelId, curPage);
			return;
		}
		switch (response.error) {
		case 'NOT_OWNER':
			alert('You are not the discussion owner');
			break;
		case 'INVALID_COMMENT':
			alert('This comment is deleted.');
			this.refreshComments(channelId, curPage);
			return;
		}
	},
	reply : function(commentId) {
		$("reply_" + commentId).style.display = 'block';
	},
	addReply : function(commentId, channelId, curPage, isLastReply) {
		this.addComment(channelId, 'input_' + commentId, commentId, curPage,
				isLastReply);
	},
	cancelReply : function(commentId) {
		$("reply_" + commentId).style.display = 'none';
		this.cancelInput("input_" + commentId);
	},
	refreshComments : function(channelId, page) {
		new Ajax.Updater(
			'ViiKii.Channel.Comment.layer',
			'/channel_comments/comments/'+channelId+'/'+ViiKii.Util.get(this, 'languageId')+'/'+page,
			{ evalScripts: true }
		);
	},
	addInput : function(channelId) {
		this.addComment(channelId, 'input_new', 0, 1, false);
	},
	addComment : function(channelId, inputId, refferId, curPage, isLastReply) {
		var text = $(inputId).value;
		if (!this.isModified(inputId) || text.trim() == '') {
			alert('Insert available discussion first.');
			return;
		}

		var params = $H( {
			channel_id	: ViiKii.Util.get(this, 'channelId'),
			content		: text,
			reffer		: refferId,
			language_id	: ViiKii.Util.get(this, 'languageId')
		}).toQueryString();

		var xml = new Ajax.RequestXML('/channel_comments/add_comment/', {
			asynchronous :false,
			parameters :params
		});
		if (isLastReply) {
			curPage++;
		}
		this.onAddCommentSuccess(xml, channelId, curPage);
	},
	onAddCommentSuccess : function(xml, channelId, curPage) {
		// alert(xml.transport.responseText);
		var response = xml.responseValue.response;
		if (response.result == 'SUCCESS') {
			this.refreshComments(channelId, curPage);
			return;
		}
		switch (response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'EMPTY_DATA':
		case 'EMPTY_COMMENT':
			alert('Invalid input discussion.');
			break;
		case 'INVALID_CHANNEL':
			alert('Channel is deleted');
			break;
		case 'UNKNOWN_REFFER':
			alert('Unknown parent discussion.');
			break;
		case 'TOO_MUCH_DEPTH':
			alert('Too much depth in the discussion.');
			break;
		case 'DB_ERROR':
			alert('Fail to add discussion with unknown error.');
			break;
		case 'NOT_PERMISSION':
			alert("You don't have permission");
			break;
		}
	},
	cancelInput : function(inputId) {
		$(inputId).setAttribute('modified', 'F');
		$(inputId).value = "Leave your comment here.";
	}
};
ViiKii.Channel.UploadPopup = {
	layerName :'ViiKii.Channel.UploadPopup.layer',
	popupUrl :'/channels/upload_popup/',
	type :'CHANNEL_THUMB',
	channelId :7,
	open : function(channelId, type) {
		this.type = type;
		this.channelId = channelId;

		var url = this.popupUrl + channelId;
		var response = new Ajax.Request(url, {
			asynchronous :true,
			evalScripts :true,
			onSuccess :this.onCompletePopUp.bind(this),
			onFailure :this.onErrorPopUp
		});
	},
	updateFlash : function(uploadUrl) {
		var flashTag = '';
		var src = '/viewer/image_uploader_090116.swf?';
		src += 'url=' + uploadUrl;
		src += '&type=' + this.type;
		src += '&user_name=' + ViiKii.Util.getDomainCookie('username');
		if (this.type == 'CHANNEL_THUMB') {
			src += '&message=*.jpg square image under 1MB only.<br>A 72 X 72 size image would be the best.';
		}
		src += '&channel_id=' + this.channelId;
		src += '&success_callback=ViiKii.Channel.UploadPopup.onSuccess';
		src += '&cancel_callback=ViiKii.Channel.UploadPopup.onCancel';

		if (Prototype.Browser.IE) {
			flashTag += '<object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" width="295" height="144" id="ViiKii_Upload_flash" align="middle">';
			flashTag += '<param name="allowScriptAccess" value="sameDomain" />';
			flashTag += '<param name="allowFullScreen" value="false" />';
			flashTag += '<param name="movie" value="' + src + '" />';
			flashTag += '<param name="quality" value="high" />';
			flashTag += '<param name="bgcolor" value="#ffffff" />';
			flashTag += '</object>';
		} else {
			flashTag += '<embed id="ViiKii_Upload_flash" ';
			flashTag += 'src="' + src + '" quality="high" ';
			flashTag += 'bgcolor="#ffffff" width="295" ';
			flashTag += 'height="144" name="ViiKii_Upload_flash" ';
			flashTag += 'align="middle" allowScriptAccess="sameDomain" ';
			flashTag += 'allowFullScreen="false" ';
			flashTag += 'type="application/x-shockwave-flash" ';
			flashTag += 'pluginspage="http://www.macromedia.com/go/getflashplayer" />';
		}
		$('ViiKii.Channel.Upload.container').innerHTML = flashTag;
	},
	onCompletePopUp : function(transport) {
		var posLeft = (document.body.scrollWidth - 618) / 2;
		var posTop = Position.realOffset(document.body)[1] + 150;

		var layerName = ViiKii.Channel.UploadPopup.layerName;
		if ($(layerName)) {
			$(layerName).innerHTML = transport.responseText.stripScripts();
			$(layerName).style.display = 'block';
		} else {
			var e = document.createElement('div');
			e.id = layerName;
			var styles = {
				position :'absolute',
				top :posTop + 'px',
				left :posLeft + 'px',
				width :'345px',
				height :'193px',
				backgroundColor :'#FFFFFF'
			};
			Element.setStyle(e, styles);
			e.innerHTML = transport.responseText.stripScripts();
			document.getElementsByTagName('body')[0].appendChild(e);
		}
		ViiKii.UI.Round.init(layerName, {
			corners :'all',
			borderSize :1
		});
		setTimeout( function() {
			transport.responseText.evalScripts();
		}.bind(this), 10);
	},
	onErrorPopUp : function() {
		alert("fail to open popup");
	},
	onSuccess : function(xml) {
		//alert(xml);
		ViiKii.Channel.UploadPopup.close();
		switch (ViiKii.Channel.UploadPopup.type) {
		case 'CHANNEL_THUMB':
			setTimeout(this.updateThumbImage, 0);
			break;
		}
		setTimeout( function() {
			alert('Uploaded!');
		}, 0);
	},
	updateThumbImage : function() {
		var imageTag = "<img ";
		imageTag += "src=\"/img/channel/"
				+ ViiKii.Channel.VideoList.channelName + ".jpg?"
				+ (new Date()).getTime() + "\" ";
		imageTag += "onerror=\"this.src='/img/channel/noimage.gif'\" ";
		imageTag += "style=\"border:none;width:72px;height:72px;\">";
		$('ViiKii.Channel.VideoList.channelImage').innerHTML = imageTag;

		var mirrorChannelName = "mirror_thumb_"
				+ ViiKii.Channel.UploadPopup.channelId;
		if ($(mirrorChannelName)) {
			$(mirrorChannelName).innerHTML = imageTag;
		}
	},
	onCancel : function() {
		ViiKii.Channel.UploadPopup.close();
	},
	close : function() {
		$(ViiKii.Channel.UploadPopup.layerName).style.display = 'none';
	}
};
ViiKii.Channel.Contributors = {
	objectId: 'ViiKii.Channel.Contributors',
	loadPage : function(curPage) {
		ViiKii.Util.set(this, 'curPage', curPage);
		this.refresh();
	},
	refresh: function() {
		new Ajax.Updater(
			'ViiKii.Channel.Contributors.layer',
			'/channels/contributors/'+ViiKii.Util.get(this, 'channelId')+'/'+ViiKii.Util.get(this, 'curPage'),
			{ evalScripts: true }
		);
	}
};
ViiKii.Channel.RelatedChannel = {
	objectId: 'ViiKii.Channel.RelatedChannel',
	loadPage : function(curPage) {
		ViiKii.Util.set(this, 'curPage', curPage);
		this.refresh();
	},
	refresh: function() {
		new Ajax.Updater(
			'ViiKii.Channel.RelatedChannel.content',
			'/channels/related_channels/'+ViiKii.Util.get(this, 'channelId')+'/'+ViiKii.Util.get(this, 'curPage'),
			{ evalScripts: true }
		);
	}
};
ViiKii.Channel.ManageForm = {
	objectId: 'ViiKii.Channel.ManageForm',
	channelId: 0,
	languageId: 'en',
	backToChannel : function(channelName) {
		document.location = '/channels/goto/' + channelName;
	},
	editVideoUrls : function(channelId) {
		var params = $H( {
			video_urls :$('ViiKii.Channel.ManageForm.videoUrls').value
		}).toQueryString();

		var response = new Ajax.Request(
				'/manage_channels/edit_video_urls/' + channelId,
				{
					asynchronous :true,
					parameters :params,
					onSuccess : function(transport) {
						$('ViiKii.Channel.ManageForm.videoUrls').value = transport.responseText;
					},
					onFailure : function() {
						alert('Sorry. Fail to edit video urls.');
					}
				});
	},
	cancelEditVideoUrls : function(channelId) {
		var response = new Ajax.Request(
				'/manage_channels/video_urls/' + channelId,
				{
					asynchronous :true,
					onSuccess : function(transport) {
						$('ViiKii.Channel.ManageForm.videoUrls').value = transport.responseText;
					}
				});
	},
	editRelatedChannels : function(channelId) {
		var params = $H(
				{
					related_channels :$('ViiKii.Channel.ManageForm.relatedChannels').value
				}).toQueryString();

		var response = new Ajax.Request(
				'/manage_channels/edit_related_channels/' + channelId,
				{
					asynchronous :true,
					parameters :params,
					onSuccess : function(transport) {
						$('ViiKii.Channel.ManageForm.relatedChannels').value = transport.responseText;
					},
					onFailure : function() {
						alert('Sorry. Fail to edit related channels.');
					}
				});
	},
	cancelEditRelatedChannels : function(channelId) {
		var response = new Ajax.Request(
				'/manage_channels/related_channel_urls/' + channelId,
				{
					asynchronous :true,
					onSuccess : function(transport) {
						$('ViiKii.Channel.ManageForm.relatedChannels').value = transport.responseText;
					}
				});
	},
	changePartnerOrder : function(partnerId, channelId, type) {
		var xml = new Ajax.RequestXML('/manage_channels/change_partner_order/'
				+ channelId + "/" + partnerId + "/" + type, {
			method :'get'
		});
		this.onChangePartnerOrderSuccess(xml, channelId);
	},
	onChangePartnerOrderSuccess : function(xml, channelId) {
		// alert(xml.transport.responseText);

		var response = xml.responseValue.response;
		if (response.result == 'SUCCESS') {
			this.refreshPartner(channelId);
			return;
		}
		switch (response.error) {
		case 'NOT_OWNER':
			alert("You are not the channel owner.");
			return;
		case 'INVALID_PARTNER':
			this.refreshPartner(channelId);
			break;
		case 'DB_ERROR':
			alert("Fail to change the order of partner blogs");
			break;
		}
	},
	deletePartner : function(partnerId, channelId) {
		if (!confirm('Do you really want to delete this partner blog?')) {
			return;
		}
		var xml = new Ajax.RequestXML('/manage_channels/delete_partner/'
				+ channelId + "/" + partnerId, {
			method :'get'
		});
		this.onDeletePartnerSuccess(xml, channelId);
	},
	onDeletePartnerSuccess : function(xml, channelId) {
		// alert(xml.transport.responseText);
		var response = xml.responseValue.response;
		if (response.result == 'SUCCESS') {
			this.refreshPartner(channelId);
			return;
		}
		switch (response.error) {
		case 'NOT_OWNER':
			alert("You are not the channel owner.");
			return;
		case 'INVALID_PARTNER':
			this.refreshPartner(channelId);
			break;
		case 'DB_ERROR':
			alert("Fail to delete partner blog");
			break;
		}
	},
	refreshPartner : function(channelId) {
		new Ajax.Updater(
			'ViiKii.Channel.ManageForm.partnersLayer',
			'/manage_channels/partners/' + channelId,
			{
				evalScripts :true
			}
		);
	},
	editDetails: function() {
		var countryComboBox = $('ViiKii.Channel.ManageForm.country');
		var country =  countryComboBox.options[countryComboBox.selectedIndex].value;
		
		var genreComboBox = $('ViiKii.Channel.ManageForm.genre');
		var genre =  genreComboBox.options[genreComboBox.selectedIndex].value;
		
		var params = $H({
			'country'				: country,
			'genre'					: genre
		}).toQueryString();
		
		new Ajax.Request(
			'/manage_channels/edit_details/'+ViiKii.Util.get(this, 'channelId'),
			{
				parameters: params,
				onComplete: this.onEditDetails.bind(this)
			}
		);
	},
	onEditDetails: function(transport, response) {
		//alert(transport.responseText);
		if (response.result == 'SUCCESS') {
			alert('Saved successfully');
			return;
		}
		switch (response.error) {
		case 'INVALID_CHANNEL':
			alert('This channel is deleted');
			document.location = '/channels';
			return;
		case 'NOT_OWNER':
			alert('You are not the owner of this channel');
			document.location = '/channels/goto/'+response.url;
			break;
		case 'EMPTY_COUNTRY':
			alert('Select country first');
			break;
		case 'DB_ERROR':
			alert("Fail to edit details. Please try again.");
			break;
		}
	},
	cancelEditDetails: function() {
		new Ajax.Updater(
			'ViiKii.Channel.ManageForm.detailsLayer',
			'/manage_channels/details/'+ViiKii.Util.get(this, 'channelId'),
			{
				evalScripts :true
			}
		)
	},
	saveSegmenters: function(channelId) {
		params = $H({'channel_id': channelId, 'segmenters': $('segmenters_textarea').value.trim()}).toQueryString();
		new Ajax.Request('/manage_channels/save_segmenters/' + channelId, {
			parameters: params,
			onComplete: function(transport, response) {
				if ('success' == response.result) {
					alert('saved');
					document.location = '/manage_channels/init/' + response.channelId;
				} else {
					alert(response.error);
				}
			}
		});
	},
	saveAbusers: function(channelId) {
		params = $H({'channel_id': channelId, 'abusers': $('abusers_textarea').value.trim()}).toQueryString();
		new Ajax.Request('/manage_channels/save_abusers/' + channelId, {
			parameters: params,
			onComplete: function(transport, response) {
				if ('success' == response.result) {
					alert('saved');
					document.location = '/manage_channels/init/' + response.channelId;
				} else {
					alert(response.error);
				}
			}
		});
	}
};
ViiKii.Channel.AddForm = {
	nameLanguage: 'en',
	descriptionLanguage: 'en',
	tagsLanguage: 'en',
	save : function() {
		var name = trim($('ViiKii.Channel.AddForm.name').value);
		if (name == '') {
			alert('Insert available channel name first');
			return;
		}
		var url = trim($('ViiKii.Channel.AddForm.url').value);
		if (url == '') {
			alert('Insert available channel url first');
			return;
		}
		if(!url.isAlnum()) {
			alert('You can use only numbers and letters for channel url!');
			return;
		}
		var countryComboBox = $('ViiKii.Channel.AddForm.country');
		var country =  countryComboBox.options[countryComboBox.selectedIndex].value;
		
		var genreComboBox = $('ViiKii.Channel.AddForm.genre');
		var genre =  genreComboBox.options[genreComboBox.selectedIndex].value;
		
		if(country == '0') {
			alert('Select country first');
			return;
		}
		var description = $('ViiKii.Channel.AddForm.description').value;
		var tags = $('ViiKii.Channel.AddForm.tags').value;
		var videos = $('ViiKii.Channel.AddForm.videos').value;
		var relatedChannels = $('ViiKii.Channel.AddForm.relatedChannels').value;
		
		var params = $H({
			'name'						: name,
			'name_language'				: this.nameLanguage,
			'url'						: url,
			'description'				: description,
			'description_language'		: this.descriptionLanguage,
			'tags'						: tags,
			'tags_language'				: this.tagsLanguage,
			'videos'					: videos,
			'related_channels'			: relatedChannels,
			'country'					: country,
			'genre'						: genre
		}).toQueryString();
		new Ajax.Request(
			'/channels/add',
			{
				parameters: params,
				onComplete: this.onSave.bind(this)
			}
		);
	},
	onSave: function(transport, response) {
		//alert(transport.responseText);
		if (response.result == 'SUCCESS') {
			document.location = '/channels/goto/' + response.url;
			return;
		}
		switch (response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'EMPTY_NAME':
			alert('Insert available channel name first!');
			break;
		case 'EMPTY_URL':
			alert('Insert available channel url first')
		case 'DUP_URL':
			alert('The url is already used by other channel.\nPlease use different url.');
			break;
		case 'EMPTY_COUNTRY':
			alert('Select country first');
			break;
		case 'DB_ERROR':
			alert("Fail to create a channel. Please try again.");
			break;
		}
	},
	cancel : function() {
		document.location = '/channels/';
	},
	showNameLanguage: function() {
		var languages = ViiKii.Languages.getActiveInterestedLanguageCodes();
		var languageTag = ViiKii.UI.Languages.CheckBox.getLanguagesTag('ViiKii.Channel.AddForm.name_language', 'ViiKii.Channel.AddForm.onNameLanguage', languages, 0);
		$('ViiKii.Channel.AddForm.nameLanguages').innerHTML = languageTag;
	},
	onNameLanguage: function(objectId, languageId) {
		this.nameLanguage = languageId;
		Element.hide('ViiKii.Channel.AddForm.nameLanguages');
		$('ViiKii.Channel.AddForm.name').removeAttribute("readOnly");
		$('ViiKii.Channel.AddForm.name').focus();
	},
	showDescriptionLanguage: function() {
		var languages = ViiKii.Languages.getActiveInterestedLanguageCodes();
		var languageTag = ViiKii.UI.Languages.CheckBox.getLanguagesTag('ViiKii.Channel.AddForm.description_language', 'ViiKii.Channel.AddForm.onDescriptionLanguage', languages, 0);
		$('ViiKii.Channel.AddForm.descriptionLanguages').innerHTML = languageTag;
	},
	onDescriptionLanguage: function(objectId, languageId) {
		this.descriptionLanguage = languageId;
		Element.hide('ViiKii.Channel.AddForm.descriptionLanguages');
		$('ViiKii.Channel.AddForm.description').removeAttribute("readOnly");
		$('ViiKii.Channel.AddForm.description').focus();
	},
	showTagsLanguage: function() {
		var languages = ViiKii.Languages.getActiveInterestedLanguageCodes();
		var languageTag = ViiKii.UI.Languages.CheckBox.getLanguagesTag('ViiKii.Channel.AddForm.tags_language', 'ViiKii.Channel.AddForm.onTagsLanguage', languages, 0);
		$('ViiKii.Channel.AddForm.tagsLanguages').innerHTML = languageTag;
	},
	onTagsLanguage: function(objectId, languageId) {
		this.tagsLanguage = languageId;
		Element.hide('ViiKii.Channel.AddForm.tagsLanguages');
		$('ViiKii.Channel.AddForm.tags').removeAttribute("readOnly");
		$('ViiKii.Channel.AddForm.tags').focus();
	},
	checkUrl: function() {
		var params = $H({
			'url': $('ViiKii.Channel.AddForm.url').value
		}).toQueryString();
		new Ajax.Request(
			'/channels/is_valid_url/',
			{
				parameters: params,
				onComplete: this.onCheckUrl.bind(this)
			}
		);
	},
	onCheckUrl: function(transport, response) {
		//alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			this.hideAlt();
			return;
		}
		switch(response.error) {
		case 'EMPTY_URL':
			this.showAlt('ViiKii.Channel.AddForm.url', 'Insert available url first.');
			break;
		case 'INVALID_URL':
			this.showAlt('ViiKii.Channel.AddForm.url', 'Numbers and alphabets only.');
			break;
		case 'DUP_URL':
			this.showAlt('ViiKii.Channel.AddForm.url', 'Unavailable url!');
			break;
		}
	},
	showAlt: function(id, message) {
		var position = Position.cumulativeOffset($(id));
		this.alt.alt(position[0]+100, position[1]-26, message);
	},
	hideAlt: function() {
		this.alt.hidden();
	}
};
ViiKii.Channel.VideoList = {
	channelName :'',
	isSelectAll: true,
	videos: {},
	name: 'ViiKii.Channel.VideoList',
	view: 'full',
	channelId: 1,
	curFolder: 'all',
	curPage: 1,
	videosPerPage: 5,
	init: function(channelId, folder, curPage, videosPerPage, view) {
		this.channelId = channelId;
		this.curFolder = folder;
		this.curPage = curPage;
		this.videos = {};
		this.isSelectAll = true;
		this.videosPerPage = videosPerPage;
		this.view = view;
	},
	setView: function(view) {
		new Ajax.Request(
			'/channels/change_view/'+view,
			{
				onComplete: this.onSetView.bind(this)
			}
		)
	},
	onSetView: function(transport) {
		this.showList(1);
	},
	addVideo: function(videoId) {
		this.videos[videoId] = false;
	},
	check: function(videoId) {
		this.changeCheck(videoId, !this.videos[videoId]);
	},
	checkAll: function() {
		for(var video in this.videos) {
			if(this.videos[video] != this.isSelectAll) {
				this.changeCheck(video, this.isSelectAll);
			}
		}
		this.changeCheckAll(!this.isSelectAll);
	},
	changeCheckAll: function(checked) {
		this.isSelectAll = checked;
		this.changeCheckImage(this.name+".checkAll", !checked);
		if(checked) {
			$(this.name+".checkAllText").innerHTML = "Select All";
		} else {
			$(this.name+".checkAllText").innerHTML = "Unselect All";
		}
	},
	changeCheck: function(videoId, checked) {
		this.videos[videoId] = checked;
		this.changeCheckImage(this.name+'.checkbox_'+videoId, checked);
	},
	changeCheckImage: function(id, checked) {
		var src = "";
		if(checked) {
			src = "/common/checkbox_ch.gif";
		} else {
			src = "/common/checkbox_wh.gif";
		}
		$(id).src = src;
	},
	getVideos: function() {
		var result = [];
		for(var video in this.videos) {
			if(this.videos[video]) {
				result.push(video);
			}
		}
		return result;
	},
	del: function(channelId, folder) {
		if(!this.videoSelected()) {
			alert("Select available videos first.");
			return;
		}
		if (!confirm('Do you really want to delete the videos from this channel?')) {
			return;
		}
		var params = $H(
			{
				'videos': this.getVideos().join(",")
			}
		).toQueryString();
		var ajax = new Ajax.RequestXML(
			'/channels/delete_videos/'+channelId,
			{
				parameters: params,
				asynchronous: false
			}
		);
		this.onSuccessDelete(ajax, channelId, folder);
	},
	onSuccessDelete: function(ajax, channelId, folder) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.showList(1, channelId);
			ViiKii.Channel.Folder.refresh(channelId);
			return;
		}
		switch(response.error) {
		case 'INVALID_CHANNEL':
			alert("This channel is deleted");
			document.location = '/channels';
			return;
		case 'NOT_OWNER':
			alert("You are not the owner of this channel");
			return;
		case 'INVALID_INPUT':
			alert("Select available videos first!");
			return;
		case 'MIRRORED_CHANNEL':
			alert("You cannot delete videos on mirrored channels");
			return;
		}
	},
	deleteSuggestion: function(channelId, folder) {
		if(!this.videoSelected()) {
			alert("Select available videos first.");
			return;
		}
		if (!confirm('Do you really want to delete the suggestions from this channel?')) {
			return;
		}
		var params = $H(
			{
				'videos': this.getVideos().join(",")
			}
		).toQueryString();
		var ajax = new Ajax.RequestXML(
			'/channels/delete_suggestions/'+channelId,
			{
				parameters: params,
				asynchronous: false
			}
		);
		this.onDeleteSuggestions(ajax, channelId, folder);
	},
	onDeleteSuggestions: function(ajax, channelId, folder) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.showList(1, channelId);
			ViiKii.Channel.Folder.refresh(channelId);
			return;
		}
		switch(response.error) {
		case 'INVALID_CHANNEL':
			alert("This channel is deleted");
			document.location = '/channels';
			return;
		case 'INVALID_INPUT':
			alert("Select available videos first!");
			return;
		case 'NOT_YOURS':
			alert("You can remove only your suggestions.");
			this.showList(1, channelId);
			ViiKii.Channel.Folder.refresh(channelId);
			return;
		}
	},
	remove: function(channelId, folder) {
		if(!this.videoSelected()) {
			alert("Select available videos first.");
			return;
		}
		if (!confirm('Do you really want to remove the videos from this folder?')) {
			return;
		}
		var params = $H(
			{
				'videos': this.getVideos().join(",")
			}
		).toQueryString();
		var ajax = new Ajax.RequestXML(
			'/channels/remove_videos/'+channelId+'/'+folder,
			{
				parameters: params,
				asynchronous: false
			}
		);
		this.onSuccessDelete(ajax, channelId, folder);
	},
	onSuccessRemove: function(ajax, channelId, folder) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.showList(1, channelId);
			ViiKii.Channel.Folder.refresh(channelId);
			return;
		}
		switch(response.error) {
		case 'INVALID_CHANNEL':
			alert("This channel is deleted");
			document.location = '/channels';
			return;
		case 'NOT_OWNER':
			alert("You are not the owner of this channel");
			return;
		case 'INVALID_INPUT':
			alert("Select available videos first!");
			return;
		}
	},
	videoSelected: function() {
		return this.getVideos().length > 0; 
	},
	gotoManageChannel : function(channelId) {
		document.location = '/manage_channels/init/' + channelId;
	},
	loadPage: function(curPage) {
		this.showList(curPage, $('channel_id').value, $('video_folder').value, $('video_per_page').value);
	},
	showList : function(pageNum, channelId, folder, videosPerPage) {
		if(pageNum == null) {
			pageNum = this.curPage;
		}
		if(folder == null) {
			folder = this.curFolder;
		}
		if(channelId == null) {
			channelId = this.channelId;
		}
		if(videosPerPage == null) {
			videosPerPage = this.videosPerPage;
		}
		new Ajax.Updater(
			'VideoList',
			'/channels/videos/'+channelId+'/'+videosPerPage+'/'+pageNum+'/'+folder,
			{
				evalScripts :true
			}
		);
	},
	openCopyToPopup: function(channelId, folder) {
		ViiKii.Channel.VideoList.CopyToPopup.open(channelId, folder);
	},
	openMoveToPopup: function(channelId, folder) {
		ViiKii.Channel.VideoList.MoveToPopup.open(channelId, folder);
	},
	openSuggestToPopup: function(channelId, folder) {
		ViiKii.Channel.VideoList.SuggestToPopup.open(channelId, folder);
	},
	openSuggestPopup: function(channelId, folder) {
		ViiKii.Channel.VideoList.SuggestPopup.open(channelId, folder);
	},
	update: function() {
		document.location.reload();
	},
	inappropriate : function(channelVideoId, ele) {
		ViiKii.Inappro.popup('CV', channelVideoId, ele);
	},
	openDefault: function() {
		document.location = '#';
		new Ajax.Updater(
			'page_content',
			'/channels/goto_content/'+$('channel_id').value,
			{
				evalScripts: true,
				onComplete: function() {
					Element.show('channel_top_ad');
				}
			}
		);
	},
	checkUrl: function() {
		var param = new RegExp(/#(.+)/).exec(document.location);
		if(!param) {
			this.openDefault();
			return;
		}
		var command = param[1].split('/');
		if(!command) {
			this.openDefault();
			return;
		}
		switch(command[0]) {
		case 'SUBSCRIBERS':
			ViiKii.Channel.Subscribe.showList($('channel_id').value, 1);
			return;
		}
		if(command.length < 2) {
			this.openDefault();
			return;
		}
		switch(command[0]) {
		case 'TOPIC':
			ViiKii.Channel.Topic.open(command[1]);
			return;
		case 'TOPIC_FOLDER':
			ViiKii.Channel.Topic.showFolderTopics.bind(ViiKii.Channel.Topic);
			ViiKii.Channel.Topic.showFolderTopics($('channel_id').value, command[1], 0);
			return;
		case 'VIDEO_FOLDER':
			ViiKii.Channel.Folder.showVideoList($('channel_id').value, command[1]);
			return;
		}
		this.openDefault();
	},
	hideTopicPanel: function() {
		Element.hide("channel_topic_list");
		Element.hide("topic_channel_list");
	},
	intervalCheckUrl: function() {
		var param = new RegExp(/#(.+)/).exec(document.location);
		if(!param) {
			return;
		}
		if($('channel_top_ad')) Element.hide('channel_top_ad');
		
		var command = param[1].split('/');
		if(!command || command.length < 2) {
			this.hideTopicPanel();
			return;
		}
		switch(command[0]) {
		case 'TOPIC':
			return;
		}
		this.hideTopicPanel();
	},
	merge: function() {
		var selected = [];
		for(var video in this.videos) {
			if(this.videos[video]) {
				selected.push(video);
			}
		}
		
		if (selected.length <= 1) {
			return;
		}
		
		var params = $H({'videos':selected.join(',')}).toQueryString();
		new Ajax.Request("/videos_merge/confirm", {
			asynchronous : false,
			parameters : params,
			onComplete: function(transport, response) {
				if ("success" == response.result) {
					document.location = "/videos_merge/step_one";
				} else {
					alert(response.error);
					return;
				}
			}
		});
	}
};
ViiKii.Channel.VideoList.CopyToPopup = {
	name: 'ViiKii.Channel.VideoList.CopyToPopup',
	folders: {},
	init: function() {
		this.folders = {};
	},
	addFolder: function(folderId) {
		this.folders[folderId] = false;
	},
	check: function(folderId) {
		this.uncheckAll(folderId);
		this.changeCheck(folderId, !this.folders[folderId]);
	},
	uncheckAll: function(folderId) {
		var newFolder = folderId.split("_");
		for(var folder in this.folders) {
			var oldFolder = folder.split("_");
			if(oldFolder[0] == newFolder[0] && oldFolder[1] ==  newFolder[1] && oldFolder[2] != newFolder[2]) {
				if(this.folders[folder]) {
					this.changeCheck(folder, false);
				}
			}
		}
	},
	changeCheck: function(folderId, checked) {
		this.folders[folderId] = checked;
		this.changeCheckImage(this.name+'_checkbox_'+folderId, checked);
	},
	changeCheckImage: function(id, checked) {
		var src = "";
		if(checked) {
			src = "/common/checkbox_ch.gif";
		} else {
			src = "/common/checkbox_wh.gif";
		}
		$(id).src = src;
	},
	getFolders: function() {
		var result = [];
		for(var folder in this.folders) {
			if(this.folders[folder]) {
				result.push(folder);
			}
		}
		return result;
	},
	open: function(channelId, folder) {
		new Ajax.Updater(
			'ViiKii.Channel.VideoList.copyTo',
			'/channels/copy_videos/'+channelId+'/'+folder,
			{ evalScripts: true }
		);
		Element.show('ViiKii.Channel.VideoList.copyTo');
	},
	close: function() {
		Element.hide('ViiKii.Channel.VideoList.copyTo');
	},
	ok: function(channelId, folder) {
		if(ViiKii.Channel.VideoList.getVideos().length == 0) {
			alert("Select available videos first.");
			return;
		}
		if(this.getFolders().length == 0) {
			alert("Select available folder first.");
			return;
		}
		var params = $H(
			{
				'videos': ViiKii.Channel.VideoList.getVideos().join(","),
				'folders': this.getFolders().join(",")
			}
		).toQueryString();
		var ajax = new Ajax.RequestXML(
			'/channels/copy_videos_to/',
			{
				asynchronous: false,
				parameters: params
			}
		);
		this.onSuccessCopy(ajax, channelId, folder);
	},
	onSuccessCopy: function(ajax, channelId, folder) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.close();
			alert('Videos are copied successfully!');
			return;
		}
		switch(response.error) {
		case 'INVALID_CHANNEL':
			alert("This channel is deleted");
			document.location = '/channels';
			return;
		case 'NOT_LOG_IN':
			alert("You are not the owner of this channel");
			return;
		case 'EMPTY_VIDEO':
			alert("Select available videos first.");
			return;
		case 'EMPTY_FOLDER':
			alert("Select available folder first.");
			return;
		case 'INVALID_FOLDER':
			alert("The folder is deleted.");
			ViiKii.Channel.VideoList.CopyToPopup.open(channelId, folder);
			return;	
		}
	}
};
ViiKii.Channel.VideoList.SuggestToPopup = Object.clone(ViiKii.Channel.VideoList.CopyToPopup);
ViiKii.Channel.VideoList.SuggestToPopup.name = 'ViiKii.Channel.VideoList.SuggestToPopup';
ViiKii.Channel.VideoList.SuggestToPopup.open = function(channelId, folder) {
	new Ajax.Updater(
		'ViiKii.Channel.VideoList.suggestTo',
		'/channels/suggest_videos/'+channelId+'/'+folder,
		{ evalScripts: true }
	);
	Element.show('ViiKii.Channel.VideoList.suggestTo');
};
ViiKii.Channel.VideoList.SuggestToPopup.close = function() {
	Element.hide('ViiKii.Channel.VideoList.suggestTo');
};

ViiKii.Channel.VideoList.MoveToPopup = Object.clone(ViiKii.Channel.VideoList.CopyToPopup);
ViiKii.Channel.VideoList.MoveToPopup.name = 'ViiKii.Channel.VideoList.MoveToPopup';
ViiKii.Channel.VideoList.MoveToPopup.open = function(channelId, folder) {
	new Ajax.Updater(
		'ViiKii.Channel.VideoList.moveTo',
		'/channels/move_videos/'+channelId+'/'+folder,
		{ evalScripts: true }
	);
	Element.show('ViiKii.Channel.VideoList.moveTo');
};
ViiKii.Channel.VideoList.MoveToPopup.close = function() {
	Element.hide('ViiKii.Channel.VideoList.moveTo');
};
ViiKii.Channel.VideoList.MoveToPopup.uncheckAll = function(folderId) {
	for(var folder in this.folders) {
		if(this.folders[folder]) {
			this.changeCheck(folder, false);
		}
	}
};
ViiKii.Channel.VideoList.MoveToPopup.ok = function(channelId, folder) {
	if(ViiKii.Channel.VideoList.getVideos().length == 0) {
		alert("Select available videos first.");
		return;
	}
	if(this.getFolders().length == 0) {
		alert("Select available folder first.");
		return;
	}
	var params = $H(
		{
			'videos': ViiKii.Channel.VideoList.getVideos().join(","),
			'folder': this.getFolders()[0]
		}
	).toQueryString();
	
	var ajax = new Ajax.Request("/channels/move_videos_to/" + channelId, {
		asynchronous: false,
		parameters: params,
		onComplete: function(transport, response) {
			if ("success" == response.result) {
				ViiKii.Channel.VideoList.MoveToPopup.close();
				if(confirm('Classified successfully. Do you want to redirect your page to check it out?')) {
					ViiKii.Channel.Folder.showVideoList(response.channelId, response.folderId);
				} else {
					ViiKii.Channel.VideoList.showList(1);
				}
				ViiKii.Channel.Folder.refresh(response.channelId);
			} else {
				switch(response.error) {
				case 'INVALID_CHANNEL':
					alert("This channel is deleted");
					document.location = '/channels';
					return;
				case 'NOW_OWNER':
					alert("You are not the owner of this channel");
					return;
				case 'EMPTY_VIDEO':
					alert("Select available videos first.");
					return;
				case 'EMPTY_FOLDER':
					alert("Select available folder first.");
					return;
				case 'INVALID_FOLDER':
					alert("The folder is deleted.");
					ViiKii.Channel.VideoList.MoveToPopup.open(response.channelId, response.folderId);
					return;	
				}
			}
		}
	});
};

ViiKii.Channel.VideoList.SuggestPopup = Object.clone(ViiKii.Channel.VideoList.MoveToPopup);
ViiKii.Channel.VideoList.SuggestPopup.name = 'ViiKii.Channel.VideoList.SuggestPopup';
ViiKii.Channel.VideoList.SuggestPopup.open = function(channelId, folder) {
	new Ajax.Updater(
		'ViiKii.Channel.VideoList.suggest',
		'/channels/suggest_directory/'+channelId+'/'+folder,
		{ evalScripts: true }
	);
	Element.show('ViiKii.Channel.VideoList.suggest');
};
ViiKii.Channel.VideoList.SuggestPopup.close = function() {
	Element.hide('ViiKii.Channel.VideoList.suggest');
};
ViiKii.Channel.VideoList.SuggestPopup.uncheckAll = function(folderId) {
	for(var folder in this.folders) {
		if(this.folders[folder]) {
			this.changeCheck(folder, false);
		}
	}
};
ViiKii.Channel.VideoList.SuggestPopup.ok = function(channelId, folder) {
	if(this.getFolders().length == 0) {
		alert("Select available folder first.");
		return;
	}
	this.close();
	ViiKii.Channel.Recommendation.Popup.open(channelId, this.getFolders()[0]);
};
ViiKii.Channel.Recommendation = {};
ViiKii.Channel.Recommendation.Popup = {
	layerName :'ViiKii.Channel.Recommendation.Popup.layer',
	popupUrl :'/channels/recommendation_popup/',
	edit : function(channelId) {
		document.location = '/manage_channels/init/' + channelId;
	},
	add : function(channelId, folder) {
		var recommendation = $('ViiKii.Channel.Recommendation.Popup.recommendation').value;

		if (recommendation.trim() == '') {
			alert('Insert available Video URL first.');
			return;
		}

		var params = $H( {
			channel_id :channelId,
			folder: folder,
			recommendation :recommendation
		}).toQueryString();

		var xml = new Ajax.RequestXML('/channels/add_recommendation/', {
			asynchronous :false,
			parameters :params
		});
		this.onAddRecommendationSuccess(xml, channelId);
	},
	onAddRecommendationSuccess : function(xml, channelId) {
		//alert(xml.transport.responseText);
		var response = xml.responseValue.response;
		if (response.result == 'SUCCESS') {
			this.close();
			ViiKii.Channel.VideoList.showList(1, channelId);
			ViiKii.Channel.Folder.refresh(channelId);
			return;
		}
		switch (response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'EMPTY_DATA':
		case 'EMPTY_RECOMMENDATION':
			alert('Insert available video url first.');
			break;
		case 'INVALID_RECOMMENDATION':
			alert('This video is unavailable. Please recommend other video.');
			return;
		case 'DUP_RECOMMENDATION':
			alert('This video is already recommended by other users.');
			return;
		case 'DB_ERROR':
			alert("Fail to add partner blog");
			return;
		case 'NOT_PERMISSION':
			alert("You don't have permission");
			return;
		}
	},
	open : function(channelId, folder) {
		new Ajax.Request(
			'/channels/recommendation_popup/' + channelId + '/' + folder,
			{
				evalScripts :true,
				onSuccess :this.onCompletePopUp.bind(this)
			}
		);
	},
	onCompletePopUp : function(transport) {
		var posLeft = (document.body.scrollWidth - 618) / 2;
		var posTop = Position.realOffset(document.body)[1] + 150;
	
		var layerName = this.layerName;
		if ($(layerName)) {
			$(layerName).innerHTML = transport.responseText.stripScripts();
			$(layerName).style.display = 'block';
		} else {
			var e = document.createElement('div');
			e.id = layerName;
			var styles = {
				position :'absolute',
				top :posTop + 'px',
				left :posLeft + 'px',
				width :'310px',
				height :'120px',
				backgroundColor :'#FFFFFF'
			};
			Element.setStyle(e, styles);
			e.innerHTML = transport.responseText.stripScripts();
			document.getElementsByTagName('body')[0].appendChild(e);
		}
		ViiKii.UI.Round.init(layerName, {
			corners :'all',
			borderSize :1
		});
		setTimeout( function() {
			transport.responseText.evalScripts();
		}.bind(this), 0);
	},
	close : function() {
		$(this.layerName).style.display = 'none';
	}
};
ViiKii.Channel.ChannelList = {
	clickTab: function(tab) {
		new Ajax.Updater(
			'channel_categories',
			'/channel_list/categories/'+tab,
			{ evalScripts: true }
		);
	},
	clickFolder: function(folderId, genreId, countryId) {
		this.showCategories(genreId, countryId);
		ViiKii.UI.Folder.toggleSubs(folderId);
	},
	showCategories: function(genreId, countryId) {
		new Ajax.Updater(
			'ViiKii.Channel.ChannelList.layer',
			'/channel_list/channel_list_content/'+genreId+'/'+countryId,
			{
				evalScripts: true,
				onComplete: function() {
					var position = Position.positionedOffset($('ViiKii.Channel.ChannelList.layer'));
					window.scrollTo(0, position[1]);
				}
			}
		)
	},
	update: function() {
//		ViiKii.Channel.ChannelList.Popular.refresh.bind(ViiKii.Channel.ChannelList.Popular);
//		ViiKii.Channel.ChannelList.Popular.refresh();
		if($('featured_channels_type')) {
			ViiKii.Channel.ChannelList.Popular.show($('featured_channels_type').value);
		}
		ViiKii.Channel.ChannelList.Channels.refresh.bind(ViiKii.Channel.ChannelList.Channels);
		ViiKii.Channel.ChannelList.Channels.refresh();
	}
};
ViiKii.Channel.ChannelList.Popular = {
	show: function(selected) {
		new Ajax.Updater(
			'featured_channels',
			'/channel_list/featured_channels/'+selected,
			{ evalScripts: true }
		);
	}
};
/*
ViiKii.Channel.ChannelList.Popular = {
	objectId: 'ViiKii.Channel.ChannelList.Popular',
	refresh: function() {
		if(!$('ViiKii.Channel.ChannelList.Popular.layer')) {
			return;
		}
		new Ajax.Updater(
			'ViiKii.Channel.ChannelList.Popular.layer',
			'/featured_channels/channel_main/'+ViiKii.Util.get(this, 'languageId'),
			{ evalScripts: true }
		)
	}
};
*/
ViiKii.Channel.ChannelList.Channels = {
	objectId: 'ViiKii.Channel.ChannelList.Channels',
	refresh: function() {
		var sortMost = $(this.objectId+'.sortMost.input').value;
		var sortDate = $(this.objectId+'.sortDate.input').value;
		new Ajax.Updater(
			'ViiKii.Channel.ChannelList.Channels.layer',
			'/channel_list/channel_list/'+ViiKii.Util.get(this, 'genreId')+'/'+ViiKii.Util.get(this, 'countryId')+'/'+ViiKii.Util.get(this, 'curPage')+'/'+sortMost+'/'+sortDate,
			{ evalScripts:true }
		);
	},
	loadPage: function(curPage) {
		ViiKii.Util.set(this, 'curPage', curPage);
		this.refresh();
	}
};
ViiKii.Channel.Folder = {
	_channelId :0,
	_folderId :0,
	_depth :0,
	_type :'',
	_contextMenuOpened :false,
	_editInputBoxOpened :false,
	_oldFolderInnerHTML :'',
	_popupedList :true,

	_isSubFolder : function(depth) {
		return depth == 2;
	},

	toggleList : function(title, isOwner) {
		$("channel_folder_list_wrap").toggle();
		if ($("new_channel_folder_menu")) {
			$("new_channel_folder_menu").toggle();
		}
		if ($("channel_folder_list_wrap").visible()) {
			title.style.background = "url(/common/bullet001_s.gif) no-repeat 3px center";
		} else {
			title.style.background = "url(/common/bullet001_s_rotate.gif) no-repeat 5px center";
		}
	},

	closeContextMenu : function() {
		$('channel-folder-context-menu').style.display = 'none';
		this._contextMenuOpened = false;
	},
	
	add : function(event, channelId, parentFolderId) {
		if (this.isOpenEditInputBox()) {
			this.closeEditInputBox();
		}
		Event.stop(event); //For openEditInputBox function
		this.closeContextMenu();
		if (typeof parentFolderId == "undefined") {
			parentFolderId = this._folderId;
		}
		
		var ajax = new Ajax.Request("/channels/add_folder/" + channelId + "/" + parentFolderId, {
			asynchronous : false,
			method: "POST",
			parameter: null,
			onComplete: function(transport, response) {
				if ("success" == response.status) {
					if (0 == response.parentFolderId) {
						depth = 1;
						var tag = "<div id='channel_folder_"+response.folderId+"' class='folder' onclick='ViiKii.Channel.Folder.showVideoList("+response.channelId+", "+response.folderId+", 1);' oncontextmenu='ViiKii.Channel.Folder.onContextMenu(event, "+response.folderId+", 1, "+response.locked+")'>"
								+ "<span id='channel_folder_name_"+response.folderId+"'>"+response.folderName+"</span> <span>(0)</span></div>"
								+ "<div id='channel_subfolders_" + response.folderId + "' style='display:none;float:left;width:193px;'></div>";
						$("channel_folder_list").update(tag + $("channel_folder_list").innerHTML);
						if ( ! $("channel_folder_list").visible()) {
							$("channel_folder_list").show();
						}
					} else {
						depth = 2;
						var tag = "<div id='channel_folder_"+response.folderId+"' class='sub_folder' onclick='ViiKii.Channel.Folder.showVideoList("+response.channelId+", "+response.folderId+", 2)' oncontextmenu='ViiKii.Channel.Folder.onContextMenu(event, "+response.folderId+", 2, "+response.locked+")'>"
								+ "- <span id='channel_folder_name_"+response.folderId+"'>" + response.folderName + "</span> <span>(0)</span>"
								+ "</div>";
						
						$('channel_subfolders_' + response.parentFolderId).update(tag + $('channel_subfolders_' + response.parentFolderId).innerHTML);
						if ( ! $('channel_subfolders_' + response.parentFolderId).visible()) {
							$("channel_folder_" + response.parentFolderId).setStyle({background : 'rgb(128, 128, 128) url(/img/common/bullet003_ss_down.gif) no-repeat 188px center'});
							$('channel_subfolders_' + response.parentFolderId).show();
						}
					}
					ViiKii.Channel.Folder.openEditInputBox(null, response.channelId, response.folderId, depth);
				} else {
					alert("Fail, to add folder");
				}
			}
		});
	},
	
	remove : function(channelId) {
		this.closeContextMenu();
		var req = new Ajax.Request("/channels/remove_folder/" + channelId + "/" + this._folderId, {
			asynchronous : false,
			method: "POST",
			parameter: null,
			onComplete: function(transport, response) {
				if ("success" == response.status) {
					if ($("channel_folder_" + response.folderId)) {
						$("channel_folder_" + response.folderId).remove();
					}
					// this condition for only IE browser!!
					if ($("channel_subfolders_" + response.parentFolderId) && $("channel_subfolders_" + response.parentFolderId).innerHTML.trim().empty()) {
						$("channel_subfolders_" + response.parentFolderId).hide();	
					}
					if ($("channel_subfolders_" + response.folderId)) {
						$("channel_subfolders_" + response.folderId).remove();
					}
					if ($("channel_folder_list").innerHTML.trim().empty()) {
						$("channel_folder_list").hide();
					}
				} else {
					alert("Fail, to delete folder");
				}
			}
		});
	},

	lock : function(channelId) {
		this.closeContextMenu();
		var url = '/channels/lock_folder/' + channelId + '/' + this._folderId;
		this.update(url);
	},

	unlock : function(channelId) {
		this.closeContextMenu();
		var url = '/channels/unlock_folder/' + channelId + '/' + this._folderId;
		this.update(url);
	},

	openEditInputBox : function(event, channelId, folderId, depth) {
		if (null != event) {
			Event.stop(event);
		}

		if (typeof folderId != "undefined" && typeof depth != "undefined") {
			this._folderId = folderId;
			this._depth = depth;
		}
		this.closeContextMenu();
		this._channelId = channelId;
		this._oldFolderInnerHTML = $('channel_folder_' + this._folderId).innerHTML;
		var folderName = $('channel_folder_name_' + this._folderId).innerHTML;
		
		var color = '#ffffff';
		if (this._isSubFolder(this._depth)) {
			color = '#808080';
		}
		$('channel_folder_' + this._folderId).innerHTML = "<input id='channel_folder_"
				+ this._folderId
				+ "_edit' type='text' onKeyDown='ViiKii.Channel.Folder.onKeyDown(event)' style='width:100%;border:0;background-color:transparent;color:"
				+ color + "' maxlength='80' onclick='Event.stop(event)'>";
		$('channel_folder_' + this._folderId + '_edit').value = folderName;
		$('channel_folder_' + this._folderId + '_edit').focus();
		this._editInputBoxOpened = true;
	},

	onKeyDown : function(event) {
		switch (event.keyCode) {
		case Event.KEY_RETURN:
			var folderName = $('channel_folder_' + this._folderId + '_edit').value;
			this.closeEditInputBox();
			this.rename(this._channelId, folderName);
			break;
		case Event.KEY_ESC:
			this.closeEditInputBox();
			break;
		}
	},

	closeEditInputBox : function() {
		$('channel_folder_' + this._folderId).innerHTML = this._oldFolderInnerHTML;
		this._editInputBoxOpened = false;
	},
	rename : function(channelId, folderName) {
		var params = $H( {
			'channelId' :channelId,
			'folderId' :this._folderId,
			'folderName' :folderName
		}).toQueryString();
		
		var req = new Ajax.Request("/channels/rename_folder", {
			asynchronous : false,
			method : 'post',
			parameters : params,
			onComplete: function(transport, response) {
				if ("success" == response.status) {
					if ($("channel_folder_name_" + response.folderId)) {
						$("channel_folder_name_" + response.folderId).update(response.folderName);
					}
				} else {
					alert("Fail, to rename folder");
				}
			}
		});
	},
	update : function(url, params) {
		if (typeof params == "undefined") {
			params = null;
		}
		var response = new Ajax.Updater('channel_folder_layer', url, {
			asynchronous :true,
			evalScripts :true,
			parameters :params
		});
	},
	onContextMenu : function(event, folderId, depth, locked, type) {
		if (this.isOpenEditInputBox()) {
			this.closeEditInputBox();
		}
		
		if ($('channel-folder-context-menu') == null) {
			return;
		}

		this._folderId = folderId;
		this._depth = depth;
		this._type = type;

		if (this._isSubFolder(depth)) {
			this._hiddenAddContextMenu();
		} else {
			this._showAddContextMenu();
		}
		/*
		if (locked) {
			this._showUnLockContextMenu();
		} else {
			this._showLockContextMenu();
		}
		*/

		$('channel-folder-context-menu').style.left = Event.pointerX(event) + 'px';
		$('channel-folder-context-menu').style.top = Event.pointerY(event) + 'px';
		$('channel-folder-context-menu').style.display = 'block';
		this._contextMenuOpened = true;
		Event.stop(event); // remove document original contextmenu event
	},
	
	_showAddContextMenu : function() {
		$('channel-folder-context-menu-add').style.display = 'block';
	},
	
	_hiddenAddContextMenu : function() {
		$('channel-folder-context-menu-add').style.display = 'none';
	},
	
	_showUnLockContextMenu : function() {
		$('channel-folder-context-menu-lock').style.display = 'none';
		$('channel-folder-context-menu-unlock').style.display = 'block';
	},
	
	_showLockContextMenu : function() {
		$('channel-folder-context-menu-lock').style.display = 'block';
		$('channel-folder-context-menu-unlock').style.display = 'none';
	},
	
	isOpenContextMenu : function() {
		return this._contextMenuOpened;
	},
	
	isOpenEditInputBox : function() {
		return this._editInputBoxOpened;
	},
	refresh: function(channelId) {
		new Ajax.Updater(
			'channel_folder_layer',
			'/channels/folders/'+channelId,
			{ evalScripts:true }
		);
	},
	showVideoList: function(channelId, folder) {
		document.location = "#VIDEO_FOLDER/"+folder;
		if ($("channel_subfolders_" + folder) && ! $("channel_subfolders_" + folder).innerHTML.trim().empty()) {
			if ($("channel_subfolders_" + folder).visible()) {
				$("channel_folder_" + folder).setStyle({background : 'rgb(128, 128, 128) url(http://vkcommon.viikii.net/bullet003_ss_left.gif) no-repeat 191px center'});
			} else {
				$("channel_folder_" + folder).setStyle({background : 'rgb(128, 128, 128) url(http://vkcommon.viikii.net/bullet003_ss_down.gif) no-repeat 188px center'});
			}
			$("channel_subfolders_" + folder).toggle();
		}
			
		new Ajax.Updater(
			'page_content',
			'/channels/videos/'+channelId+'/15/1/'+folder,
			{ evalScripts:true }
		);
	},
	updateForumTopics: function(channelId, itemPerPage, page, folder) {
		folder = Object.isUndefined(folder)?'all':folder;
		new Ajax.Updater(
			'page_content',
			"/channels/forum_topics/"+channelId+"/"+itemPerPage+"/"+page+'/'+orderBy+'/'+inOrder+'/'+folder,
			{ evalScripts:true }
		);
	}
};
ViiKii.Channel.Editor = {};
ViiKii.Channel.Editor.Introduction = {
	objectId: 'ViiKii.Channel.Editor.Introduction',
	open : function(channelId, uploadUrl) {
		this.showEditor(uploadUrl);
		Element.show('ViiKii.Channel.Editor.Introduction.editor');
		Element.hide('ViiKii.Channel.Editor.Introduction.boundary');
	},
	save : function() {
		var params = $H({
			'intro' :this.getContent()
		}).toQueryString();
		new Ajax.Request(
			'/channel_intros/edit_intro/'+ViiKii.Util.get(this, 'channelId')+'/'+ViiKii.Util.get(this, 'languageId'),
			{
				parameters :params,
				onComplete: this.onSave.bind(this)
			}
		);
	},
	onSave : function(transport, response) {
//		alert(transport.responseText);
		if (response.result == 'SUCCESS') {
			this.closeEditor();
			ViiKii.Channel.Intro.showLanguage.bind(ViiKii.Channel.Intro);
			ViiKii.Channel.Intro.showLanguage(ViiKii.Util.get(this, 'languageId'));
			return;
		}
		switch (response.error) {
		case 'INVALID_CHANNEL':
			alert("This channel is deleted.");
			document.location = '/channels';
			return;
		case 'NOT_OWNER':
			alert("You are not the owner of this channel.");
			this.closeEditor();
			ViiKii.Channel.Intro.refresh.bind(ViiKii.Channel.Intro);
			ViiKii.Channel.Intro.refresh();
			return;
		case 'EMPTY_INPUT':
			alert("Insert available content first!");
			return;
		case 'DB_ERROR':
			alert("Fail to edit channel introduction. Please try again!");
			return;
		case 'OUT_OF_LENGTH':
			alert("The content is out of length.");
			return;
		}
	},
	discard : function() {
		this.closeEditor();
		ViiKii.Channel.Intro.refresh.bind(ViiKii.Channel.Intro);
		ViiKii.Channel.Intro.refresh();
	},
	showEditor : function(uploadUrl) {
		var uploadUrl = uploadUrl+'?type=CHANNEL_INTRODUCTION&user_name=' + ViiKii.Util.getDomainCookie('username');
		ViiKii.Editor.openEditor('ViiKii.Channel.Editor.Introduction.editorContent', this.getContentHeight(), '', uploadUrl);
		var content = $('ViiKii.Channel.Editor.Introduction.content').innerHTML;
		ViiKii.Editor.setContent(content);
	},
	getContent : function() {
		return ViiKii.Editor.getEditorContent();
	},
	getContentHeight : function() {
		if(trim($('ViiKii.Channel.Editor.Introduction.content').innerHTML) == '') {
			return 129;
		}
		var contentHeight = Element.getHeight('ViiKii.Channel.Editor.Introduction.content');
		if (contentHeight < 36) {
			return 36;
		}
		return contentHeight;
	},
	closeEditor : function() {
		ViiKii.Editor.closeEditor();
	}
};

ViiKii.Channel.Searching = {
	goMore : function() {
		this.paging(1);
	},
	paging: function(pageNo) {
		var params = $H({'pageNo':pageNo, 'query':$F('query')}).toQueryString();
		document.location = '/search/channels?' + params;
	}
};
ViiKii.Channel.Evangelists = {
	objectId: 'ViiKii.Channel.Evangelists',
	loadPage: function(curPage) {
		ViiKii.Util.set(this, 'curPage', curPage);
		this.updatePage();
	},
	updatePage: function() {
		new Ajax.Updater(
			'ViiKii.Channel.Evangelists.content',
			'/channels/evangelists/'+ViiKii.Util.get(this, 'channelId')+'/'+ViiKii.Util.get(this, 'curPage'),
			{ evalScripts: true }
		);
	}
};

ViiKii.Channel.Segmenters = {
	objectId: 'ViiKii.Channel.Segmenters',
	loadPage: function(curPage) {
		ViiKii.Util.set(this, 'curPage', curPage);
		this.refresh();
	},
	refresh: function() {
		new Ajax.Updater(
			'ViiKii.Channel.Segmenters.layer',
			'/channels/segmenters/' + ViiKii.Util.get(this, 'channelId') + '/' + ViiKii.Util.get(this, 'curPage'),
			{ evalScripts: true }
		);
	}
};

ViiKii.Channel.Embeds = {
	objectId: 'ViiKii.Channel.Embeds',
	click: function(embedId) {
		document.location = '#EMBED/'+embedId;
		//alert("click embed: "+embedId);
		new Ajax.Updater(
			'page_content',
			'/channel_embeds/show_embed/'+embedId,
			{ evalScripts: true }
		);
	},
	edit: function(embedId) {
		//alert("edit embed: "+embedId);
		document.location = '#EDIT_EMBED/'+embedId;
		new Ajax.Updater(
			'page_content',
			'/channel_embeds/edit_embed/'+embedId,
			{ evalScripts: true }
		);
	},
	del: function(embedId) {
		var ajax = new Ajax.RequestXML(
			'/channel_embeds/delete_embed/'+embedId,
			{ asynchronous: false }
		);
		this.onDel(ajax);
	},
	onDel: function(ajax) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if (response.result == 'SUCCESS') {
			alert('Deleted successfully.');
			document.location = '/channels/goto/'+response.channel_url;
			return;
		}
		switch (response.error) {
		case 'NOT_OWNER':
			alert('You are not the owner of this channel.');
			return;
		}
	},
	changeOrder: function(embedId, type) {
		//alert("change order: "+embedId+" "+type);
		var ajax = new Ajax.RequestXML(
			'/channel_embeds/change_order/'+embedId+'/'+type,
			{
				asynchronous: false
			}
		);
		this.onChangeOrder(ajax);
	},
	onChangeOrder: function(ajax) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if (response.result == 'SUCCESS') {
			this.refresh();
			return;
		}
		switch (response.error) {
		case 'NOT_OWNER':
			alert('You are not the owner of this channel.');
			return;
		case 'INVALID_EMBED':
			alert('The embed stuff is deleted.');
			this.refresh();
			return;
		case 'DB_ERROR':
			alert('Fail to change orders. Please try again.');
			return;
		}
	},
	makeNew: function() {
		document.location = '#NEW_EMBED';
		new Ajax.Updater(
			'page_content',
			'/channel_embeds/new_embed/'+ViiKii.Util.get(this, 'channelId'),
			{ evalScripts: true }
		);
	},
	refresh: function() {
		new Ajax.Updater(
			'ViiKii.Channel.Embeds.layer',
			'/channels/embeds/'+ViiKii.Util.get(this, 'channelId'),
			{ evalScripts: true }
		);
	}
};

ViiKii.Channel.Embeds.New = {
	objectId: 'ViiKii.Channel.Embeds.New',
	save: function() {
		var title = $('ViiKii.Channel.Embeds.New.title').value.trim();
		var code = $('ViiKii.Channel.Embeds.New.code').value.trim();
		if(title == '') {
			alert('Insert available title first.');
			return;
		}
		if(code == '') {
			alert('Insert available embed code first.');
			return;
		}
		var params = $H({
			'title': title,
			'code': code
		}).toQueryString();
		var ajax =	new Ajax.RequestXML(
						'/channel_embeds/save_new_embed/'+ViiKii.Util.get(this, 'channelId'),
						{
							asynchronous: false,
							parameters: params
						}
					);
		this.onSave(ajax);
	},
	onSave: function(ajax, channelId) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if (response.result == 'SUCCESS') {
			alert('Added successfully.');
			ViiKii.Channel.Embeds.refresh();
			ViiKii.Channel.Embeds.click(response.embed_id);
			return;
		}
		switch (response.error) {
		case 'INVALID_CHANNEL':
			alert("This channel is deleted.");
			document.location = '/channels';
			return;
		case 'NOT_OWNER':
			alert('You are not the owner of this channel.');
			document.location = '/channels/goto/'+$('channel_url').value;
			return;
		case 'EMPTY_TITLE':
			alert('Insert available title first.');
			return;
		case 'EMPTY_TITLE':
			alert('Insert available embed code first.');
			return;
		case 'DB_ERROR':
			alert('Fail to add embed stuff. Please try again.');
			return;
		}
	},
	cancel: function() {
		ViiKii.Channel.VideoList.openDefault();
	}
};
ViiKii.Channel.Embeds.Edit = {
	objectId: 'ViiKii.Channel.Embeds.Edit',
	save: function() {
		var title = $('ViiKii.Channel.Embeds.Edit.title').value.trim();
		var code = $('ViiKii.Channel.Embeds.Edit.code').value.trim();
		if(title == '') {
			alert('Insert available title first.');
			return;
		}
		if(code == '') {
			alert('Insert available embed code first.');
			return;
		}
		var params = $H({
			'title': title,
			'code': code
		}).toQueryString();
		var ajax =	new Ajax.RequestXML(
						'/channel_embeds/save_edit_embed/'+ViiKii.Util.get(this, 'embedId'),
						{
							asynchronous: false,
							parameters: params
						}
					);
		this.onSave(ajax);
	},
	onSave: function(ajax) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if (response.result == 'SUCCESS') {
			alert('Edited successfully.');
			ViiKii.Channel.Embeds.refresh();
			ViiKii.Channel.Embeds.click(ViiKii.Util.get(this, 'embedId'));
			return;
		}
		switch (response.error) {
		case 'INVALID_EMBED':
			alert("This embed is deleted.");
			document.location = '/channels/goto/'+$('channel_url').value;
			return;
		case 'NOT_OWNER':
			alert('You are not the owner of this channel.');
			document.location = '/channels/goto/'+$('channel_url').value;
			return;
		case 'EMPTY_TITLE':
			alert('Insert available title first.');
			return;
		case 'EMPTY_TITLE':
			alert('Insert available embed code first.');
			return;
		}
	},
	cancel: function() {
		ViiKii.Channel.VideoList.openDefault();
	}
};
ViiKii.Channel.Translate = {
	channelId: 0,
	isEditing: false,
	init: function() {
		this.isEditing = false;
	},
	update: function() {
		document.location = '/channel_translates/init/'+this.channelId;
	}
};
ViiKii.Channel.Translate.Title = {
	name: 'ViiKii.Channel.Translate.Title',
	type: 'TITLE',
	isLogin: function() {
		return ViiKii.Util.getDomainCookie('username') != null;
	},
	clickCell: function(event) {
		if(!this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}
		var source = Event.element(event);
		var sourceId = source.id.split("_");
		var sourceItem = sourceId[0];
		if (this.isLogin() && sourceItem.indexOf('cell') != -1) {
			this.editCell(source.id);
		} else if (sourceItem.indexOf('revision') != -1) {
			this.revision(sourceId[1], sourceId[2]);
		} else if (this.isLogin() && sourceItem.indexOf('save') != -1) {
			this.saveText();
		} else if (this.isLogin() && sourceItem.indexOf('cancel') != -1) {
			this.onCancelSave();
		}
	},
	revision: function(channelId, languageId) {
		if(ViiKii.Channel.Translate.isEditing) {
			return;
		}
		ViiKii.Channel.Translate.Popup.open(channelId, this.type, languageId);
	},
	editCell: function(cellId) {
		if(ViiKii.Channel.Translate.isEditing) {
			return;
		}
		var onKeyEnterHandler = this.saveText;
		var onKeyESCHandler = this.onCancelSave;
		this.editableCell.onKeyEnterDown = this.name+".saveText()";
		this.editableCell.onKeyESCDown = this.name+".onCancelSave()";
		this.editableCell.editCell(cellId);
		ViiKii.Channel.Translate.isEditing = true;
	},
	saveText: function() {
		if(!ViiKii.Channel.Translate.isEditing) {
			return;
		}
		var inputText = this.editableCell.getTextAreaText();
		inputText = inputText.trim();
		this.addTitle(this.getMetaId(), this.getLanguage(), inputText);
	},
	getMetaId: function() {
		var cellId = this.editableCell.getCellId();
		return cellId.split("_")[1];
	},
	getLanguage: function() {
		var cellId = this.editableCell.getCellId();
		return cellId.split("_")[2];
	},
	addTitle: function(channelId, language, title) {
		var params=$H(
			{channel_id:channelId, language_id:language, title:title}
		).toQueryString();
		
		new Ajax.Request(
			'/channel_translates/add_title/',
			{
				asynchronous: false,
				parameters: params,
				onComplete: this.onAddTitle.bind(this)
			}
		);
	},
	onAddTitle: function(transport, response) {
		//alert(ajax.transport.responseText);
		if(response.result == 'SUCCESS') {
			this.onSaveText(parseInt(response.revision, 10));
			return;
		}

		switch(response.error) {
		case 'DUPLICATED':
			alert("Somebody already posted the same translation as yours.");
			this.onCancelSave();
			break;
		case 'INVALID_CHANNEL':
			alert('This channel is deleted.');
			document.location = '/channels';
			break;
		case 'NOT_LOG_IN':
			this.onCancelSave();
			ViiKii.Login.popUp();
			break;
		case 'DB_ERROR':
			alert("Fail to add title.");
			break;
		}
	},
	onSaveText: function(revision) {
		var inputText = this.editableCell.getTextAreaText();
		this.editableCell.setText(inputText, this.editableCell.getTagId(), revision);
		ViiKii.Channel.Translate.isEditing = false;
	},
	onCancelSave: function() {
		this.editableCell.cancelEdit();
		ViiKii.Channel.Translate.isEditing = false;
	},
	editableCell: new ViiKii.UI.EditableCell()
};
ViiKii.Channel.Translate.Description = Object.clone(ViiKii.Channel.Translate.Title);
ViiKii.Channel.Translate.Description.name = 'ViiKii.Channel.Translate.Description';
ViiKii.Channel.Translate.Description.type = 'DESCRIPTION';
ViiKii.Channel.Translate.Description.addTitle = function(channelId, language, description) {
	var params=$H(
		{channel_id:channelId, language_id:language, description:description}
	).toQueryString();
	
	var ajax = new Ajax.Request(
		'/channel_translates/add_description/',
		{
			asynchronous: false,
			parameters: params,
			onComplete: this.onAddTitle.bind(this)
		}
	);
};
ViiKii.Channel.Translate.Description.onAddTitle = function(transport, response) {
	//alert(ajax.transport.responseText);
	if(response.result == 'SUCCESS') {
		this.onSaveText(parseInt(response.revision, 10));
		return;
	}
	switch(response.error) {
	case 'DUPLICATED':
		alert("Somebody already posted the same translation as yours.");
		this.onCancelSave();
		break;
	case 'INVALID_CHANNEL':
		alert('This channel is deleted.');
		document.location = '/channels';
		break;
	case 'NOT_LOG_IN':
		this.onCancelSave();
		ViiKii.Login.popUp();
		break;
	case 'DB_ERROR':
		alert("Fail to add description.");
		break;
	}
};
ViiKii.Channel.Translate.Popup = {
	channelId: 0,
	type: '',
	languageId: 'en',
	orderBy: 'T',
	inOrder: true,
	starBox: null,
	open: function(channelId, type, languageId) {
		var req = new Ajax.Request(
			'/channel_translates/translate_popup/'+channelId+'/'+type+'/'+languageId,
			{
				asynchronous: true,
				evalScripts: true,
				onSuccess: this.onOpen.bind(this)
			}
		);
	},
	onOpen: function(transport) {
		var posLeft = (document.body.scrollWidth - 618) / 2;
		var posTop  = Position.realOffset(document.body)[1] + 150;
		
		var layerName = "ViiKii.Channel.Translate.Popup.layer";
		if ($(layerName)) {
			$(layerName).innerHTML = transport.responseText;
			$(layerName).style.display = 'block';
		} else {
			var e = document.createElement('div');
			e.id = layerName;
			var styles = {
				position: 'absolute',
				top:posTop+'px',
				left:posLeft+'px',
				width: '672px',
				height: '521px',
				backgroundColor: '#FFFFFF'
			};
			Element.setStyle(e, styles);
			e.innerHTML = transport.responseText;
			document.getElementsByTagName('body')[0].appendChild(e);
		}
		ViiKii.UI.Round.init(layerName, {corners:'all', borderSize:1});
	},
	close: function() {
		Element.hide('ViiKii.Channel.Translate.Popup.layer');
		ViiKii.Channel.Translate.update();
	},
	sortList: function(orderBy, inOrder) {
		this.orderBy = orderBy;
		this.inOrder = inOrder;
		this.refresh();
	},
	refresh: function() {
		new Ajax.Updater(
			'ViiKii.Channel.Translate.Popup.content',
			'/channel_translates/translate_histories/'+this.channelId+'/'+this.type+'/'+this.languageId+'/'+this.orderBy+'/'+this.inOrder,
			{
				evalScripts: true
			}
		);
	},
	save: function() {
		var content = trim($('ViiKii.Channel.Translate.Popup.input').value);
		if(content == '') {
			alert('Insert available content first!');
			return;
		}
		switch(this.type) {
		case 'TITLE':
			this.addTitle(content);
			break;
		case 'DESCRIPTION':
			this.addDescription(content);
			break;
		}
	},
	addTitle: function(content) {
		var params=$H(
			{channel_id:this.channelId, language_id:this.languageId, title:content}
		).toQueryString();
		new Ajax.Request(
			'/channel_translates/add_title/',
			{
				asynchronous: false,
				parameters: params,
				onComplete: this.onAddTitle.bind(this)
			}
		);
	},
	onAddTitle: function(transport, response) {
		//alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			this.refresh();
			return;
		}
		switch(response.error) {
		case 'DUPLICATED':
			alert("Somebody already posted the same translation as yours.");
			break;
		case 'INVALID_CHANNEL':
			alert('This channel is deleted.');
			document.location = '/channels';
			break;
		case 'NOT_LOG_IN':
			this.onCancelSave();
			ViiKii.Login.popUp();
			break;
		case 'DB_ERROR':
			alert("Fail to add title.");
			break;
		}
	},
	addDescription: function(content) {
		var params=$H(
			{channel_id:this.channelId, language_id:this.languageId, description:content}
		).toQueryString();
		new Ajax.Request(
			'/channel_translates/add_description/',
			{
				asynchronous: false,
				parameters: params,
				onComplete: this.onAddDescription.bind(this)
			}
		);
	},
	onAddDescription: function(transport, response) {
		//alert(ajax.transport.responseText);
		if(response.result == 'SUCCESS') {
			this.refresh();
			return;
		}
		switch(response.error) {
		case 'DUPLICATED':
			alert("Somebody already posted the same translation as yours.");
			break;
		case 'INVALID_CHANNEL':
			alert('This channel is deleted.');
			document.location = '/channels';
			break;
		case 'NOT_LOG_IN':
			this.onCancelSave();
			ViiKii.Login.popUp();
			break;
		case 'DB_ERROR':
			alert("Fail to add description.");
			break;
		}
	},
	inappro: function(itemId) {
		alert('Under Construction!!');
	},
	del: function(itemId) {
		switch(this.type) {
		case 'TITLE':
			this.delTitle(itemId);
			break;
		case 'DESCRIPTION':
			this.delDescription(itemId);
			break;
		}
	},
	delTitle: function(itemId) {
		new Ajax.Request(
			'/channel_translates/delete_title/'+itemId,
			{
				asynchronous: true,
				onComplete: this.onDelTitle.bind(this)
			}
		);
	},
	onDelTitle: function(transport, response) {
		if(response.result == 'SUCCESS') {
			this.refresh();
			return;
		}
		switch(response.error) {
		case 'NOT_OWNER':
			alert("You are not the owner of the translation.");
			this.refresh();
			break;
		case 'CANNOT_DELETE':
			alert("You cannot delete every title of this channel!");
			break;
		case 'DB_ERROR':
			alert("Fail to delete title. Please try again!!");
			break;
		}
	},
	delDescription: function(itemId) {
		new Ajax.Request(
			'/channel_translates/delete_description/'+itemId,
			{
				asynchronous: true,
				onComplete: this.onDelDescription.bind(this)
			}
		);
	},
	onDelDescription: function(transport, response) {
		if(response.result == 'SUCCESS') {
			this.refresh();
			return;
		}
		switch(response.error) {
		case 'NOT_OWNER':
			alert("You are not the owner of the translation.");
			this.refresh();
			break;
		case 'DB_ERROR':
			alert("Fail to delete title. Please try again!!");
			break;
		}
	},
	onRating: function(starBox, itemId) {
		ViiKii.Channel.Translate.Popup.starBox = starBox;
		switch(ViiKii.Channel.Translate.Popup.type) {
		case 'TITLE':
			ViiKii.Channel.Translate.Popup.rateTitle.bind(ViiKii.Channel.Translate.Popup);
			ViiKii.Channel.Translate.Popup.rateTitle(itemId, starBox.getPoint());
			break;
		case 'DESCRIPTION':
			ViiKii.Channel.Translate.Popup.rateDescription.bind(ViiKii.Channel.Translate.Popup);
			ViiKii.Channel.Translate.Popup.rateDescription(itemId, starBox.getPoint());
			break;
		}
	},
	rateTitle: function(itemId, point) {
		new Ajax.Request(
			'/channel_translates/rate_title/'+itemId+'/'+point,
			{
				onComplete: this.onRateTitle.bind(this)
			}
		);
	},
	onRateTitle: function(transport, response) {
		//alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			alert(response.score);
			this.starBox.set(response.score);
			return;
		}
		switch(response.error) {
		case 'INVALID_TITLE':
			alert('The content is deleted');
			this.refresh();
			break;
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'DB_ERROR':
			alert("Fail to rate the translation. Please try again!!");
			break;
		}
	},
	rateDescription: function(itemId, point) {
		new Ajax.Request(
			'/channel_translates/rate_description/'+itemId+'/'+point,
			{
				onComplete: this.onRateDescription.bind(this)
			}
		);
	},
	onRateDescription: function(transport, response) {
		//alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			alert(response.score);
			this.starBox.set(response.score);
			return;
		}
		switch(response.error) {
		case 'INVALID_DESCRIPTION':
			alert('The content is deleted');
			this.refresh();
			break;
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'DB_ERROR':
			alert("Fail to rate the translation. Please try again!!");
			break;
		}
	}
};
ViiKii.Channel.Staffs = {
	objectId: 'ViiKii.Channel.Staffs',
	refresh: function() {
		new Ajax.Updater(
			'channel_staffs_layer',
			'/channels/staffs/'+ViiKii.Util.get(this, 'channelId')+'/'+ViiKii.Util.get(this, 'curPage'),
			{
				evalScripts: true
			}
		);
	},
	loadPage: function(curPage) {
		ViiKii.Util.set(this, 'curPage', curPage);
		this.refresh();
	},
	appoint: function() {
		ViiKii.Channel.Staffs.Popup.open.bind(ViiKii.Channel.Staffs.Popup);
		ViiKii.Channel.Staffs.Popup.open('/channel_moderators/appoint_popup/'+ViiKii.Util.get(this, 'channelId'));
	},
	apply: function() {
		ViiKii.Channel.Staffs.Popup.open.bind(ViiKii.Channel.Staffs.Popup);
		ViiKii.Channel.Staffs.Popup.open('/channel_moderators/apply_popup/'+ViiKii.Util.get(this, 'channelId'));
	},
	block: function(userName) {
		new Ajax.Request(
			'/channel_moderators/block/'+ViiKii.Util.get(this, 'channelId')+'/'+userName,
			{
				onComplete: this.onBlock.bind(this)
			}
		);
	},
	onBlock: function(transport, response) {
		//alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			this.refresh();
			return;
		}
		switch(response.error) {
		case 'INVALID_CHANNEL':
			alert('This channel is deleted');
			document.location = 'channels/home';
			break;
		case 'NOT_OWNER':
			alert("You are not the manager of this channels.");
			this.refresh();
			break;
		case 'DB_ERROR':
			alert("Fail to block the user. Please try again!!");
			break;
		}
	},
	drop: function() {
		new Ajax.Request(
			'/channel_moderators/drop/'+ViiKii.Util.get(this, 'channelId'),
			{
				onComplete: this.onDrop.bind(this)
			}
		);
	},
	onDrop: function(transport, response) {
		//alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			this.refresh();
			return;
		}
		switch(response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'DB_ERROR':
			alert("Fail to drop moderator. Please try again!!");
			break;
		}
	},
	wannabe: function() {
		var message = "If you want to be a staff member for this channel, you can contact and ask the channel manager since the channel manager has the right to appoint moderators.\n\n";
		message += "In case the channel manager is absent for more than 10 days, you can leave a message in the ViiKiihelper's inbox. ViiKiihelper will examine the situation and will help if possible.";
		alert(message);
	}
};
ViiKii.Channel.Staffs.Popup = {
	objectId: 'ViiKii.Channel.Staffs.Popup',
	languageId: null,
	init: function() {
		this.languageId = null;
	},
	open: function(url) {
		new Ajax.Request(
			url,
			{
				asynchronous: true,
				evalScripts: true,
				onSuccess: this.onOpen.bind(this)
			}
		);
	},
	onOpen: function(transport) {
		var posLeft = (document.body.scrollWidth - 618) / 2;
		var posTop  = Position.realOffset(document.body)[1] + 150;
		
		var layerName = 'ViiKii.Channel.Staffs.Popup.layer';
		if ($(layerName)) {
			$(layerName).innerHTML = transport.responseText;
			$(layerName).style.display = 'block';
		} else {
			var e = document.createElement('div');
			e.id = layerName;
			var styles = {
				position: 'absolute',
				top:posTop+'px',
				left:posLeft+'px',
				width: '599px',
				height: '170px',
				backgroundColor: '#FFFFFF'
			};
			Element.setStyle(e, styles);
			e.innerHTML = transport.responseText;
			document.getElementsByTagName('body')[0].appendChild(e);
		}
		ViiKii.UI.Round.init(layerName, {corners:'all', borderSize:1});
	},
	close: function() {
		ViiKii.Languages.SelectBox.close();
		Element.hide('ViiKii.Channel.Staffs.Popup.layer');
	},
	openLanguageBox : function() {
		var popup = $('ViiKii.Channel.Staffs.Popup.layer');
		var marginLeft = parseInt(popup.style.left.replace('px', ''));
		var marginTop = parseInt(popup.style.top.replace('px', ''));
		
		var position = Position.positionedOffset($('original-language'));
		var languageBox = ViiKii.Languages.SelectBox.getChannelMirrorChooseState();
		languageBox.setCallback(ViiKii.Channel.Staffs.Popup.setLanguage);
		ViiKii.Languages.SelectBox.open(marginLeft+position[0] + 1, marginTop+position[1] + 20, languageBox);
	},
	setLanguage : function(languageId, languageName) {
		$('original-language').innerHTML = languageName;
		ViiKii.Channel.Staffs.Popup.languageId = languageId;
	},
	apply: function() {
		if(Object.isNull(this.languageId)) {
			alert("Select language first!");
			return;
		}
		new Ajax.Request(
			'/channel_moderators/apply/'+ViiKii.Util.get(this, 'channelId')+'/'+this.languageId,
			{
				onComplete: this.onApply.bind(this)
			}
		);
	},
	onApply: function(transport, response) {
		ViiKii.Channel.Staffs.refresh.bind(ViiKii.Channel.Staffs);
		// alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			this.close();
			ViiKii.Channel.Staffs.refresh();
			return;
		}
		switch(response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'INVALID_CHANNEL':
			alert('This channel is deleted!');
			document.location = '/channels';
			break;
		case 'BLOCKED_USER':
			alert('You have been rejected to be a moderator by the manager.\nApply to the manager directly.');
			break;
		case 'ALREADY_MODERATOR':
			alert('You are already a moderator of '+ViiKii.Languages.SelectBox.convertToName(response.language_id)+' community.');
			break;
		case 'DB_ERROR':
			alert("Fail to apply as a moderator. Please try again!!");
			break;
		}
	},
	appoint: function() {
		var userName = trim($('ViiKii.Channel.Staffs.Popup.userName').value);
		if(userName == '') {
			alert("Insert available username first!");
			return;
		}
		if(Object.isNull(this.languageId)) {
			alert("Select language first!");
			return;
		}
		new Ajax.Request(
			'/channel_moderators/appoint/'+ViiKii.Util.get(this, 'channelId')+'/'+this.languageId+'/'+userName,
			{
				onComplete: this.onAppoint.bind(this)
			}
		);
	},
	onAppoint: function(transport, response) {
		//alert(transport.responseText);
		ViiKii.Channel.Staffs.refresh.bind(ViiKii.Channel.Staffs);
		if(response.result == 'SUCCESS') {
			this.close();
			ViiKii.Channel.Staffs.refresh();
			return;
		}
		switch(response.error) {
		case 'NOT_OWNER':
			alert('You are not the manager of this channel.');
			break;
		case 'INVALID_CHANNEL':
			alert('This channel is deleted!');
			document.location = '/channels';
			break;
		case 'INVALID_USER':
			alert('Insert available username first.');
			break;
		case 'ALREADY_MODERATOR':
			alert(response.user_name+' is already a moderator of '+ViiKii.Languages.SelectBox.convertToName(response.language_id)+' community.');
			break;
		case 'DB_ERROR':
			alert("Fail to apply as a moderator. Please try again!!");
			break;
		}
	}
};
ViiKii.Channel.Topic = {
	objectId: 'ViiKii.Channel.Topic',
	add: function() {
		document.location = '/forums/new_topic/'+$('channel_id').value+'/CHANNEL';
	},
	open: function(topicId) {
		this.openTopic(topicId);
		new Ajax.Updater(
			'channel_topic_list',
			'/channels/topic_list/'+$('channel_id').value,
			{
				evalScripts: true,
				onComplete: function() {
					Element.show("channel_topic_list");
				}
			}
		);
	},
	openTopic: function(topicId) {
		new Ajax.Updater(
			'page_content',
			'/channels/topic/'+$('channel_id').value+'/'+topicId,
			{ evalScripts: true }
		);
		new Ajax.Updater(
			'topic_channel_list',
			'/topics/channel_list/'+topicId,
			{
				evalScripts: true,
				onComplete: function() {
					Element.show("topic_channel_list");
				}
			}
		);
	},
	showFolderTopics: function(channelId, folder, depth) {
		document.location = "#TOPIC_FOLDER/"+folder;
		if (depth == 1) {
			if ($("forum_subfolders_" + folder) && ! $("forum_subfolders_" + folder).innerHTML.trim().empty()) {
				if ($("forum_subfolders_" + folder).visible()) {
					$("forum_folder_" + folder).setStyle({background : 'rgb(128, 128, 128) url(http://vkcommon.viikii.net/bullet003_ss_left.gif) no-repeat 191px center'});
				} else {
					$("forum_folder_" + folder).setStyle({background : 'rgb(128, 128, 128) url(http://vkcommon.viikii.net/bullet003_ss_down.gif) no-repeat 188px center'});
				}
				$("forum_subfolders_" + folder).toggle();
			}
		}
		this.updateForumTopics(channelId, 20, 1, 'time', '1', folder);
	},
	updateForumTopics: function(channelId, itemPerPage, page, orderBy, inOrder, folder) {
		folder = Object.isUndefined(folder)?'all':folder;
		new Ajax.Updater(
			'page_content',
			"/channels/forum_topics/"+channelId+"/"+itemPerPage+"/"+page+'/'+orderBy+'/'+inOrder+'/'+folder,
			{ evalScripts: true }
		);
	},
	loadPage: function(curPage) {
		ViiKii.Util.set(this, 'curPage', curPage);
		this.refresh();
	},
	sorting: function(orderBy, inOrder) {
		$('topic_order_by').value = orderBy;
		$('topic_in_order').value = inOrder;
		ViiKii.Util.set(this, 'curPage', 1);
		this.refresh();
	},
	refresh: function() {
		var target = 'page_content';
		if($('forum_topics')) {
			target = 'forum_topics';
		}
		new Ajax.Updater(
			target,
			'/channels/forum_topics/'+$('channel_id').value+'/'+$('topic_per_page').value+'/'+ViiKii.Util.get(this, 'curPage')+'/'+$('topic_order_by').value+'/'+$('topic_in_order').value+'/'+$('topic_folder').value,
			{ evalScripts: true }
		);
	}
};
ViiKii.Channel.TopicList = {
	loadPage: function(curPage) {
		new Ajax.Updater(
			'channel_topic_list',
			'/channels/topic_list/'+$('channel_id').value+'/'+curPage,
			{ evalScripts: true }
		)
	}
};
ViiKii.Channel.Admin = {
	toggleClean: function(event, channel_id) {
		var source = Event.element(event);
		var isClean = source.hasClassName('channel_clean')?'F':'T';
		new Ajax.Request(
			'/channels/on_clean/'+channel_id+'/'+isClean,
			{ onComplete: this.onSetClean.bind(this) }
		);
	},
	onSetClean: function(transport, response) {
		if(response.result == 'SUCCESS') {
			var cleanIcons = $$('.channel_clean_'+response.channel_id);
			var isClean = response.is_clean=='T';
			for(var i=0; i<cleanIcons.length; i++) {
				if(isClean) {
					cleanIcons[i].removeClassName('channel_unclean');
					cleanIcons[i].addClassName('channel_clean');
				} else {
					cleanIcons[i].removeClassName('channel_clean');
					cleanIcons[i].addClassName('channel_unclean');
				}
			}
		}
		switch(response.error) {
		case 'NOT_ADMIN':
			alert('You are not an administrator.');
			break;
		case 'INVALID_CHANNEL':
			alert('The channel is deleted.');
			break;
		case 'DB_ERROR':
			alert('Fail to change the channel. Please try again!')
			break;
		}
	}
};
ViiKii.Channel.Admin.Lolly = {
	setCheckBoxes: function(className, checked) {
		var checkBoxes = $$('.'+className);
		for(var i=0; i<checkBoxes.length; i++) {
			checkBoxes[i].checked = checked;
		}
	},
	setTexts: function(className, value) {
		var textFields = $$('.'+className);
		for(var i=0; i<textFields.length; i++) {
			textFields[i].value = value;
		}
	},
	toggleAllPr: function(event) {
		var source = Event.element(event);
		this.setCheckBoxes('pr_check', source.checked);
		this.checkAllPrs();
	},
	toggleAllBrn: function(event) {
		var source = Event.element(event);
		this.setCheckBoxes('bnr_check', source.checked);
	},
	toggleAllLock: function(event) {
		var source = Event.element(event);
		this.setCheckBoxes('lock_check', source.checked);
	},
	setAllPrNumber: function() {
		this.setTexts('pr_number', $('all_pr_number').value);
	},
	setAllHqLolly: function() {
		this.setTexts('hq_lolly', $('all_hq_lolly').value);
	},
	setAllDwLolly: function() {
		this.setTexts('dw_lolly', $('all_dw_lolly').value);
	},
	checkAllPrs: function() {
		var rows = $$('.video_content_row');
		for(var i=0; i<rows.length; i++) {
			this.updateRow(rows[i].id);
		}
	},
//	checkPr: function(rowId) {
//		var hqCheck = $$('#'+rowId+' .hq_check')[0];
//		var hqLolly = $$('#'+rowId+' .hq_lolly')[0];
//		var prCheck = $$('#'+rowId+' .pr_check')[0];
//		if(hqCheck.checked && prCheck.checked && hqLolly.value > 0) {
//			alert('Selected both HQ payment and Pre-roll !');
//		}
//	},
	updateRow: function(rowId) {
		var hqCheck = $$('#'+rowId+' .hq_check')[0];
		if(hqCheck.checked) {
			Element.show($$('#'+rowId+' .hq_lolly')[0]);
			Element.show($$('#'+rowId+' .hq_url')[0])
		} else {
			Element.hide($$('#'+rowId+' .hq_lolly')[0]);
			Element.hide($$('#'+rowId+' .hq_url')[0])
		}
		var dwCheck = $$('#'+rowId+' .dw_check')[0];
		if(dwCheck.checked) {
			Element.show($$('#'+rowId+' .dw_lolly')[0]);
		} else {
			Element.hide($$('#'+rowId+' .dw_lolly')[0]);
		}
		var prCheck = $$('#'+rowId+' .pr_check')[0];
		if(prCheck.checked) {
			Element.show($$('#'+rowId+' .pr_number')[0]);
			Element.show($$('#'+rowId+' .pr_url')[0])
		} else {
			Element.hide($$('#'+rowId+' .pr_number')[0]);
			Element.hide($$('#'+rowId+' .pr_url')[0])
		}
	},
	clickCheck: function(rowId) {
//		this.checkPr(rowId);
		this.updateRow(rowId);
	},
	loadPage: function(curPage) {
		new Ajax.Updater(
			'lolly_videos',
			'/manage_channels/lolly_videos/'+$('channel_id').value+'/'+curPage,
			{ evalScripts: true }
		);
	},
	refresh: function() {
		this.loadPage($('lolly_videos_cur_page').value);
	},
	save: function() {
		var frm = $('videos_form');
		new Ajax.Request(
			'/manage_channels/on_save_lolly_videos/'+$('channel_id').value,
			{
				parameters: frm.serialize(),
				onComplete: this.onSave.bind(this)
			}
		);
	},
	onSave: function(transport, response) {
//		alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			alert('Saved successfully!');
			this.refresh();
			return;
		}
		switch(response.error) {
		case 'NOT_ADMIN':
			alert('You not an administrator.');
			break;
		case 'INVALID_DATA':
			alert('Invalid data. Please try again!');
			break;
		case 'INVALID_CHANNEL':
			alert('Invalid channel!');
			break;
		}
	},
	saveKeywords: function() {
		return alert('Under Construction!!');
		var params=$H({keywords:$('filter_keywords').value}).toQueryString();
		new Ajax.Request(
			'/manage_channels/on_save_keywords/'+$('channel_id').value,
			{
				parameters: params,
				onComplete: this.onSaveKeywords.bind(this)
			}
		);
	},
	onSaveKeywords: function(transport, response) {
		if(response.result == 'SUCCESS') {
			alert('Saved successfully');
			new Ajax.Updater(
				'lolly_keywords',
				'/manage_channels/lolly_keywords/'+$('channel_id').value,
				{ evalScripts: true}
			);
			return;
		}
		switch(response.error) {
		case 'INVALID_DATA':
			alert('Invalid keywords');
			return;
		case 'NOT_ADMIN':
			alert('You are not an administrator.');
			return;
		case 'INVALID_CHANNEL':
			alert('Invalid channel.');
			return;
		}
	},
	changeDwVideo: function(videoId) {
//		alert('change dw video '+videoId);
		var dwVideoId = prompt("Input DW Video ID. To Delete DW Video, input 0.", "DW Video ID here");
		if(!dwVideoId) return;
		
		new Ajax.Request(
			'/manage_channels/on_change_dw_video/'+videoId+'/'+dwVideoId,
			{
				evalScripts: true,
				onComplete: this.onChangeDwVideo.bind(this)
			}
		);
	},
	onChangeDwVideo: function(transport, response) {
		if(response.result == 'SUCCESS') {
			this.refresh();
			return;
		}
		switch(response.error) {
		case 'NOT_ADMIN':
			alert('You are not an administrator');
			return;
		case 'INVALID_VIDEO':
			alert('The video is deleted.');
			return;
		case 'INVALID_AWS_VIDEO':
			alert('Invalid DW Video ID. Please insert available DW Video ID');
			return;
		case 'DB_ERROR':
			alert('Fail to change. Please try again.');
			return;
		}
	}
};
ViiKii.Channel.Manage = {};
ViiKii.Channel.Manage.Moderator = {
	changeUrl: function() {
		var url = encodeURIComponent($('channel_url').value);
		new Ajax.Updater(
			'change_manager_content',
			'/manage_channels/change_manager_channel_url/'+url,
			{ evalScripts: true }
		);
	},
	refreshUrl: function() {
		new Ajax.Updater(
			'change_manager_content',
			'/manage_channels/change_manager_channel_id/'+$('channel_id').value,
			{ evalScripts: true }
		);
	},
	changeManager: function() {
		new Ajax.Request(
			'/manage_channels/on_change_manager/'+$('channel_id').value+'/'+$('new_manager').value,
			{
				evalScripts: true,
				onComplete: this.onChangeManager.bind(this)
			}
		);
	},
	onChangeManager: function(transport, response) {
//		alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			alert('Successfully changed!');
			this.refreshUrl();
			return;
		}
		switch(response.error) {
		case 'NOT_ADMIN':
			alert('You are not an administrator.');
			return;
		case 'INVALID_USER':
			alert('Invalid Username.');
			return;
		case 'DB_ERROR':
			alert('Fail to change manager. Please try again.');
			return;
		default:
			alert(response.error);
			return;
		}
	},	addModerator: function() {
		var languageComboBox = $('moderator_language');
		var language =  languageComboBox.options[languageComboBox.selectedIndex].value;
		new Ajax.Request(
			'/manage_channels/on_add_moderator/'+$('channel_id').value+'/'+language+'/'+$('new_moderator').value,
			{
				evalScripts: true,
				onComplete: this.onAddModerator.bind(this)
			}
		);
	},
	onAddModerator: function(transport, response) {
//		alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			alert('Successfully added!');
			this.refreshUrl();
			return;
		}
		switch(response.error) {
		case 'NOT_ADMIN':
			alert('You are not an administrator.');
			return;
		case 'INVALID_USER':
			alert('Invalid Username.');
			return;
		case 'ALREADY_MODERATOR':
			alert('The user is already an moderator of this channel.');
			this.refreshUrl();
		case 'DB_ERROR':
			alert('Fail to add new moderator. Please try again.');
			return;
		default:
			alert(response.error);
			return;
		}
	},
	removeModerator: function(userName) {
		new Ajax.Request(
			'/manage_channels/on_remove_moderator/'+$('channel_id').value+'/'+userName,
			{
				evalScripts: true,
				onComplete: this.onRemoveModerator.bind(this)
			}
		);
	},
	onRemoveModerator: function(transport, response) {
//		alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			alert('Successfully removed!');
			this.refreshUrl();
			return;
		}
		switch(response.error) {
		case 'NOT_ADMIN':
			alert('You are not an administrator.');
			return;
		case 'INVALID_USER':
			alert('Invalid Username.');
			return;
		default:
			alert(response.error);
			return;
		}
	}
};ViiKii.Contributor = {
	version: '0.1',
	name: 'ContributorsController',
	language: 'null',
	pageNum: 1,
	orderBy: 'tot',
	inOrder: 1,
	myRankPage: 1,
	_popUpUrl: '/contributors/popup/',
	_listUrl: '/contributors/listing/',
	popUpLayerName: 'ViiKii.Contributor',
	popUpContributor: function(language){
		/*
		this.init(language);
		var requestUrl = this._popUpUrl + language;
		new Ajax.Request(requestUrl,
			{
				asynchronous: true,
				evalScripts: true,
				parameters: null,
				onSuccess: this.onCompletePopupContributor,
				onFailure: this.onErrorPopupContributor
			}
		);
		*/
	},
	init: function(language) {
		this.language = language;
		this.pageNum = 1;
		this.orderBy = 'tot';
		this.inOrder = 1;
		this.myRankPage = 1;
	},
	/*
	onCompletePopupContributor: function(transport) {
		$(ViiKii.Contributor.popUpLayerName).innerHTML = transport.responseText;
	},
	onErrorPopupContributor: function(transport) {
		alert("onErrorPopupContributor"+transport);
	},
	*/
	loadLanguage: function(language) {
		this.updateList(language, 1, 'tot', 1);
	},
	loadList: function(orderBy, inOrder) {
		this.updateList(this.language, 1, orderBy, inOrder);
	},
	loadPage: function(pageNum) {
		this.updateList(this.language, pageNum, this.orderBy, this.inOrder);
	},
	updateList: function(language, pageNum, orderBy, inOrder) {
		this.language = language;
		this.pageNum = pageNum;
		this.orderBy = orderBy;
		this.inOrder = inOrder;
		var requestUrl = this._listUrl + this.language + '/'+this.pageNum+'/' + this.orderBy + '/' + this.inOrder;
		var response = new Ajax.Request(requestUrl,
			{
				asynchronous: true,
				evalScripts: true,
				parameters: null,
				onSuccess: this.onCompleteLoadList,
				onFailure: this.onErrorLoadList
			}
		);
	},
	onCompleteLoadList: function(transport) {
		$("ContributorList").innerHTML = transport.responseText.stripScripts();
		setTimeout(function() {transport.responseText.evalScripts();}, 10);
	},
	onErrorLoadList: function(transport) {
		alert("onErrorLoadList"+transport);
	},
	openMyViiKii: function(userId) {
		ViiKii.My.Open(userId);
	}
};
/**********************************************************************
	Version: FreeRichTextEditor.com Version 1.00.
	License: http://creativecommons.org/licenses/by/2.5/
	Description: Configuration File.
	Author: Copyright (C) 2006  Steven Ewing
**********************************************************************/
// Width of the rich text editor.
rteWidth = "100%";
// Name of the IFRAME (content editor).
rteName = "freeRTE";
// Name of the hidden form field.
rteFormName = "freeRTE_content";
// Height of the rich text editor.
rteHeight = "150px";
// Path to the images folder.
rteImagePath = "http://vkeditor.viikii.net/";
// Path to insert form popup.
rteHTMLPathInsertForm = "/editor/insert_form.html";
// Path to insert checkbox popup.
rteHTMLPathInsertCheckbox = "/editor/insert_checkbox.html";
// Path to insert radio button popup.
rteHTMLPathInsertRadiobutton = "/editor/insert_radiobutton.html";
// Path to insert text area popup.
rteHTMLPathInsertTextArea = "/editor/insert_textarea.html";
// Path to insert submit button popup.
rteHTMLPathInsertSubmit = "/editor/insert_submit.html";
// Path to insert image submit button popup.
rteHTMLPathInsertImageSubmit = "/editor/insert_image_submit.html";
// Path to reset form button popup.
rteHTMLPathInsertReset = "/editor/insert_reset.html";
// Path to insert hidden form field popup.
rteHTMLPathInsertHidden = "/editor/insert_hidden.html";
// Path to insert password field popup.
rteHTMLPathInsertPassword = "/editor/insert_password.html";
// Path to insert text field popup.
rteHTMLPathInsertText = "/editor/insert_text.html";
// Path to insert table popup.
rteHTMLPathInsertTable = "/editor/insert_table.html";
// Path to edit table properties popup.
rteHTMLPathEditTable = "/editor/edit_table.html";
// Path to insert link popup.
rteHTMLPathInsertLink = "/editor/insert_link.html";
// Path to edit link popup.
rteHTMLPathEditLink = "/editor/edit_link.html";
// Path to insert image popup.
rteHTMLPathInsertImage = "/editor/insert_image.html";
// Format Menu (H1, H2, H3 etc etc).
rteFormat = true;
// Font Face Menu (Arial, Verdana etc etc).
rteFontFace = true;
// Font Size Menu (1, 2, etc etc).
rteFontSize = true;
// Font Color Menu.
rteFontColor = true;
// Bold Text Button.
rteBold = true;
// Italicize Text Button.
rteItalic = true;
// Underline Text Button.
rteUnderline = true;
// Strikethrough Text Button.
rteStrikeThrough = true;
// Left Justify Button.
rteLeftAlign = true;
// Center Justify Button.
rteCenterAlign = true;
// Right Justify Button.
rteRightAlign = true;
// Full Justify Button.
rteFullAlign = true;
// Insert Horizontal Rule Button.
rteHorizontalRule = true;
// Superscript Text Button.
rteSuperscript = false;
// Subscript Text Button.
rteSubscript = false;
// Insert Hyperlink Button.
rteLink = true;
// Remove Hyperlink Button.
rteUnlink = true;
// Insert Image Button.
rteImages = true;
// Remove Formatting Button.
rteRemoveFormat = true;
// Table Formatting Buttons.
rteTables = true;
// Insert an ordered list Button.
rteOrderedList = true;
// Insert an unordered list Button.
rteUnorderedList = true;
// Indent Button.
rteIndent = true;
// Outdent Button.
rteOutdent = true;
// Undo Button.
rteUndo = false;
// Redo Button.
rteRedo = false;
// Cut, Copy & Paste Buttons.
rteCutCopyPaste = false;
// Insert form button.
rteInsertForm = false;
// Insert checkbox button.
rteInsertCheckbox = false;
// Insert radio button.
rteInsertRadio = false;
// Insert textarea.
rteInsertTextArea = false;
// Insert submit button.
rteInsertSubmit = false;
// Insert image submit button.
rteInsertImageSubmit = false;
// Insert reset button.
rteInsertReset = false;
// Insert hidden field.
rteInsertHidden = false;
// Insert password field.
rteInsertPassword = false;
// Insert text field.
rteInsertTextField = false;
// Print Rich Text Area Content.
rtePrint = false;
// Select All of Rich Text Area Content.
rteSelectAll = false;
// Spell Checker.
rteShowSpellCheck = false;
// About
rteShowAbout = false;

// Show Tool Bar 1
rteToolbar1 = true;
// Show Tool Bar 1
rteToolbar2 = true;
// Show Tool Bar 3
rteToolbar3 = false;

// Show Design Mode Button.
rteDesignMode = false;
// Show Code Edit Button.
rteCodeMode = false;
// Show Preview Button.
rtePreviewMode = false;

// Insert image popup window
rteInsertImagePopupWindow = null;
// Insert image upload url
rteImageUploadUrl = '';

/*******************************************************************************
 * Version: FreeRichTextEditor.com Version 1.00. License:
 * http://creativecommons.org/licenses/by/2.5/ Description: RunTime File.
 * Author: Copyright (C) 2006 Steven Ewing
 * *********************************************************************
 * Html2Xhtml : Javascript Mini HTML to XHTML Parser Copyright (C) 2006 All
 * rights reserved. Jacob Lee <letsgolee@lycos.co.kr> Free for noncommercial &&
 * commercial use.
 ******************************************************************************/
function Html2Xhtml(data) {
	this.data = data || '';
}
Html2Xhtml.prototype.setHTML = function(data) {
	this.data = data || this.data;
};
Html2Xhtml.prototype.parse = function() {
	var state = 0;
	var xhtml = '';
	var p = 0;
	var unget = false;
	var tagname = '';
	var attrname = '';
	var attrval = '';
	var quot = '';
	var data = this.data;
	var len = data.length;
	var phpval = '';
	var tagtype = 0;
	var insidepre = false;
	while (1) {
		if (p >= len && !unget) {
			return xhtml;
		}
		if (unget) {
			unget = false;
		} else {
			var c = data.substr(p++, 1);
		}
		switch (state) {
			case 0 :
				if (c == '<') {
					state = 1;
					break;
				}
				var cc = c.charCodeAt();
				if (Html2Xhtml.charEntities[cc]) {
					xhtml += '&' + Html2Xhtml.charEntities[cc] + ';';
				} else {
					xhtml += c;
				}
				break;
			case 1 :
				if (/[a-zA-Z]/.test(c)) {
					state = 2;
					tagtype = 1;
					tagname = c.toLowerCase();
					break;
				}
				if (c == '/') {
					state = 2;
					tagtype = -1;
					break;
				}
				if (c == '!') {
					if (data.substr(p, 2) == '--') {
						xhtml += '<!--';
						p += 2;
						state = 9;
						break;
					}
					xhtml += '<!';
					state = 10;
					break;
				}
				if (c == '?') {
					state = 11;
					xhtml += '<' + '?';
					break;
				}
				xhtml += '&lt;';
				unget = true;
				state = 0;
				break;
			case 2 :
				if (Html2Xhtml.isSpaceChar[c]) {
					xhtml += (!insidepre && tagtype > 0 && Html2Xhtml.hasNLBefore[tagname] && xhtml.length && xhtml.substr(xhtml.length - 1, 1) != '\n' ? '\n' : '') + (tagtype > 0 ? '<' : '</') + tagname;
					state = 3;
					break;
				}
				if (c == '/') {
					xhtml += (!insidepre && tagtype > 0 && Html2Xhtml.hasNLBefore[tagname] && xhtml.length && xhtml.substr(xhtml.length - 1, 1) != '\n' ? '\n' : '') + (tagtype > 0 ? '<' : '</') + tagname;
					if (data.substr(p, 1) != '>') {
						state = 3;
						break;
					}
					state = 4;
					break;
				}
				if (c == '>') {
					xhtml += (!insidepre && tagtype > 0 && Html2Xhtml.hasNLBefore[tagname] && xhtml.length && xhtml.substr(xhtml.length - 1, 1) != '\n' ? '\n' : '') + (tagtype > 0 ? '<' : '</') + tagname;
					unget = true;
					state = 4;
					break;
				}
				tagname += c.toLowerCase();
				break;
			case 3 :
				if (Html2Xhtml.isSpaceChar[c]) {
					break;
				}
				if (c == '/') {
					if (data.substr(p, 1) != '>') {
						break;
					}
					state = 4;
					break;
				}
				if (c == '>') {
					unget = true;
					state = 4;
					break;
				}
				attrname = c.toLowerCase();
				attrval = '';
				state = 5;
				break;
			case 4 :
				xhtml += (Html2Xhtml.isEmptyTag[tagname] ? ' />' : '>') + (!insidepre && tagtype < 0 && Html2Xhtml.hasNLAfter[tagname] && p < len && data.substr(p, 1) != '\n' ? '\n' : '');
				if (tagtype > 0 && Html2Xhtml.dontAnalyzeContent[tagname]) {
					state = 13;
					attrname = attrval = quot = '';
					tagtype = 0;
					break;
				}
				if (tagname == 'pre') {
					insidepre = !insidepre;
				}
				state = 0;
				tagname = attrname = attrval = quot = '';
				tagtype = 0;
				break;
			case 5 :
				if (Html2Xhtml.isSpaceChar[c]) {
					xhtml += ' ' + attrname;
					if (Html2Xhtml.isEmptyAttr[attrname]) {
						xhtml += '="' + attrname + '"';
					}
					state = 3;
					break;
				}
				if (c == '/') {
					xhtml += ' ' + attrname;
					if (Html2Xhtml.isEmptyAttr[attrname]) {
						xhtml += '="' + attrname + '"';
					}
					if (data.substr(p, 1) != '>') {
						state = 3;
						break;
					}
					state = 4;
					break;
				}
				if (c == '>') {
					xhtml += ' ' + attrname;
					if (Html2Xhtml.isEmptyAttr[attrname]) {
						xhtml += '="' + attrname + '"';
					}
					unget = true;
					state = 4;
					break;
				}
				if (c == '=') {
					xhtml += ' ' + attrname + '=';
					state = 6;
					break;
				}
				if (c == '"' || c == "'") {
					attrname += '?';
				} else {
					attrname += c.toLowerCase();
				}
				break;
			case 6 :
				if (Html2Xhtml.isSpaceChar[c]) {
					xhtml += (Html2Xhtml.isEmptyAttr[attrname] ? '"' + attrname + '"' : '""');
					state = 3;
					break;
				}
				if (c == '>') {
					xhtml += (Html2Xhtml.isEmptyAttr[attrname] ? '"' + attrname + '"' : '""');
					unget = true;
					state = 4;
					break;
				}
				if (c == '/' && data.substr(p, 1) == '>') {
					xhtml += (Html2Xhtml.isEmptyAttr[attrname] ? '"' + attrname + '"' : '""');
					state = 4;
					break;
				}
				if (c == '"' || c == "'") {
					quot = c;
					state = 8;
					break;
				}
				attrval = c;
				state = 7;
				break;
			case 7 :
				if (Html2Xhtml.isSpaceChar[c]) {
					xhtml += '"' + Html2Xhtml.escapeQuot(attrval, '"') + '"';
					state = 3;
					break;
				}
				if (c == '/' && data.substr(p, 1) == '>') {
					xhtml += '"' + Html2Xhtml.escapeQuot(attrval, '"') + '"';
					state = 4;
					break;
				}
				if (c == '>') {
					unget = true;
					xhtml += '"' + Html2Xhtml.escapeQuot(attrval, '"') + '"';
					state = 4;
					break;
				}
				attrval += c;
				break;
			case 8 :
				if (c == quot) {
					xhtml += '"' + Html2Xhtml.escapeQuot(attrval, '"') + '"';
					state = 3;
					break;
				}
				attrval += c;
				break;
			case 9 :
				if (c == '-' && data.substr(p, 2) == '->') {
					p += 2;
					xhtml += '-->';
					state = 0;
					break;
				}
				xhtml += c;
				break;
			case 10 :
				if (c == '>') {
					state = 0;
				}
				xhtml += c;
				break;
			case 11 :
				if (c == "'" || c == '"') {
					quot = c;
					state = 12;
					break;
				}
				if (c == '?' && data.substr(p, 1) == '>') {
					state = 0;
					xhtml += '?' + '>';
					p++;
					break;
				}
				xhtml += c;
				break;
			case 12 :
				if (c == quot) {
					state = 11;
					xhtml += quot + Html2Xhtml.escapeQuot(phpval, quot) + quot;
					phpval = quot = '';
					break;
				}
				phpval += c;
				break;
			case 13 :
				if (c == '<' && data.substr(p, tagname.length + 1).toLowerCase() == '/' + tagname) {
					unget = true;
					state = 0;
					tagname = '';
					break;
				}
				if (tagname == 'textarea') {
					xhtml += Html2Xhtml.escapeHTMLChar(c);
				} else {
					xhtml += c;
				}
				break;
		}
	}
	return xhtml;
};
Html2Xhtml.escapeQuot = function(str, quot) {
	if (!quot) {
		quot = '"';
	}
	if (quot == '"') {
		return str.replace(/"/ig, '\\"');
	}
	return str.replace(/'/ig, "\\'");
};
Html2Xhtml.escapeHTMLChar = function(c) {
	if (c == '&') {
		return '&amp;';
	}
	if (c == '<') {
		return '&lt;';
	}
	if (c == '>') {
		return '&gt;';
	}
	var cc = c.charCodeAt();
	if (Html2Xhtml.charEntities[cc]) {
		return '&' + Html2Xhtml.charEntities[cc] + ';';
	} else {
		return c;
	}
};
Html2Xhtml.isSpaceChar = {
	' ' : 1,
	'\r' : 1,
	'\n' : 1,
	'\t' : 1
};
Html2Xhtml.isEmptyTag = {
	'area' : 1,
	'base' : 1,
	'basefont' : 1,
	'br' : 1,
	'hr' : 1,
	'img' : 1,
	'input' : 1,
	'link' : 1,
	'meta' : 1,
	'param' : 1
};
Html2Xhtml.isEmptyAttr = {
	'checked' : 1,
	'compact' : 1,
	'declare' : 1,
	'defer' : 1,
	'disabled' : 1,
	'ismap' : 1,
	'multiple' : 1,
	'noresize' : 1,
	'nosave' : 1,
	'noshade' : 1,
	'nowrap' : 1,
	'readonly' : 1,
	'selected' : 1
};
Html2Xhtml.hasNLBefore = {
	'div' : 1,
	'p' : 1,
	'table' : 1,
	'tbody' : 1,
	'tr' : 1,
	'td' : 1,
	'th' : 1,
	'title' : 1,
	'head' : 1,
	'body' : 1,
	'script' : 1,
	'comment' : 1,
	'li' : 1,
	'meta' : 1,
	'h1' : 1,
	'h2' : 1,
	'h3' : 1,
	'h4' : 1,
	'h5' : 1,
	'h6' : 1,
	'hr' : 1,
	'ul' : 1,
	'ol' : 1,
	'option' : 1,
	'link' : 1
};
Html2Xhtml.hasNLAfter = {
	'html' : 1,
	'head' : 1,
	'body' : 1,
	'p' : 1,
	'th' : 1,
	'style' : 1
};
Html2Xhtml.dontAnalyzeContent = {
	'textarea' : 1,
	'script' : 1,
	'style' : 1
};
Html2Xhtml.charEntities = {
	160 : 'nbsp',
	161 : 'iexcl',
	162 : 'cent',
	163 : 'pound',
	164 : 'curren',
	165 : 'yen',
	166 : 'brvbar',
	167 : 'sect',
	168 : 'uml',
	169 : 'copy',
	170 : 'ordf',
	171 : 'laquo',
	172 : 'not',
	173 : 'shy',
	174 : 'reg',
	175 : 'macr',
	176 : 'deg',
	177 : 'plusmn',
	178 : 'sup2',
	179 : 'sup3',
	180 : 'acute',
	181 : 'micro',
	182 : 'para',
	183 : 'middot',
	184 : 'cedil',
	185 : 'sup1',
	186 : 'ordm',
	187 : 'raquo',
	188 : 'frac14',
	189 : 'frac12',
	190 : 'frac34',
	191 : 'iquest',
	192 : 'agrave',
	193 : 'aacute',
	194 : 'acirc',
	195 : 'atilde',
	196 : 'auml',
	197 : 'aring',
	198 : 'aelig',
	199 : 'ccedil',
	200 : 'egrave',
	201 : 'eacute',
	202 : 'ecirc',
	203 : 'euml',
	204 : 'igrave',
	205 : 'iacute',
	206 : 'icirc',
	207 : 'iuml',
	208 : 'eth',
	209 : 'ntilde',
	210 : 'ograve',
	211 : 'oacute',
	212 : 'ocirc',
	213 : 'otilde',
	214 : 'ouml',
	215 : 'times',
	216 : 'oslash',
	217 : 'ugrave',
	218 : 'uacute',
	219 : 'ucirc',
	220 : 'uuml',
	221 : 'yacute',
	222 : 'thorn',
	223 : 'szlig',
	224 : 'agrave',
	225 : 'aacute',
	226 : 'acirc',
	227 : 'atilde',
	228 : 'auml',
	229 : 'aring',
	230 : 'aelig',
	231 : 'ccedil',
	232 : 'egrave',
	233 : 'eacute',
	234 : 'ecirc',
	235 : 'euml',
	236 : 'igrave',
	237 : 'iacute',
	238 : 'icirc',
	239 : 'iuml',
	240 : 'eth',
	241 : 'ntilde',
	242 : 'ograve',
	243 : 'oacute',
	244 : 'ocirc',
	245 : 'otilde',
	246 : 'ouml',
	247 : 'divide',
	248 : 'oslash',
	249 : 'ugrave',
	250 : 'uacute',
	251 : 'ucirc',
	252 : 'uuml',
	253 : 'yacute',
	254 : 'thorn',
	255 : 'yuml',
	338 : 'oelig',
	339 : 'oelig',
	352 : 'scaron',
	353 : 'scaron',
	376 : 'yuml',
	710 : 'circ',
	732 : 'tilde',
	8194 : 'ensp',
	8195 : 'emsp',
	8201 : 'thinsp',
	8204 : 'zwnj',
	8205 : 'zwj',
	8206 : 'lrm',
	8207 : 'rlm',
	8211 : 'ndash',
	8212 : 'mdash',
	8216 : 'lsquo',
	8217 : 'rsquo',
	8218 : 'sbquo',
	8220 : 'ldquo',
	8221 : 'rdquo',
	8222 : 'bdquo',
	8224 : 'dagger',
	8225 : 'dagger',
	8240 : 'permil',
	8249 : 'lsaquo',
	8250 : 'rsaquo',
	8364 : 'euro',
	402 : 'fnof',
	913 : 'alpha',
	914 : 'beta',
	915 : 'gamma',
	916 : 'delta',
	917 : 'epsilon',
	918 : 'zeta',
	919 : 'eta',
	920 : 'theta',
	921 : 'iota',
	922 : 'kappa',
	923 : 'lambda',
	924 : 'mu',
	925 : 'nu',
	926 : 'xi',
	927 : 'omicron',
	928 : 'pi',
	929 : 'rho',
	931 : 'sigma',
	932 : 'tau',
	933 : 'upsilon',
	934 : 'phi',
	935 : 'chi',
	936 : 'psi',
	937 : 'omega',
	945 : 'alpha',
	946 : 'beta',
	947 : 'gamma',
	948 : 'delta',
	949 : 'epsilon',
	950 : 'zeta',
	951 : 'eta',
	952 : 'theta',
	953 : 'iota',
	954 : 'kappa',
	955 : 'lambda',
	956 : 'mu',
	957 : 'nu',
	958 : 'xi',
	959 : 'omicron',
	960 : 'pi',
	961 : 'rho',
	962 : 'sigmaf',
	963 : 'sigma',
	964 : 'tau',
	965 : 'upsilon',
	966 : 'phi',
	967 : 'chi',
	968 : 'psi',
	969 : 'omega',
	977 : 'thetasym',
	978 : 'upsih',
	982 : 'piv',
	8226 : 'bull',
	8230 : 'hellip',
	8242 : 'prime',
	8243 : 'prime',
	8254 : 'oline',
	8260 : 'frasl',
	8472 : 'weierp',
	8465 : 'image',
	8476 : 'real',
	8482 : 'trade',
	8501 : 'alefsym',
	8592 : 'larr',
	8593 : 'uarr',
	8594 : 'rarr',
	8595 : 'darr',
	8596 : 'harr',
	8629 : 'crarr',
	8656 : 'larr',
	8657 : 'uarr',
	8658 : 'rarr',
	8659 : 'darr',
	8660 : 'harr',
	8704 : 'forall',
	8706 : 'part',
	8707 : 'exist',
	8709 : 'empty',
	8711 : 'nabla',
	8712 : 'isin',
	8713 : 'notin',
	8715 : 'ni',
	8719 : 'prod',
	8721 : 'sum',
	8722 : 'minus',
	8727 : 'lowast',
	8730 : 'radic',
	8733 : 'prop',
	8734 : 'infin',
	8736 : 'ang',
	8743 : 'and',
	8744 : 'or',
	8745 : 'cap',
	8746 : 'cup',
	8747 : 'int',
	8756 : 'there4',
	8764 : 'sim',
	8773 : 'cong',
	8776 : 'asymp',
	8800 : 'ne',
	8801 : 'equiv',
	8804 : 'le',
	8805 : 'ge',
	8834 : 'sub',
	8835 : 'sup',
	8836 : 'nsub',
	8838 : 'sube',
	8839 : 'supe',
	8853 : 'oplus',
	8855 : 'otimes',
	8869 : 'perp',
	8901 : 'sdot',
	8968 : 'lceil',
	8969 : 'rceil',
	8970 : 'lfloor',
	8971 : 'rfloor',
	9001 : 'lang',
	9002 : 'rang',
	9426 : 'copy',
	9674 : 'loz',
	9824 : 'spades',
	9827 : 'clubs',
	9829 : 'hearts',
	9830 : 'diams'
};
function getXHTML(data) {
	return new Html2Xhtml(data).parse();
}
function trim(str) {
	if (typeof str != "string") {
		return str;
	}
	str = str.replace(/^\s+|\s+$/g, "");
	return str;
}
function rteGetOffsetTop(elm) {
	var mOffsetTop = elm.offsetTop;
	var mOffsetParent = elm.offsetParent;
	while (mOffsetParent) {
		mOffsetTop += mOffsetParent.offsetTop;
		mOffsetParent = mOffsetParent.offsetParent;
	}
	return mOffsetTop;
}
function rteGetOffsetLeft(elm) {
	var mOffsetLeft = elm.offsetLeft;
	var mOffsetParent = elm.offsetParent;
	while (mOffsetParent) {
		mOffsetLeft += mOffsetParent.offsetLeft;
		mOffsetParent = mOffsetParent.offsetParent;
	}
	return mOffsetLeft;
}
function rteMouseOverMenuFontColorContents() {
	this.className = "rtedropdown14";
}
function rteMouseOutMenuFontColorContents() {
	this.className = "rtedropdown13";
}
function rteMouseOverFormatMenu() {
	document.getElementById("format1").className = "rtedropdown4";
	document.getElementById("format2").className = "rtedropdown5";
}
function rteMouseOutFormatMenu() {
	document.getElementById("format1").className = "rtedropdown1";
	document.getElementById("format2").className = "rtedropdown2";
}
function rteMouseOverFontFaceMenu() {
	document.getElementById("fontface1").className = "rtedropdown4";
	document.getElementById("fontface2").className = "rtedropdown5";
}
function rteMouseOutFontFaceMenu() {
	document.getElementById("fontface1").className = "rtedropdown1";
	document.getElementById("fontface2").className = "rtedropdown2";
}
function rteMouseOverFontSizeMenu() {
	document.getElementById("fontsize1").className = "rtedropdown4";
	document.getElementById("fontsize2").className = "rtedropdown5";
}
function rteMouseOutFontSizeMenu() {
	document.getElementById("fontsize1").className = "rtedropdown1";
	document.getElementById("fontsize2").className = "rtedropdown2";
}
function rteMouseOverFontColorMenu() {
	document.getElementById("fontcolor1").className = "rtedropdown8";
	document.getElementById("fontcolor2").className = "rtedropdown5b";
}
function rteMouseOutFontColorMenu() {
	document.getElementById("fontcolor1").className = "rtedropdown10";
	document.getElementById("fontcolor2").className = "rtedropdown11b";
}
function rteBtnMouseUpBottom() {
	this.className = "rtebtn9";
}
function rteBtnMouseOutBottom() {
	this.className = "rtebtn6";
}
function rteBtnMouseOutDownBottom() {
	this.className = "rtebtn9";
}
function rteBtnMouseOverBottom() {
	this.className = "rtebtn7";
}
function rteHideMenus() {
	rteMouseOutFormatMenu();
	document.getElementById("format3").style.display = "none";
	rteMouseOutFontFaceMenu();
	document.getElementById("fontface3").style.display = "none";
	rteMouseOutFontSizeMenu();
	document.getElementById("fontsize3").style.display = "none";
	rteMouseOutFontColorMenu();
	document.getElementById("fontcolor3").style.display = "none";
}
function rteMouseOverMenuContents() {
	this.style.color = "#FFFFFF";
	this.style.backgroundColor = "#316AC5";
	document.getElementById(rteName).contentWindow.focus();
}
function rteMouseOutMenuContents() {
	this.style.color = "#000000";
	this.style.backgroundColor = "#FFFFFF";
}
function rteMouseDownMenuContents() {
	if (this.innerHTML == "Header 1") {
		document.getElementById(rteName).contentWindow.document.execCommand("formatblock", false, "<h1>");
		document.getElementById("format1").innerHTML = "Header 1";
	} else if (this.innerHTML == "Header 2") {
		document.getElementById(rteName).contentWindow.document.execCommand("formatblock", false, "<h2>");
		document.getElementById("format1").innerHTML = "Header 2";
	} else if (this.innerHTML == "Header 3") {
		document.getElementById(rteName).contentWindow.document.execCommand("formatblock", false, "<h3>");
		document.getElementById("format1").innerHTML = "Header 3";
	} else if (this.innerHTML == "Header 4") {
		document.getElementById(rteName).contentWindow.document.execCommand("formatblock", false, "<h4>");
		document.getElementById("format1").innerHTML = "Header 4";
	} else if (this.innerHTML == "Header 5") {
		document.getElementById(rteName).contentWindow.document.execCommand("formatblock", false, "<h5>");
		document.getElementById("format1").innerHTML = "Header 5";
	} else if (this.innerHTML == "Header 6") {
		document.getElementById(rteName).contentWindow.document.execCommand("formatblock", false, "<h6>");
		document.getElementById("format1").innerHTML = "Header 6";
	} else if (this.innerHTML == "Paragraph") {
		document.getElementById(rteName).contentWindow.document.execCommand("formatblock", false, "<p>");
		document.getElementById("format1").innerHTML = "Paragraph";
	} else if (this.innerHTML == "Arial") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontname", false, "arial");
		document.getElementById("fontface1").innerHTML = "Arial";
	} else if (this.innerHTML == "Arial Black") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontname", false, "arial black");
		document.getElementById("fontface1").innerHTML = "Arial Black";
	} else if (this.innerHTML == "Arial Narrow") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontname", false, "arial narrow");
		document.getElementById("fontface1").innerHTML = "Arial Narrow";
	} else if (this.innerHTML == "Courier New") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontname", false, "courier new");
		document.getElementById("fontface1").innerHTML = "Courier New";
	} else if (this.innerHTML == "Century Gothic") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontname", false, "century gothic");
		document.getElementById("fontface1").innerHTML = "Century Gothic";
	} else if (this.innerHTML == "Comic Sans MS") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontname", false, "comic sans ms");
		document.getElementById("fontface1").innerHTML = "Comic Sans MS";
	} else if (this.innerHTML == "Impact") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontname", false, "impact");
		document.getElementById("fontface1").innerHTML = "Impact";
	} else if (this.innerHTML == "Tahoma") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontname", false, "tahoma");
		document.getElementById("fontface1").innerHTML = "Tahoma";
	} else if (this.innerHTML == "Times New Roman") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontname", false, "times new roman");
		document.getElementById("fontface1").innerHTML = "Times New Roman";
	} else if (this.innerHTML == "Trebuchet MS") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontname", false, "trebuchet ms");
		document.getElementById("fontface1").innerHTML = "Trebuchet MS";
	} else if (this.innerHTML == "Verdana") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontname", false, "verdana");
		document.getElementById("fontface1").innerHTML = "Verdana";
	} else if (this.innerHTML == "1") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontsize", false, "1");
		document.getElementById("fontsize1").innerHTML = "1";
	} else if (this.innerHTML == "2") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontsize", false, "2");
		document.getElementById("fontsize1").innerHTML = "2";
	} else if (this.innerHTML == "3") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontsize", false, "3");
		document.getElementById("fontsize1").innerHTML = "3";
	} else if (this.innerHTML == "4") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontsize", false, "4");
		document.getElementById("fontsize1").innerHTML = "4";
	} else if (this.innerHTML == "5") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontsize", false, "5");
		document.getElementById("fontsize1").innerHTML = "5";
	} else if (this.innerHTML == "6") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontsize", false, "6");
		document.getElementById("fontsize1").innerHTML = "6";
	} else if (this.innerHTML == "7") {
		document.getElementById(rteName).contentWindow.document.execCommand("fontsize", false, "7");
		document.getElementById("fontsize1").innerHTML = "7";
	}
	this.style.color = "#000000";
	this.style.backgroundColor = "#FFFFFF";
	rteHideMenus();
}
function rteColorClick(hexcolor) {
	rteHideMenus();
	// because of IE bug
	document.getElementById(rteName).contentWindow.focus();
	document.getElementById(rteName).contentWindow.document.execCommand("forecolor", false, hexcolor);
	document.getElementById("fontcolor4").style.backgroundColor = hexcolor;
}
function rteMouseDownFontFaceMenu() {
	rteHideMenus();
	document.getElementById("fontface1").className = "rtedropdown4";
	document.getElementById("fontface2").className = "rtedropdown6";
	document.getElementById("fontface1").style.left = rteGetOffsetLeft(document.getElementById("fontface1"));
	document.getElementById("fontface1").style.top = rteGetOffsetTop(document.getElementById("fontface1")) + document.getElementById("fontface1").offsetHeight;
	document.getElementById("fontface3").style.display = (document.getElementById("fontface3").style.display == "none") ? "" : "none";
	var kids = document.getElementsByTagName('DIV');
	for (var i = 0; i < kids.length; i++) {
		if (kids[i].id == "format1" || kids[i].id == "format2") {
			kids[i].onmouseout = rteMouseOutFormatMenu;
		} else if (kids[i].id == "fontface1" || kids[i].id == "fontface2") {
			kids[i].onmouseout = rteMouseDownFontFaceMenu;
		} else if (kids[i].id == "fontsize1" || kids[i].id == "fontsize2") {
			kids[i].onmouseout = rteMouseOutFontSizeMenu;
		} else if (kids[i].id == "fontcolor1" || kids[i].id == "fontcolor2") {
			kids[i].onmouseout = rteMouseOutFontColorMenu;
		}
	}
}
function rteMouseDownFontSizeMenu() {
	rteHideMenus();
	document.getElementById("fontsize1").className = "rtedropdown4";
	document.getElementById("fontsize2").className = "rtedropdown6";
	document.getElementById("fontsize1").style.left = rteGetOffsetLeft(document.getElementById("fontsize1"));
	document.getElementById("fontsize1").style.top = rteGetOffsetTop(document.getElementById("fontsize1")) + document.getElementById("fontsize1").offsetHeight;
	document.getElementById("fontsize3").style.display = (document.getElementById("fontsize3").style.display == "none") ? "" : "none";
	var kids = document.getElementsByTagName('DIV');
	for (var i = 0; i < kids.length; i++) {
		if (kids[i].id == "format1" || kids[i].id == "format2") {
			kids[i].onmouseout = rteMouseOutFormatMenu;
		} else if (kids[i].id == "fontface1" || kids[i].id == "fontface2") {
			kids[i].onmouseout = rteMouseOutFontFaceMenu;
		} else if (kids[i].id == "fontsize1" || kids[i].id == "fontsize2") {
			kids[i].onmouseout = rteMouseDownFontSizeMenu;
		} else if (kids[i].id == "fontcolor1" || kids[i].id == "fontcolor2") {
			kids[i].onmouseout = rteMouseOutFontColorMenu;
		}
	}
}
function rteMouseDownFontColorMenu() {
	rteHideMenus();
	document.getElementById("fontcolor1").className = "rtedropdown12";
	document.getElementById("fontcolor2").className = "rtedropdown9b";
	document.getElementById("fontcolor1").style.left = rteGetOffsetLeft(document.getElementById("fontcolor1"));
	document.getElementById("fontcolor1").style.top = rteGetOffsetTop(document.getElementById("fontcolor1")) + document.getElementById("fontcolor1").offsetHeight;
	document.getElementById("fontcolor3").style.display = (document.getElementById("fontcolor3").style.display == "none") ? "" : "none";
	var kids = document.getElementsByTagName('DIV');
	for (var i = 0; i < kids.length; i++) {
		if (kids[i].id == "format1" || kids[i].id == "format2") {
			kids[i].onmouseout = rteMouseOutFormatMenu;
		} else if (kids[i].id == "fontface1" || kids[i].id == "fontface2") {
			kids[i].onmouseout = rteMouseOutFontFaceMenu;
		} else if (kids[i].id == "fontsize1" || kids[i].id == "fontsize2") {
			kids[i].onmouseout = rteMouseOutFontSizeMenu;
		} else if (kids[i].id == "fontcolor1" || kids[i].id == "fontcolor2") {
			kids[i].onmouseout = rteMouseDownFontColorMenu;
		}
	}
}
function rteMouseDownFormatMenu() {
	rteHideMenus();
	document.getElementById("format1").className = "rtedropdown4";
	document.getElementById("format2").className = "rtedropdown6";
	document.getElementById("format1").style.left = rteGetOffsetLeft(document.getElementById("format1"));
	document.getElementById("format1").style.top = rteGetOffsetTop(document.getElementById("format1")) + document.getElementById("format1").offsetHeight;
	document.getElementById("format3").style.display = (document.getElementById("format3").style.display == "none") ? "" : "none";
	var kids = document.getElementsByTagName('DIV');
	for (var i = 0; i < kids.length; i++) {
		if (kids[i].id == "format1" || kids[i].id == "format2") {
			kids[i].onmouseout = rteMouseDownFormatMenu;
		} else if (kids[i].id == "fontface1" || kids[i].id == "fontface2") {
			kids[i].onmouseout = rteMouseOutFontFaceMenu;
		} else if (kids[i].id == "fontsize1" || kids[i].id == "fontsize2") {
			kids[i].onmouseout = rteMouseOutFontSizeMenu;
		} else if (kids[i].id == "fontcolor1" || kids[i].id == "fontcolor2") {
			kids[i].onmouseout = rteMouseOutFontColorMenu;
		}
	}
}
function rteFormHandler() {
	var newHTML;
	if (document.getElementById(rteFormName).style.display === "") {
		newHTML = getXHTML(trim(document.getElementById(rteFormName).value));
	} else {
		newHTML = getXHTML(trim(document.getElementById(rteName).contentWindow.document.body.innerHTML));
	}
	pattern = /<div[^>]*border: 1px dotted red[^>]*>.*<\/form><\/div>/gi;
	matchesArray = newHTML.match(pattern);
	if (matchesArray !== null) {
		for (i = 0; i < matchesArray.length; i++) {
			pattern2 = /<div[^>]*border: 1px dotted red[^>]*>/gi;
			pattern3 = /<\/div>/gi;
			replacement = matchesArray[i];
			replacement = replacement.replace(pattern2, "");
			replacement = replacement.replace(pattern3, "");
			if (document.getElementById(rteFormName).style.display === "") {
				newHTML = document.getElementById(rteFormName).value.replace(matchesArray[i], replacement);
			} else {
				newHTML = document.getElementById(rteName).contentWindow.document.body.innerHTML.replace(matchesArray[i], replacement);
			}
		}
	}
	pattern = /<table[^>]*class=\"rte_tbl\"[^>]*>/gi;
	matchesArray = newHTML.match(pattern);
	if (matchesArray !== null) {
		for (i = 0; i < matchesArray.length; i++) {
			pattern2 = /class=\"rte_tbl\"/gi;
			replacement = matchesArray[i];
			replacement = replacement.replace(pattern2, "");
			newHTML = newHTML.replace(matchesArray[i], replacement);
		}
	}
	document.getElementById(rteFormName).value = newHTML;
	document.getElementById(rteName).contentWindow.document.body.innerHTML = newHTML;
}
function rteFormHandler2() {
	var newHTML;
	if (document.getElementById(rteFormName).style.display === "") {
		newHTML = document.getElementById(rteFormName).value;
	} else {
		newHTML = document.getElementById(rteName).contentWindow.document.body.innerHTML;
	}
	pattern = /<form[^>]*>[^<]*<\/form>/gi;
	matchesArray = newHTML.match(pattern);
	if (matchesArray !== null) {
		for (i = 0; i < matchesArray.length; i++) {
			replacement = matchesArray[i];
			replacement = replacement.replace(matchesArray[i], "<div style=\"border: 1px dotted red;\">" + matchesArray[i] + "</div>");
			if (document.getElementById(rteFormName).style.display === "") {
				newHTML = document.getElementById(rteFormName).value.replace(matchesArray[i], replacement);
			} else {
				newHTML = document.getElementById(rteName).contentWindow.document.body.innerHTML.replace(matchesArray[i], replacement);
			}
		}
	}
	pattern = /<table[^>]*border=\"0\"[^>]*>/gi;
	matchesArray = newHTML.match(pattern);
	if (matchesArray !== null) {
		for (i = 0; i < matchesArray.length; i++) {
			pattern2 = /border=\"0\"/gi;
			replacement = matchesArray[i];
			replacement = replacement.replace(pattern2, "border=\"0\" class=\"rte_tbl\"");
			newHTML = newHTML.replace(matchesArray[i], replacement);
		}
	}
	if (document.getElementById(rteFormName).style.display === "") {
		document.getElementById(rteFormName).value = newHTML;
	} else {
		document.getElementById(rteName).contentWindow.document.body.innerHTML = newHTML;
	}
}
function rteModeType(id) {
	if(id === "rte_design_mode") {
		rteFormHandler2();
		document.getElementById(rteName).contentWindow.document.body.innerHTML = getXHTML(trim(document.getElementById(rteFormName).value));
		if(rteToolbar1) {
			document.getElementById("tb1").style.display = "";
		}
		if(rteToolbar2) {
			document.getElementById("tb2").style.display = "";
		}
		if(rteToolbar3) {
			document.getElementById("tb3").style.display = "";
		}
		document.getElementById(rteFormName).style.display = "none";
		document.getElementById(rteName).style.display = "";
		document.getElementById("preview_" + rteName).style.display = "none";
		document.getElementById(rteName).contentWindow.focus();
		return false;
	} else if (id === "rte_code_mode") {
		rteFormHandler();
		document.getElementById(rteFormName).value = getXHTML(trim(document.getElementById(rteName).contentWindow.document.body.innerHTML));
		if(rteToolbar1) {
			document.getElementById("tb1").style.display = "none";
		}
		if(rteToolbar2) {
			document.getElementById("tb2").style.display = "none";
		}
		if(rteToolbar3) {
			document.getElementById("tb3").style.display = "none";
		}
		document.getElementById(rteFormName).style.display = "";
		document.getElementById(rteName).style.display = "none";
		document.getElementById("preview_" + rteName).style.display = "none";
	} else if (id === "rte_preview_mode") {
		rteFormHandler();
		html = "<div style=\"padding:5px;\">" + getXHTML(trim(document.getElementById(rteFormName).value)) + "</div>";
		document.getElementById('preview_' + rteName).contentWindow.document.open();
		document.getElementById('preview_' + rteName).contentWindow.document.write("<html><head>" + "<style type=\"text/css\">@import url(" + document.getElementById("preview_css").value + ");</style>" + "</head><body>" + html + "</body></html>");
		document.getElementById('preview_' + rteName).contentWindow.document.close();
		if(rteToolbar1) {
			document.getElementById("tb1").style.display = "none";
		}
		if(rteToolbar2) {
			document.getElementById("tb2").style.display = "none";
		}
		if(rteToolbar3) {
			document.getElementById("tb3").style.display = "none";
		}
		document.getElementById(rteFormName).style.display = "none";
		document.getElementById(rteName).style.display = "none";
		document.getElementById("preview_" + rteName).style.display = "";
	}
}
function rteBtnMouseDownBottom() {
	var kids = document.getElementsByTagName("DIV");
	for (var i = 0; i < kids.length; i++) {
		if (kids[i].className === "rtebtn6" || kids[i].className == "rtebtn7" || kids[i].className == "rtebtn8" || kids[i].className == "rtebtn9") {
			kids[i].className = "rtebtn6";
			kids[i].onmouseover = rteBtnMouseOverBottom;
			kids[i].onmouseout = rteBtnMouseOutBottom;
			kids[i].onmousedown = rteBtnMouseDownBottom;
			kids[i].onmouseup = rteBtnMouseUpBottom;
		}
	}
	this.className = "rtebtn9";
	this.onmouseover = rteBtnMouseOverBottom;
	this.onmouseout = rteBtnMouseOutDownBottom;
	this.onmouseup = rteBtnMouseUpBottom;
}
function rteBtnMouseDown() {
	var kids = document.getElementsByTagName('DIV');
	for (var i = 0; i < kids.length; i++) {
		if (kids[i].className === "rtebtn2" || kids[i].className === "rtebtn3" || kids[i].className === "rtebtn4") {
			kids[i].className = "rtebtn1";
		}
	}
	rteSelection();
	this.className = "rtebtn4";
}
function rteBtnMouseUp() {
	this.className = "rtebtn4";
}
function rteBtnMouseOut() {
	this.className = "rtebtn1";
}
function rteBtnMouseOver() {
	this.className = "rtebtn2";
}
function rteAction(ID) {
	rteHideMenus();
	if (this.id !== "editlink" && this.id !== "insertflash" && this.id !== "edittable" && this.id !== "createlink" && this.id !== "insertimage" && this.id !== "inserttable" && this.id !== "insertrowbelow" && this.id !== "insertrowabove" && this.id !== "insertcolumnleft" && this.id !== "insertcolumnright" && this.id !== "deletecolumn" && this.id !== "deleterow" && this.id !== "insertform" && this.id !== "form_checkbox" && this.id !== "form_radio" && this.id !== "form_dropdown" && this.id !== "form_textarea" && this.id !== "form_submit" && this.id !== "form_image_submit" && this.id !== "form_reset" && this.id !== "form_hidden" && this.id !== "form_password" && this.id !== "form_textfield" && this.id !== "spellcheck" && this.id !== "printrte" && this.id !== "aboutrte") {
		document.getElementById(rteName).contentWindow.document.execCommand(this.id, false, null);
		document.getElementById(this.id).className = "rtebtn4";
		document.getElementById(this.id).onmouseout = rteBtnMouseDown;
		document.getElementById(rteName).contentWindow.focus();
	}
}
function rteSelection() {
	rteHideMenus();
	if (document.getElementById("rte_code_mode").className == "rtebtn9") {
		if(rteToolbar1) {
			document.getElementById("tb1").style.display = "none";
		}
		if(rteToolbar2) {
			document.getElementById("tb2").style.display = "none";
		}
		if(rteToolbar3) {
			document.getElementById("tb3").style.display = "none";
		}
	} else {
		document.getElementById("format1").innerHTML = '<div style="height:16px;">Paragraph</div>';
		document.getElementById("fontface1").innerHTML = '<div style="height:16px;">Arial</div>';
		document.getElementById("fontsize1").innerHTML = '<div style="height:16px;">2</div>';
		var kids = document.getElementsByTagName('DIV');
		for (var i = 0; i < kids.length; i++) {
			switch (kids[i].className) {
				case "rtebtn1" :
					if (kids[i].onmouseover != rteBtnMouseOver) {
						kids[i].onmouseover = rteBtnMouseOver;
					}
					if (kids[i].onclick != rteAction) {
						kids[i].onclick = rteAction;
					}
					if (kids[i].className == "rtebtn4") {
						if (kids[i].onmouseout != rteBtnMouseDown) {
							kids[i].onmouseout = rteBtnMouseDown;
						}
					} else {
						if (kids[i].onmouseout != rteBtnMouseOut) {
							kids[i].onmouseout = rteBtnMouseOut;
						}
					}
					if (kids[i].onmousedown != rteBtnMouseDown) {
						kids[i].onmousedown = rteBtnMouseDown;
					}
					if (kids[i].onmouseup != rteBtnMouseUp) {
						kids[i].onmouseup = rteBtnMouseUp;
					}
					break;
				case "rtebtn2" :
					kids[i].className = "rtebtn1";
					if (kids[i].onmouseover != rteBtnMouseOver) {
						kids[i].onmouseover = rteBtnMouseOver;
					}
					if (kids[i].onclick != rteAction) {
						kids[i].onclick = rteAction;
					}
					if (kids[i].className == "rtebtn4") {
						if (kids[i].onmouseout != rteBtnMouseDown) {
							kids[i].onmouseout = rteBtnMouseDown;
						}
					} else {
						if (kids[i].onmouseout != rteBtnMouseOut) {
							kids[i].onmouseout = rteBtnMouseOut;
						}
					}
					if (kids[i].onmousedown != rteBtnMouseDown) {
						kids[i].onmousedown = rteBtnMouseDown;
					}
					if (kids[i].onmouseup != rteBtnMouseUp) {
						kids[i].onmouseup = rteBtnMouseUp;
					}
					break;
				case "rtebtn3" :
					kids[i].className = "rtebtn1";
					if (kids[i].onmouseover != rteBtnMouseOver) {
						kids[i].onmouseover = rteBtnMouseOver;
					}
					if (kids[i].onclick != rteAction) {
						kids[i].onclick = rteAction;
					}
					if (kids[i].className == "rtebtn4") {
						if (kids[i].onmouseout != rteBtnMouseDown) {
							kids[i].onmouseout = rteBtnMouseDown;
						}
					} else {
						if (kids[i].onmouseout != rteBtnMouseOut) {
							kids[i].onmouseout = rteBtnMouseOut;
						}
					}
					if (kids[i].onmousedown != rteBtnMouseDown) {
						kids[i].onmousedown = rteBtnMouseDown;
					}
					if (kids[i].onmouseup != rteBtnMouseUp) {
						kids[i].onmouseup = rteBtnMouseUp;
					}
					break;
				case "rtebtn4" :
					kids[i].className = "rtebtn1";
					if (kids[i].onmouseover != rteBtnMouseOver) {
						kids[i].onmouseover = rteBtnMouseOver;
					}
					if (kids[i].onclick != rteAction) {
						kids[i].onclick = rteAction;
					}
					if (kids[i].onmouseout != rteBtnMouseOut) {
						kids[i].onmouseout = rteBtnMouseOut;
					}
					if (kids[i].onmousedown != rteBtnMouseDown) {
						kids[i].onmousedown = rteBtnMouseDown;
					}
					if (kids[i].onmouseup != rteBtnMouseUp) {
						kids[i].onmouseup = rteBtnMouseUp;
					}
					break;
			}
			switch (kids[i].id) {
				case "format1" :
					if (kids[i].onmouseover != rteMouseOverFormatMenu) {
						kids[i].onmouseover = rteMouseOverFormatMenu;
					}
					if (kids[i].onmousedown != rteMouseDownFormatMenu) {
						kids[i].onmousedown = rteMouseDownFormatMenu;
					}
					if (kids[i].onmouseout != rteMouseOutFormatMenu) {
						kids[i].onmouseout = rteMouseOutFormatMenu;
					}
					if (kids[i].className == "rtedropdown6") {
						if (kids[i].onmouseout != rteMouseDownFormatMenu) {
							kids[i].onmouseout = rteMouseDownFormatMenu;
						}
					} else {
						if (kids[i].onmouseout != rteMouseOutFormatMenu) {
							kids[i].onmouseout = rteMouseOutFormatMenu;
						}
					}
					break;
				case "format2" :
					if (kids[i].onmouseover != rteMouseOverFormatMenu) {
						kids[i].onmouseover = rteMouseOverFormatMenu;
					}
					if (kids[i].onmousedown != rteMouseDownFormatMenu) {
						kids[i].onmousedown = rteMouseDownFormatMenu;
					}
					if (kids[i].onmouseout != rteMouseOutFormatMenu) {
						kids[i].onmouseout = rteMouseOutFormatMenu;
					}
					if (kids[i].className == "rtedropdown6") {
						kids[i].onmouseout = rteMouseDownFormatMenu;
					} else {
						kids[i].onmouseout = rteMouseOutFormatMenu;
					}
					break;
				case "fontface1" :
					if (kids[i].onmouseover != rteMouseOverFontFaceMenu) {
						kids[i].onmouseover = rteMouseOverFontFaceMenu;
					}
					if (kids[i].onmousedown != rteMouseDownFontFaceMenu) {
						kids[i].onmousedown = rteMouseDownFontFaceMenu;
					}
					if (kids[i].onmouseout != rteMouseOutFontFaceMenu) {
						kids[i].onmouseout = rteMouseOutFontFaceMenu;
					}
					if (kids[i].className == "rtedropdown6") {
						if (kids[i].onmouseout != rteMouseDownFontFaceMenu) {
							kids[i].onmouseout = rteMouseDownFontFaceMenu;
						}
					} else {
						if (kids[i].onmouseout != rteMouseOutFontFaceMenu) {
							kids[i].onmouseout = rteMouseOutFontFaceMenu;
						}
					}
					break;
				case "fontface2" :
					if (kids[i].onmouseover != rteMouseOverFontFaceMenu) {
						kids[i].onmouseover = rteMouseOverFontFaceMenu;
					}
					if (kids[i].onmousedown != rteMouseDownFontFaceMenu) {
						kids[i].onmousedown = rteMouseDownFontFaceMenu;
					}
					if (kids[i].onmouseout != rteMouseOutFontFaceMenu) {
						kids[i].onmouseout = rteMouseOutFontFaceMenu;
					}
					if (kids[i].className == "rtedropdown6") {
						if (kids[i].onmouseout != rteMouseDownFontFaceMenu) {
							kids[i].onmouseout = rteMouseDownFontFaceMenu;
						}
					} else {
						if (kids[i].onmouseout != rteMouseOutFontFaceMenu) {
							kids[i].onmouseout = rteMouseOutFontFaceMenu;
						}
					}
					break;
				case "fontsize1" :
					if (kids[i].onmouseover != rteMouseOverFontSizeMenu) {
						kids[i].onmouseover = rteMouseOverFontSizeMenu;
					}
					if (kids[i].onmousedown != rteMouseDownFontSizeMenu) {
						kids[i].onmousedown = rteMouseDownFontSizeMenu;
					}
					if (kids[i].onmouseout != rteMouseOutFontSizeMenu) {
						kids[i].onmouseout = rteMouseOutFontSizeMenu;
					}
					if (kids[i].className == "rtedropdown6") {
						if (kids[i].onmouseout != rteMouseDownFontSizeMenu) {
							kids[i].onmouseout = rteMouseDownFontSizeMenu;
						}
					} else {
						if (kids[i].onmouseout != rteMouseOutFontSizeMenu) {
							kids[i].onmouseout = rteMouseOutFontSizeMenu;
						}
					}
					break;
				case "fontsize2" :
					if (kids[i].onmouseover != rteMouseOverFontSizeMenu) {
						kids[i].onmouseover = rteMouseOverFontSizeMenu;
					}
					if (kids[i].onmousedown != rteMouseDownFontSizeMenu) {
						kids[i].onmousedown = rteMouseDownFontSizeMenu;
					}
					if (kids[i].onmouseout != rteMouseOutFontSizeMenu) {
						kids[i].onmouseout = rteMouseOutFontSizeMenu;
					}
					if (kids[i].className == "rtedropdown6") {
						if (kids[i].onmouseout != rteMouseDownFontSizeMenu) {
							kids[i].onmouseout = rteMouseDownFontSizeMenu;
						}
					} else {
						if (kids[i].onmouseout != rteMouseOutFontSizeMenu) {
							kids[i].onmouseout = rteMouseOutFontSizeMenu;
						}
					}
					break;
				case "fontcolor1" :
					if (kids[i].onmouseover != rteMouseOverFontColorMenu) {
						kids[i].onmouseover = rteMouseOverFontColorMenu;
					}
					if (kids[i].onmousedown != rteMouseDownFontColorMenu) {
						kids[i].onmousedown = rteMouseDownFontColorMenu;
					}
					if (kids[i].onmouseout != rteMouseOutFontColorMenu) {
						kids[i].onmouseout = rteMouseOutFontColorMenu;
					}
					if (kids[i].className == "rtedropdown9") {
						if (kids[i].onmouseout != rteMouseDownFontColorMenu) {
							kids[i].onmouseout = rteMouseDownFontColorMenu;
						}
					} else {
						if (kids[i].onmouseout != rteMouseOutFontColorMenu) {
							kids[i].onmouseout = rteMouseOutFontColorMenu;
						}
					}
					break;
				case "fontcolor2" :
					if (kids[i].onmouseover != rteMouseOverFontColorMenu) {
						kids[i].onmouseover = rteMouseOverFontColorMenu;
					}
					if (kids[i].onmousedown != rteMouseDownFontColorMenu) {
						kids[i].onmousedown = rteMouseDownFontColorMenu;
					}
					if (kids[i].onmouseout != rteMouseOutFontColorMenu) {
						kids[i].onmouseout = rteMouseOutFontColorMenu;
					}
					if (kids[i].className == "rtedropdown9") {
						if (kids[i].onmouseout != rteMouseDownFontColorMenu) {
							kids[i].onmouseout = rteMouseDownFontColorMenu;
						}
					} else {
						if (kids[i].onmouseout != rteMouseOutFontColorMenu) {
							kids[i].onmouseout = rteMouseOutFontColorMenu;
						}
					}
					break;
				case "formatblock" :
					if (kids[i].onmouseover != rteMouseOverMenuContents) {
						kids[i].onmouseover = rteMouseOverMenuContents;
					}
					if (kids[i].onmouseout != rteMouseOutMenuContents) {
						kids[i].onmouseout = rteMouseOutMenuContents;
					}
					if (kids[i].onmousedown != rteMouseDownMenuContents) {
						kids[i].onmousedown = rteMouseDownMenuContents;
					}
					break;
				case "fontface" :
					if (kids[i].onmouseover != rteMouseOverMenuContents) {
						kids[i].onmouseover = rteMouseOverMenuContents;
					}
					if (kids[i].onmouseout != rteMouseOutMenuContents) {
						kids[i].onmouseout = rteMouseOutMenuContents;
					}
					if (kids[i].onmousedown != rteMouseDownMenuContents) {
						kids[i].onmousedown = rteMouseDownMenuContents;
					}
					break;
				case "fontsize" :
					if (kids[i].onmouseover != rteMouseOverMenuContents) {
						kids[i].onmouseover = rteMouseOverMenuContents;
					}
					if (kids[i].onmouseout != rteMouseOutMenuContents) {
						kids[i].onmouseout = rteMouseOutMenuContents;
					}
					if (kids[i].onmousedown != rteMouseDownMenuContents) {
						kids[i].onmousedown = rteMouseDownMenuContents;
					}
					break;
				case "fontcolor" :
					if (kids[i].onmouseover != rteMouseOverMenuFontColorContents) {
						kids[i].onmouseover = rteMouseOverMenuFontColorContents;
					}
					if (kids[i].onmouseout != rteMouseOutMenuFontColorContents) {
						kids[i].onmouseout = rteMouseOutMenuFontColorContents;
					}
					break;
			}
		}
		var tbl = false;
		var in_list = false;
		var selected_obj;
		if (window.getSelection) {
			selected_obj = document.getElementById(rteName).contentWindow.window.getSelection();
			// for safari browser
			if(selected_obj && selected_obj.focusNode) {
				selected_obj = selected_obj.focusNode;
			} else {
				selected_obj = document.getElementById(rteName).contentWindow.document.body;
			}
		} else if (document.getSelection) {
			selected_obj = document.getElementById(rteName).contentWindow.document.getSelection().focusNode;
		} else if (document.selection) {
			selected_obj = document.getElementById(rteName).contentWindow.document.selection.createRange().parentElement();
		}
		var is_link = false;
		var is_table = false;
		var current_tag = selected_obj;
		var previous_tagName = selected_obj.tagName;
		var textcolor = "";
		document.getElementById("fontcolor4").style.backgroundColor = "#000000";
		
		while (previous_tagName != "HTML") {
			if (previous_tagName === "B" || previous_tagName === "STRONG") {
				document.getElementById("bold").className = "rtebtn4";
				document.getElementById("bold").onmouseout = rteBtnMouseDown;
			}
			if (previous_tagName === "LI") {
				in_list = true;
			}
			if (previous_tagName === "TD" && !is_table) {
				is_table = true;
			}
			if (previous_tagName === "I" || previous_tagName === "EM") {
				document.getElementById("italic").className = "rtebtn4";
				document.getElementById("italic").onmouseout = rteBtnMouseDown;
			}
			if (previous_tagName === "U") {
				document.getElementById("underline").className = "rtebtn4";
				document.getElementById("underline").onmouseout = rteBtnMouseDown;
			}
			if (previous_tagName === "STRIKE") {
				document.getElementById("strikethrough").className = "rtebtn4";
				document.getElementById("strikethrough").onmouseout = rteBtnMouseDown;
			}
			if (previous_tagName === "A") {
				is_link = true;
				document.getElementById("editlink").className = "rtebtn4";
				document.getElementById("editlink").onmouseout = rteBtnMouseDown;
			}
			if (previous_tagName === "UL") {
				document.getElementById("insertunorderedlist").className = "rtebtn4";
				document.getElementById("insertunorderedlist").onmouseout = rteBtnMouseDown;
			}
			if (previous_tagName === "OL") {
				document.getElementById("insertorderedlist").className = "rtebtn4";
				document.getElementById("insertorderedlist").onmouseout = rteBtnMouseDown;
			}
			if (previous_tagName === "SUB") {
				document.getElementById("subscript").className = "rtebtn4";
				document.getElementById("subscript").onmouseout = rteBtnMouseDown;
			}
			if (previous_tagName === "SUP") {
				document.getElementById("superscript").className = "rtebtn4";
				document.getElementById("superscript").onmouseout = rteBtnMouseDown;
			}
			if (previous_tagName === "H1") {
				document.getElementById("format1").innerHTML = '<div style="height:16px;">Header 1</div>';
			}
			if (previous_tagName === "H2") {
				document.getElementById("format1").innerHTML = '<div style="height:16px;">Header 2</div>';
			}
			if (previous_tagName === "H3") {
				document.getElementById("format1").innerHTML = '<div style="height:16px;">Header 3</div>';
			}
			if (previous_tagName === "H4") {
				document.getElementById("format1").innerHTML = '<div style="height:16px;">Header 4</div>';
			}
			if (previous_tagName === "H5") {
				document.getElementById("format1").innerHTML = '<div style="height:16px;">Header 5</div>';
			}
			if (previous_tagName === "H6") {
				document.getElementById("format1").innerHTML = '<div style="height:16px;">Header 6</div>';
			}
			if (previous_tagName === "BLOCKQUOTE") {
				document.getElementById("indent").className = "rtebtn4";
				document.getElementById("indent").onmouseout = rteBtnMouseDown;
			}
			if (is_table) {
				document.getElementById("table_options_on").style.display = "";
				document.getElementById("table_options_off").style.display = "none";
			} else {
				document.getElementById("table_options_on").style.display = "none";
				document.getElementById("table_options_off").style.display = "";
			}
			if (current_tag.align === "left") {
				document.getElementById("justifyleft").className = "rtebtn4";
				document.getElementById("justifyleft").onmouseout = rteBtnMouseDown;
			} else if (current_tag.align === "center") {
				document.getElementById("justifycenter").className = "rtebtn4";
				document.getElementById("justifycenter").onmouseout = rteBtnMouseDown;
			} else if (current_tag.align === "right") {
				document.getElementById("justifyright").className = "rtebtn4";
				document.getElementById("justifyright").onmouseout = rteBtnMouseDown;
			} else if (current_tag.align === "justify") {
				document.getElementById("justifyfull").className = "rtebtn4";
				document.getElementById("justifyfull").onmouseout = rteBtnMouseDown;
			} else if (current_tag.align === "") {
				document.getElementById("justifyleft").className = "rtebtn1";
			} else {
			}
			if (current_tag.face === "arial") {
				document.getElementById("fontface1").innerHTML = '<div style="height:16px;">Arial</div>';
			} else if (current_tag.face === "arial black") {
				document.getElementById("fontface1").innerHTML = '<div style="height:16px;">Arial Black</div>';
			} else if (current_tag.face === "arial narrow") {
				document.getElementById("fontface1").innerHTML = '<div style="height:16px;">Arial Narrow</div>';
			} else if (current_tag.face === "courier new") {
				document.getElementById("fontface1").innerHTML = '<div style="height:16px;">Courier New</div>';
			} else if (current_tag.face === "century gothic") {
				document.getElementById("fontface1").innerHTML = '<div style="height:16px;">Century Gothic</div>';
			} else if (current_tag.face === "comic sans ms") {
				document.getElementById("fontface1").innerHTML = '<div style="height:16px;">Comic Sans MS</div>';
			} else if (current_tag.face === "impact") {
				document.getElementById("fontface1").innerHTML = '<div style="height:16px;">Impact</div>';
			} else if (current_tag.face === "tahoma") {
				document.getElementById("fontface1").innerHTML = '<div style="height:16px;">Tahoma</div>';
			} else if (current_tag.face === "times new roman") {
				document.getElementById("fontface1").innerHTML = '<div style="height:16px;">Times New Roman</div>';
			} else if (current_tag.face === "trebuchet ms") {
				document.getElementById("fontface1").innerHTML = '<div style="height:16px;">Trebuchet MS</div>';
			} else if (current_tag.face === "verdana") {
				document.getElementById("fontface1").innerHTML = '<div style="height:16px;">Verdana</div>';
			}
			if (current_tag.size === "1") {
				document.getElementById("fontsize1").innerHTML = '<div style="height:16px;">1</div>';
			} else if (current_tag.size === "2") {
				document.getElementById("fontsize1").innerHTML = '<div style="height:16px;">2</div>';
			} else if (current_tag.size === "3") {
				document.getElementById("fontsize1").innerHTML = '<div style="height:16px;">3</div>';
			} else if (current_tag.size === "4") {
				document.getElementById("fontsize1").innerHTML = '<div style="height:16px;">4</div>';
			} else if (current_tag.size === "5") {
				document.getElementById("fontsize1").innerHTML = '<div style="height:16px;">5</div>';
			} else if (current_tag.size === "6") {
				document.getElementById("fontsize1").innerHTML = '<div style="height:16px;">6</div>';
			} else if (current_tag.size === "7") {
				document.getElementById("fontsize1").innerHTML = '<div style="height:16px;">7</div>';
			} else {
			}
			if (current_tag.color !== null) {
				textcolor = current_tag.color;
			}
			current_tag = current_tag.parentNode;
			previous_tagName = current_tag.tagName;
		}
		if (in_list) {
		}
	}
	if (textcolor === "") {
		textcolor = "#000000";
	}
	if (is_table) {
		document.getElementById("edittable").className = "rtebtn4";
		document.getElementById("edittable").onmouseout = rteBtnMouseDown;
		document.getElementById("inserttable").style.display = "none";
		document.getElementById("edittable").style.display = "";
	} else {
		document.getElementById("edittable").className = "rtebtn1";
		document.getElementById("edittable").onmouseout = rteBtnMouseOut;
		document.getElementById("inserttable").style.display = "";
		document.getElementById("edittable").style.display = "none";
	}
	document.getElementById("fontcolor4").style.backgroundColor = textcolor;
	if (is_link) {
		document.getElementById("createlink").style.display = "none";
		document.getElementById("editlink").style.display = "";
	} else {
		document.getElementById("createlink").style.display = "";
		document.getElementById("editlink").style.display = "none";
	}
}
function rteBtnInsertImage() {
	rteInsertImagePopupWindow = window.open(rteHTMLPathInsertImage, "blank", "toolbar=no,width=340,height=230");
}
function rteOnInsertImagePopupLoaded() {
	rteInsertImagePopupWindow.setImageUploadInfo(rteImageUploadUrl);
}
function rteBtnEditLink() {
	window.open(rteHTMLPathEditLink, "blank", "toolbar=no,width=250,height=300");
}
function rteBtnEditTable() {
	window.open(rteHTMLPathEditTable, "blank", "toolbar=no,width=320,height=150");
}
function rteBtnCreateLink() {
	window.open(rteHTMLPathInsertLink, "blank", "toolbar=no,width=250,height=300");
}
function rteBtnPrint() {
	var oFrame;
	if (document.all) {
		oFrame = window.frames[rteName];
		oFrame.focus();
		oFrame.print();
	} else {
		oFrame = document.getElementById(rteName).contentWindow;
		oFrame.focus();
		oFrame.window.print();
	}
}
function rteInsertHTML(html) {
	// IE
	if (document.all) {
		document.getElementById(rteName).contentWindow.focus();
		var oRng = document.getElementById(rteName).contentWindow.document.selection.createRange();
		oRng.pasteHTML(html);
		oRng.collapse(false);
		oRng.select();
	// Other Browsers
	} else {
		document.getElementById(rteName).contentWindow.document.execCommand('insertHTML', false, html);
	}
}
function rteGetSelectedText() {
	var selection;
	var selectedText = "";
	if (window.getSelection) {
		// Safari, Firefox, Opera
		selection = document.getElementById(rteName).contentWindow.window.getSelection();
		selectedText = String(selection);
	} else if (document.getSelection) {
		selection = document.getElementById(rteName).contentWindow.document.getSelection();
		selectedText = String(selection);
	} else if (document.selection) {
		selection = document.getElementById(rteName).contentWindow.document.selection;
		selectedText = String(selection.createRange().text);
	}
	return selectedText;
}
function rteGetSelection() {
	var selection;
	var selected_obj;
	if (window.getSelection) {
		// Safari, Firefox, Opera
		selection = document.getElementById(rteName).contentWindow.window.getSelection();
		selected_obj = selection.focusNode;
	} else if (document.getSelection) {
		selection = document.getElementById(rteName).contentWindow.document.getSelection();
		selected_obj = selection.focusNode;
	} else if (document.selection) {
		selection = document.getElementById(rteName).contentWindow.document.selection;
		selected_obj = selection.createRange().parentElement();
	}
	return selected_obj;
}
function rteInsertLink(url, target) {
	var selectedText = rteGetSelectedText();
	if(String(selectedText) != "") {
		document.getElementById(rteName).contentWindow.document.execCommand("createlink", false, url);
		var selected_obj = rteGetSelection();
		var current_tag = selected_obj;
		var previous_tagName = selected_obj.tagName;
		while(previous_tagName !== "HTML"){
			if (previous_tagName == "A") {
				current_tag.href = url;
				current_tag.target = target;
				//alert("found "+target);
				break;
			}
			//alert("loop "+previous_tagName);
			current_tag = current_tag.parentNode;
			previous_tagName = current_tag.tagName;
		}
	} else {
		var linkTag = '<a href="' + url + '" target="' + target + '">' + url + '</a>';
		rteInsertHTML(linkTag);
	}
}
function rteBtnInsertForm() {
	window.open(rteHTMLPathInsertForm, "blank", "toolbar=no,width=320,height=180");
}
function rteBtnInsertCheckbox() {
	window.open(rteHTMLPathInsertCheckbox, "blank", "toolbar=no,width=320,height=150");
}
function rteBtnInsertRadio() {
	window.open(rteHTMLPathInsertRadiobutton, "blank", "toolbar=no,width=320,height=150");
}
function rteBtnInsertFlash() {
	window.open(rteHTMLPathInsertFlash, "blank", "toolbar=no,width=350,height=130");
}
function rteBtnInsertTextArea() {
	window.open(rteHTMLPathInsertTextArea, "blank", "toolbar=no,width=320,height=230");
}
function rteBtnInsertSubmit() {
	window.open(rteHTMLPathInsertSubmit, "blank", "toolbar=no,width=320,height=130");
}
function rteBtnInsertImageSubmit() {
	window.open(rteHTMLPathInsertImageSubmit, "blank", "toolbar=no,width=320,height=130");
}
function rteBtnInsertReset() {
	window.open(rteHTMLPathInsertReset, "blank", "toolbar=no,width=320,height=130");
}
function rteBtnInsertHidden() {
	window.open(rteHTMLPathInsertHidden, "blank", "toolbar=no,width=320,height=130");
}
function rteBtnInsertPassword() {
	window.open(rteHTMLPathInsertPassword, "blank", "toolbar=no,width=320,height=150");
}
function rteBtnInsertText() {
	window.open(rteHTMLPathInsertText, "blank", "toolbar=no,width=320,height=170");
}
function rteAbout() {
	msg = window.open("", "msg", "height=100,width=320");
	msg.document.write("<style>");
	msg.document.write("body, td {");
	msg.document.write("background-color:#ECE9D8;");
	msg.document.write("font-family:arial;");
	msg.document.write("font-size:11px;");
	msg.document.write("}");
	msg.document.write("input {");
	msg.document.write("font-family:arial;");
	msg.document.write("font-size:11px;");
	msg.document.write("}");
	msg.document.write("select {");
	msg.document.write("font-family:arial;");
	msg.document.write("font-size:11px;");
	msg.document.write("}");
	msg.document.write("</style>");
	msg.document.write("<fieldset>");
	msg.document.write("<legend><b>About FreeRichTextEditor</b></legend>");
	msg.document.write("<table width=\"100%\" cellspacing=\"2\" cellpadding=\"0\" border=\"0\">");
	msg.document.write("<tr>");
	msg.document.write("<td colspan=\"2\" align=\"center\">Copyright &copy; 2006 Steven Ewing<br><a href=\"http://www.freerichtexteditor.com\" target=\"_blank\">www.FreeRichTextEditor.com</a></td>");
	msg.document.write("</tr>");
	msg.document.write("<tr>");
	msg.document.write("<td colspan=\"2\" align=\"center\"><input type=\"button\" value=\"License\" onclick=\"window.open('http://www.freerichtexteditor.com/page/5.htm' , 'blank','');\"><input type=\"button\" value=\"Donate\" onclick=\"window.open('http://www.freerichtexteditor.com/page/7.htm' , 'blank','');\"><input type=\"button\" value=\"Download\" onclick=\"window.open('http://www.freerichtexteditor.com/page/4.htm' , 'blank','');\"></td>");
	msg.document.write("</tr>");
	msg.document.write("</table>");
	msg.document.write("</fieldset>");
	msg.document.close();
}
function rteBtnInsertTable() {
	window.open(rteHTMLPathInsertTable, "blank", "toolbar=no,width=320,height=240");
}
function rteBtnInsertTableRowBefore() {
	document.getElementById(rteName).contentWindow.focus();
	
	var selected_obj;
	if (window.getSelection) {
		selected_obj = document.getElementById(rteName).contentWindow.window.getSelection().focusNode;
	} else if (document.getSelection) {
		selected_obj = document.getElementById(rteName).contentWindow.document.getSelection().focusNode;
	} else if (document.selection) {
		selected_obj = document.getElementById(rteName).contentWindow.document.selection.createRange().parentElement();
	}
	current_tag = selected_obj;
	while (current_tag.tagName != "TABLE") {
		if (current_tag.tagName === "TR") {
			cellTotal = current_tag.cells.length;
			RowIndex = current_tag.rowIndex;
		}
		if (current_tag.parentNode.tagName === "TBODY") {
			var x = current_tag.parentNode.insertRow(RowIndex);
			for (i = 0; i < cellTotal; i++) {
				var j = x.insertCell(i);
				j.innerHTML = "&nbsp;";
			}
		}
		current_tag = current_tag.parentNode;
	}
}

function rteBtnInsertTableRowAfter() {
	document.getElementById(rteName).contentWindow.focus();
	
	var selected_obj;
	if (window.getSelection) {
		selected_obj = document.getElementById(rteName).contentWindow.window.getSelection().focusNode;
	} else if (document.getSelection) {
		selected_obj = document.getElementById(rteName).contentWindow.document.getSelection().focusNode;
	} else if (document.selection) {
		selected_obj = document.getElementById(rteName).contentWindow.document.selection.createRange().parentElement();
	}
	current_tag = selected_obj;
	while (current_tag.tagName != "TABLE") {
		if (current_tag.tagName === "TR") {
			cellTotal = current_tag.cells.length;
			RowIndex = current_tag.rowIndex;
		}
		if (current_tag.parentNode.tagName === "TBODY") {
			var x = current_tag.parentNode.insertRow(RowIndex + 1);
			for (i = 0; i < cellTotal; i++) {
				var j = x.insertCell(i);
				j.innerHTML = "&nbsp;";
			}
		}
		current_tag = current_tag.parentNode;
	}
}
function rteBtnInsertTableColumnBefore() {
	document.getElementById(rteName).contentWindow.focus();
	
	var selected_obj;
	if (window.getSelection) {
		selected_obj = document.getElementById(rteName).contentWindow.window.getSelection().focusNode;
	} else if (document.getSelection) {
		selected_obj = document.getElementById(rteName).contentWindow.document.getSelection().focusNode;
	} else if (document.selection) {
		selected_obj = document.getElementById(rteName).contentWindow.document.selection.createRange().parentElement();
	}
	current_tag = selected_obj;
	while (current_tag.tagName != "TABLE") {
		if (current_tag.tagName === "TD") {
			cellIndex = current_tag.cellIndex;
		}
		if (current_tag.tagName === "TBODY") {
			RowTotal = current_tag.parentNode.rows.length;
			var x = current_tag.parentNode;
			for (i = 0; i < RowTotal; i++) {
				var j = x.rows[i].insertCell(cellIndex);
				j.innerHTML = "&nbsp;";
			}
		}
		current_tag = current_tag.parentNode;
	}
}
function rteBtnInsertTableColumnAfter() {
	document.getElementById(rteName).contentWindow.focus();
	
	var selected_obj;
	if (window.getSelection) {
		selected_obj = document.getElementById(rteName).contentWindow.window.getSelection().focusNode;
	} else if (document.getSelection) {
		selected_obj = document.getElementById(rteName).contentWindow.document.getSelection().focusNode;
	} else if (document.selection) {
		selected_obj = document.getElementById(rteName).contentWindow.document.selection.createRange().parentElement();
	}
	current_tag = selected_obj;
	while (current_tag.tagName != "TABLE") {
		if (current_tag.tagName == "TD") {
			cellIndex = current_tag.cellIndex;
		}
		if (current_tag.tagName == "TBODY") {
			RowTotal = current_tag.parentNode.rows.length;
			var x = current_tag.parentNode;
			for (i = 0; i < RowTotal; i++) {
				var j = x.rows[i].insertCell(cellIndex + 1);
				j.innerHTML = "&nbsp;";
			}
		}
		current_tag = current_tag.parentNode;
	}
}
function rteBtnDeleteTableColumn() {
	var selected_obj;
	if (window.getSelection) {
		selected_obj = document.getElementById(rteName).contentWindow.window.getSelection().focusNode;
	} else if (document.getSelection) {
		selected_obj = document.getElementById(rteName).contentWindow.document.getSelection().focusNode;
	} else if (document.selection) {
		selected_obj = document.getElementById(rteName).contentWindow.document.selection.createRange().parentElement();
	}
	current_tag = selected_obj;
	while (current_tag.tagName !== "TABLE") {
		if (current_tag.tagName === "TD") {
			cellIndex = current_tag.cellIndex;
		}
		if (current_tag.tagName == "TBODY") {
			RowTotal = current_tag.parentNode.rows.length;
			var x = current_tag.parentNode;
			for (i = 0; i < RowTotal; i++) {
				j = x.rows[i].deleteCell(cellIndex);
			}
		}
		current_tag = current_tag.parentNode;
	}
}
function rteBtnDeleteTableRow() {
	var selected_obj;
	if (window.getSelection) {
		selected_obj = document.getElementById(rteName).contentWindow.window.getSelection().focusNode;
	} else if (document.getSelection) {
		selected_obj = document.getElementById(rteName).contentWindow.document.getSelection().focusNode;
	} else if (document.selection) {
		selected_obj = document.getElementById(rteName).contentWindow.document.selection.createRange().parentElement();
	}
	current_tag = selected_obj;
	while (current_tag.tagName !== "TABLE") {
		if (current_tag.tagName === "TR") {
			RowIndex = current_tag.rowIndex;
		}
		if (current_tag.tagName == "TBODY") {
			RowTotal = current_tag.parentNode.rows.length;
			var x = current_tag.parentNode;
			x.deleteRow(RowIndex);
		}
		current_tag = current_tag.parentNode;
	}
}
function startRTE(rtePreloadContent) {
	var kids;
	var i;
	rteCSS = document.getElementById("preview_css").value;
	kids = document.getElementsByTagName("FORM");
	for (i = 0; i < kids.length; i++) {
		kids[i].onsubmit = rteFormHandler;
	}
	document.getElementById(rteName).contentWindow.document.designMode = "on";
	document.getElementById(rteFormName).value = rtePreloadContent;
	document.getElementById(rteName).contentWindow.document.open();
	document.getElementById(rteName).contentWindow.document.write("<html><head><style type=\"text/css\">@import url(" + rteCSS+ ");</style></head><body>" + rtePreloadContent + "</body></html>");
	document.getElementById(rteName).contentWindow.document.close();
	try {
		if (document.all && !window.opera) {
			document.getElementById(rteName).contentWindow.document.attachEvent("onkeypress", rteSelection);
			document.getElementById(rteName).contentWindow.document.attachEvent("onclick", rteSelection);
			document.getElementById(rteName).contentWindow.document.attachEvent("onmouseup", rteSelection);
		} else {
			// because of firefox error
			// document.getElementById(rteName).contentWindow.document.execCommand("useCSS", false, null);
			document.getElementById(rteName).contentWindow.document.addEventListener("keypress", rteSelection, true);
			document.getElementById(rteName).contentWindow.document.addEventListener("click", rteSelection, true);
			document.getElementById(rteName).contentWindow.document.addEventListener("mouseup", rteSelection, true);
		}
	} catch(err) {
		//alert(err);
	}
	rteSelection();
	kids = document.getElementsByTagName("DIV");
	for (i = 0; i < kids.length; i++) {
		if (kids[i].className == "rtebtn6") {
			kids[i].onmouseover = rteBtnMouseOverBottom;
			kids[i].onmouseout = rteBtnMouseOutBottom;
			kids[i].onmousedown = rteBtnMouseDownBottom;
			kids[i].onmouseup = rteBtnMouseUpBottom;
		}
	}
}
function rteSpellCheck() {
	alert('Not yet supported.');
}
function isSafari() {
	return navigator.userAgent.toLowerCase().indexOf("safari") != -1;
}
function menuBuilder() {
	if (rteFormat) {
		document.getElementById("rteformat").style.display = "";
	} else {
		document.getElementById("rteformat").style.display = "none";
	}
	if (rteFontFace) {
		document.getElementById("rtefontface").style.display = "";
	} else {
		document.getElementById("rtefontface").style.display = "none";
	}
	if (rteFontSize) {
		document.getElementById("rtefontsize").style.display = "";
	} else {
		document.getElementById("rtefontsize").style.display = "none";
	}
	if (rteFontColor) {
		document.getElementById("rtefontcolor").style.display = "";
	} else {
		document.getElementById("rtefontcolor").style.display = "none";
	}
	if (rteBold) {
		document.getElementById("bold").style.display = "";
	} else {
		document.getElementById("bold").style.display = "none";
	}
	if (rteItalic) {
		document.getElementById("italic").style.display = "";
	} else {
		document.getElementById("italic").style.display = "none";
	}
	if (rteUnderline) {
		document.getElementById("underline").style.display = "";
	} else {
		document.getElementById("underline").style.display = "none";
	}
	if (rteStrikeThrough) {
		document.getElementById("strikethrough").style.display = "";
	} else {
		document.getElementById("strikethrough").style.display = "none";
	}
	if (rteLeftAlign) {
		document.getElementById("justifyleft").style.display = "";
	} else {
		document.getElementById("justifyleft").style.display = "none";
	}
	if (rteCenterAlign) {
		document.getElementById("justifycenter").style.display = "";
	} else {
		document.getElementById("justifycenter").style.display = "none";
	}
	if (rteRightAlign) {
		document.getElementById("justifyright").style.display = "";
	} else {
		document.getElementById("justifyright").style.display = "none";
	}
	if (rteFullAlign) {
		document.getElementById("justifyfull").style.display = "";
	} else {
		document.getElementById("justifyfull").style.display = "none";
	}
	if (rteHorizontalRule) {
		document.getElementById("inserthorizontalrule").style.display = "";
	} else {
		document.getElementById("inserthorizontalrule").style.display = "none";
	}
	if (rteSubscript) {
		document.getElementById("subscript").style.display = "";
	} else {
		document.getElementById("subscript").style.display = "none";
	}
	if (rteSuperscript) {
		document.getElementById("superscript").style.display = "";
	} else {
		document.getElementById("superscript").style.display = "none";
	}
	if (rteLink) {
		document.getElementById("createlink").style.display = "";
	} else {
		document.getElementById("createlink").style.display = "none";
	}
	if (rteUnlink) {
		document.getElementById("unlink").style.display = "";
	} else {
		document.getElementById("unlink").style.display = "none";
	}
	if (rteImages) {
		document.getElementById("insertimage").style.display = "";
	} else {
		document.getElementById("insertimage").style.display = "none";
	}
	if (rteRemoveFormat) {
		document.getElementById("removeformat").style.display = "";
	} else {
		document.getElementById("removeformat").style.display = "none";
	}
	if (rteTables) {
		document.getElementById("tables").style.display = "";
	} else {
		document.getElementById("tables").style.display = "none";
	}
	if (rteOrderedList) {
		document.getElementById("insertorderedlist").style.display = "";
	} else {
		document.getElementById("insertorderedlist").style.display = "none";
	}
	if (rteUnorderedList) {
		document.getElementById("insertunorderedlist").style.display = "";
	} else {
		document.getElementById("insertunorderedlist").style.display = "none";
	}
	if (rteIndent) {
		document.getElementById("indent").style.display = "";
	} else {
		document.getElementById("indent").style.display = "none";
	}
	if (rteOutdent) {
		document.getElementById("outdent").style.display = "";
	} else {
		document.getElementById("outdent").style.display = "none";
	}
	if (rteUndo) {
		document.getElementById("undo").style.display = "";
	} else {
		document.getElementById("undo").style.display = "none";
	}
	if (rteRedo) {
		document.getElementById("redo").style.display = "";
	} else {
		document.getElementById("redo").style.display = "none";
	}
	if (rteCutCopyPaste) {
		document.getElementById("cutcopypaste").style.display = "";
	} else {
		document.getElementById("cutcopypaste").style.display = "none";
	}
	if (rteInsertForm) {
		document.getElementById("insertform").style.display = "";
	} else {
		document.getElementById("insertform").style.display = "none";
	}
	if (rteInsertCheckbox) {
		document.getElementById("form_checkbox").style.display = "";
	} else {
		document.getElementById("form_checkbox").style.display = "none";
	}
	if (rteInsertRadio) {
		document.getElementById("form_radio").style.display = "";
	} else {
		document.getElementById("form_radio").style.display = "none";
	}
	if (rteInsertTextArea) {
		document.getElementById("form_textarea").style.display = "";
	} else {
		document.getElementById("form_textarea").style.display = "none";
	}
	if (rteInsertSubmit) {
		document.getElementById("form_submit").style.display = "";
	} else {
		document.getElementById("form_submit").style.display = "none";
	}
	if (rteInsertImageSubmit) {
		document.getElementById("form_image_submit").style.display = "";
	} else {
		document.getElementById("form_image_submit").style.display = "none";
	}
	if (rteInsertReset) {
		document.getElementById("form_reset").style.display = "";
	} else {
		document.getElementById("form_reset").style.display = "none";
	}
	if (rteInsertHidden) {
		document.getElementById("form_hidden").style.display = "";
	} else {
		document.getElementById("form_hidden").style.display = "none";
	}
	if (rteInsertPassword) {
		document.getElementById("form_password").style.display = "";
	} else {
		document.getElementById("form_password").style.display = "none";
	}
	if (rteInsertTextField) {
		document.getElementById("form_textfield").style.display = "";
	} else {
		document.getElementById("form_textfield").style.display = "none";
	}
	if (rtePrint) {
		document.getElementById("printrte").style.display = "";
	} else {
		document.getElementById("printrte").style.display = "none";
	}
	if (rteSelectAll) {
		document.getElementById("selectall").style.display = "";
	} else {
		document.getElementById("selectall").style.display = "none";
	}
	if(rteShowAbout) {
		document.getElementById("aboutrte").style.display = "";
	} else {
		document.getElementById("aboutrte").style.display = "none";
	}
	if (rteSpellCheck) {
		document.getElementById("spellchecker").style.display = "";
	} else {
		document.getElementById("spellchecker").style.display = "none";
	}
	if (!rteFormat && !rteFontFace && !rteFontSize && !rteFontColor) {
		document.getElementById("rtesep1").style.display = "none";
		document.getElementById("rtesep2").style.display = "none";
	}
	if (!rteBold && !rteItalic && !rteUnderline && !rteStrikeThrough) {
		document.getElementById("rtesep3").style.display = "none";
	}
	if (!rteLeftAlign && !rteCenterAlign && !rteRightAlign && !rteFullAlign && !rteHorizontalRule) {
		document.getElementById("rtesep4").style.display = "none";
	}
	if(!rteToolbar1) {
		document.getElementById("tb1").style.display = "none";
	}
	if(!rteToolbar2) {
		document.getElementById("tb2").style.display = "none";
	}
	if(!rteToolbar3) {
		document.getElementById("tb3").style.display = "none";
	}
	if(!rteDesignMode) {
		document.getElementById("rte_design_mode").style.display = "none";
	}
	if(!rteCodeMode) {
		document.getElementById("rte_code_mode").style.display = "none";
	}
	if(!rtePreviewMode || isSafari()) {
		document.getElementById("rte_preview_mode").style.display = "none";
	}
	if(!rteDesignMode && !rteCodeMode && (!rtePreviewMode || isSafari())) {
		document.getElementById("view_mode").style.display = "none";
	}
	
	if (!rteLink && !rteUnlink) {
		document.getElementById("rtesep5").style.display = "none";
	}
	if (!rteImages && !rteRemoveFormat) {
		document.getElementById("rtesep6").style.display = "none";
	}
	if (!rteTables) {
		document.getElementById("rtesep7").style.display = "none";
	}
	if (!rteOrderedList && !rteUnorderedList && !rteIndent && !rteOutdent) {
		document.getElementById("rtesep8").style.display = "none";
	}
	if (!rteUndo && !rteRedo) {
		document.getElementById("rtesep9").style.display = "none";
	}
	if (!rteInsertForm && !rteInsertCheckbox && !rteInsertRadio && !rteInsertTextArea && !rteInsertSubmit && !rteInsertImageSubmit && !rteInsertReset && !rteInsertHidden && !rteInsertPassword && !rteInsertTextField) {
		document.getElementById("rtesep10").style.display = "none";
	}
	if (!rtePrint && !rteSelectAll && !rteShowSpellCheck) {
		document.getElementById("rtesep11").style.display = "none";
	}
}
function getToolbar1Tag(rteImagePath) {
	var tag = '';
	tag += '<tr>';
	//tag += '	<td bgcolor="#C3DAF9">';
	tag += '	<td bgcolor="#FFFFFF">';
	tag += '		<table cellpadding="0" cellspacing="0" id="tb1" onmousedown="return false;">';
	tag += '			<tr>';
	tag += '				<td width="7"><img src="' + rteImagePath + 'start.gif" width="7" height="25"></td>';
	tag += '				<td class="rtebg" id="rtesep1"><img src="' + rteImagePath + 'blank.gif"></td>';
	tag += '				<td background="' + rteImagePath + 'bg.gif" id="rteformat">';
	tag += '					<table width="100%" cellpadding="0" cellspacing="0" id="format4" bgcolor="#FFFFFF" title="Style">';
	tag += '						<tr>';
	tag += '							<td nowrap>';
	tag += '								<div unselectable="on" id="format1" class="rtedropdown1" style="width:58px;font-family:arial;font-size:11px;color:#000000;line-height:16px;">Paragraph</div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div unselectable="on" id="format2" class="rtedropdown2"><img src="' + rteImagePath + 'arrow.gif" width="11" height="16"></div>';
	tag += '							</td>';
	tag += '						</tr>';
	tag += '					</table>';
	tag += '					<div id="format3" class="rtedropdown7" style="position:absolute;display:none;">';
	tag += '						<div unselectable="on" id="formatblock" style="font-size:24px; font-family:arial;color:#000000;font-weight:bold;padding:5px;" nowrap>Header 1</div>';
	tag += '						<div unselectable="on" id="formatblock" style="font-size:18px; font-family:arial;color:#000000;font-weight:bold;padding:5px;" nowrap>Header 2</div>';
	tag += '						<div unselectable="on" id="formatblock" style="font-size:16px; font-family:arial;color:#000000;font-weight:bold;padding:5px;" nowrap>Header 3</div>';
	tag += '						<div unselectable="on" id="formatblock" style="font-size:14px; font-family:arial;color:#000000;font-weight:bold;padding:5px;" nowrap>Header 4</div>';
	tag += '						<div unselectable="on" id="formatblock" style="font-size:12px; font-family:arial;color:#000000;font-weight:bold;padding:5px;" nowrap>Header 5</div>';
	tag += '						<div unselectable="on" id="formatblock" style="font-size:10px; font-family:arial;color:#000000;font-weight:bold;padding:5px;" nowrap>Header 6</div>';
	tag += '						<div unselectable="on" id="formatblock" style="font-size:12px; font-family:arial;color:#000000;font-weight:bold;padding:5px;" nowrap>Paragraph</div>';
	tag += '					</div>';
	tag += '				</td>';
	tag += '				<td class="rtebg"><img src="' + rteImagePath + 'blank.gif"></td>';
	tag += '				<td background="' + rteImagePath + 'bg.gif" id="rtefontface">';
	tag += '					<table style="width:110px;" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" title="Font">';
	tag += '						<tr>';
	tag += '							<td nowrap>';
	tag += '								<div unselectable="on" id="fontface1" class="rtedropdown1" style="width:98px;font-family:arial;font-size:11px;color:#000000;line-height:16px;">Verdana</div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div unselectable="on" id="fontface2" class="rtedropdown2"><img src="' + rteImagePath + 'arrow.gif" width="11" height="16"></div>';
	tag += '							</td>';
	tag += '						</tr>';
	tag += '					</table>';
	tag += '					<div id="fontface3" class="rtedropdown7" style="position:absolute;display:none;">';
	tag += '						<div unselectable="on" id="fontface" style="color:#000000;font-family:arial;padding:5px;" nowrap>Arial</div>';
	tag += '						<div unselectable="on" id="fontface" style="color:#000000;font-family:arial black;padding:5px;" nowrap>Arial Black</div>';
	tag += '						<div unselectable="on" id="fontface" style="color:#000000;font-family:arial narrow;padding:5px;" nowrap>Arial Narrow</div>';
	tag += '						<div unselectable="on" id="fontface" style="color:#000000;font-family:courier new;padding:5px;" nowrap>Courier New</div>';
	tag += '						<div unselectable="on" id="fontface" style="color:#000000;font-family:century gothic;padding:5px;" nowrap>Century Gothic</div>';
	tag += '						<div unselectable="on" id="fontface" style="color:#000000;font-family:comic sans ms;padding:5px;" nowrap>Comic Sans MS</div>';
	tag += '						<div unselectable="on" id="fontface" style="color:#000000;font-family:impact;padding:5px;" nowrap>Impact</div>';
	tag += '						<div unselectable="on" id="fontface" style="color:#000000;font-family:tahoma;padding:5px;" nowrap>Tahoma</div>';
	tag += '						<div unselectable="on" id="fontface" style="color:#000000;font-family:times new roman;padding:5px;" nowrap>Times New Roman</div>';
	tag += '						<div unselectable="on" id="fontface" style="color:#000000;font-family:trebuchet ms;padding:5px;" nowrap>Trebuchet MS</div>';
	tag += '						<div unselectable="on" id="fontface" style="color:#000000;font-family:verdana;padding:5px;" nowrap>Verdana</div>';
	tag += '					</div>';
	tag += '				</td>';
	tag += '				<td class="rtebg"><img src="' + rteImagePath + 'blank.gif"></td>';
	tag += '				<td background="' + rteImagePath + 'bg.gif" id="rtefontsize">';
	tag += '					<table width="100%" cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" title="Font Size">';
	tag += '						<tr>';
	tag += '							<td>';
	tag += '								<div unselectable="on" id="fontsize1" class="rtedropdown1" style="font-family:arial;font-size:11px;color:#000000;line-height:16px;">2</div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div unselectable="on" id="fontsize2" class="rtedropdown2"><img src="' + rteImagePath + 'arrow.gif" width="11" height="16"></div>';
	tag += '							</td>';
	tag += '						</tr>';
	tag += '					</table>';
	tag += '					<div id="fontsize3" class="rtedropdown7" style="position:absolute;display:none;">';
	tag += '						<div unselectable="on" id="fontface" style="font-family:arial;color:#000000;font-size:7px;padding:5px;">1</div>';
	tag += '						<div unselectable="on" id="fontface" style="font-family:arial;color:#000000;font-size:10px;padding:5px;">2</div>';
	tag += '						<div unselectable="on" id="fontface" style="font-family:arial;color:#000000;font-size:12px;padding:5px;">3</div>';
	tag += '						<div unselectable="on" id="fontface" style="font-family:arial;color:#000000;font-size:13px;padding:5px;">4</div>';
	tag += '						<div unselectable="on" id="fontface" style="font-family:arial;color:#000000;font-size:17px;padding:5px;">5</div>';
	tag += '						<div unselectable="on" id="fontface" style="font-family:arial;color:#000000;font-size:23px;padding:5px;">6</div>';
	tag += '						<div unselectable="on" id="fontface" style="font-family:arial;color:#000000;font-size:35px;padding:5px;">7</div>';
	tag += '					</div>';
	tag += '				</td>';
	tag += '				<td class="rtebg"><img src="' + rteImagePath + 'blank.gif"></td>';
	tag += '				<td class="rtebg" id="rtefontcolor" title="Font Color">';
	tag += '					<table style="width:35px;" border="0" cellspacing="0" cellpadding="0">';
	tag += '						<tr>';
	tag += '							<td>';
	tag += '								<div id="fontcolor1" align="center" class="rtedropdown5" style="padding-bottom:1px;"><img src="' + rteImagePath + 'fontcolor.gif"><br><img id="fontcolor4" src="' + rteImagePath + 'fontcolor2.gif" style="background-color:#FF0000;"></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div align="center" id="fontcolor2" class="rtedropdown8"><div style="height:19px;"><img src="' + rteImagePath + 'arrow.gif"></div></div>';
	tag += '							</td>';
	tag += '						</tr>';
	tag += '					</table>';
	tag += '					<div id="fontcolor3" class="rtedropdown7" style="position:absolute;display:none;padding:4px;border:1px solid #002D96;">';
	tag += '						<table border="0" cellspacing="1" cellpadding="0">';
	tag += '							<tr>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#000000;" onClick="rteColorClick(\'#000000\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#993300;" onClick="rteColorClick(\'#993300\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#333300;" onClick="rteColorClick(\'#333300\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#003300;" onClick="rteColorClick(\'#003300\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#003366;" onClick="rteColorClick(\'#003366\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#000080;" onClick="rteColorClick(\'#000080\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#333399;" onClick="rteColorClick(\'#333399\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#333333;" onClick="rteColorClick(\'#333333\');"></div>';
	tag += '								</td>';
	tag += '							</tr>';
	tag += '							<tr>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#800000;" onClick="rteColorClick(\'#800000\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#FF6600;" onClick="rteColorClick(\'#FF6600\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#808000;" onClick="rteColorClick(\'#808000\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#008000;" onClick="rteColorClick(\'#008000\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#008080;" onClick="rteColorClick(\'#008080\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#0000FF;" onClick="rteColorClick(\'#0000FF\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#666699;" onClick="rteColorClick(\'#666699\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#808080;" onClick="rteColorClick(\'#808080\');"></div>';
	tag += '								</td>';
	tag += '							</tr>';
	tag += '							<tr>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#FF0000;" onClick="rteColorClick(\'#FF0000\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#FF9900;" onClick="rteColorClick(\'#FF9900\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#99CC00;" onClick="rteColorClick(\'#99CC00\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#339966;" onClick="rteColorClick(\'#339966\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#33CCCC;" onClick="rteColorClick(\'#33CCCC\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#3366FF;" onClick="rteColorClick(\'#3366FF\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#800080;" onClick="rteColorClick(\'#800080\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#999999;" onClick="rteColorClick(\'#999999\');"></div>';
	tag += '								</td>';
	tag += '							</tr>';
	tag += '							<tr>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#FF00FF;" onClick="rteColorClick(\'#FF00FF\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#FFCC00;" onClick="rteColorClick(\'#FFCC00\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#FFFF00;" onClick="rteColorClick(\'#FFFF00\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#00FF00;" onClick="rteColorClick(\'#00FF00\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#00FFFF;" onClick="rteColorClick(\'#00FFFF\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#00CCFF;" onClick="rteColorClick(\'#00CCFF\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#993366;" onClick="rteColorClick(\'#993366\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#C0C0C0;" onClick="rteColorClick(\'#C0C0C0\');"></div>';
	tag += '								</td>';
	tag += '							</tr>';
	tag += '							<tr>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#FF99CC;" onClick="rteColorClick(\'#FF99CC\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#FFCC99;" onClick="rteColorClick(\'#FFCC99\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#FFFF99;" onClick="rteColorClick(\'#FFFF99\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#CCFFCC;" onClick="rteColorClick(\'#CCFFCC\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#CCFFFF;" onClick="rteColorClick(\'#CCFFFF\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#99CCFF;" onClick="rteColorClick(\'#99CCFF\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#CC99FF;" onClick="rteColorClick(\'#CC99FF\');"></div>';
	tag += '								</td>';
	tag += '								<td>';
	tag += '									<div id="fontcolor" class="rtedropdown13"><img src="' + rteImagePath + 'fontcolor3.gif" style="background-color:#FFFFFF;" onClick="rteColorClick(\'#FFFFFF\');"></div>';
	tag += '								</td>';
	tag += '							</tr>';
	tag += '						</table>';
	tag += '					</div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" id="rtesep2"><img src="' + rteImagePath + 'seperator.gif"></td>';
	tag += '				<td class="rtebg" title="Bold">';
	tag += '					<div id="bold" class="rtebtn1"><img src="' + rteImagePath + 'bold.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Italic">';
	tag += '					<div id="italic" class="rtebtn1"><img src="' + rteImagePath + 'italic.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Underline">';
	tag += '					<div id="underline" class="rtebtn1"><img src="' + rteImagePath + 'underline.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Strikethrough">';
	tag += '					<div id="strikethrough" class="rtebtn1"><img src="' + rteImagePath + 'strikethrough.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" id="rtesep3"><img src="' + rteImagePath + 'seperator.gif"></td>';
	tag += '				<td class="rtebg" title="Align Left">';
	tag += '					<div id="justifyleft" class="rtebtn1"><img src="' + rteImagePath + 'leftalign.gif" width="21" height="20"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Center">';
	tag += '					<div id="justifycenter" class="rtebtn1"><img src="' + rteImagePath + 'centeralign.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Align Right">';
	tag += '					<div id="justifyright" class="rtebtn1"><img src="' + rteImagePath + 'rightalign.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Justify">';
	tag += '					<div id="justifyfull" class="rtebtn1"><img src="' + rteImagePath + 'fullalign.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Horizontal Rule">';
	tag += '					<div id="inserthorizontalrule" class="rtebtn1"><img src="' + rteImagePath + 'hr.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" id="rtesep4"><img src="' + rteImagePath + 'seperator.gif"></td>';
	tag += '				<td class="rtebg" title="Superscript">';
	tag += '					<div id="superscript" class="rtebtn1"><img src="' + rteImagePath + 'superscript.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Subscript">';
	tag += '					<div id="subscript" class="rtebtn1"><img src="' + rteImagePath + 'subscript.gif"></div>';
	tag += '				</td>';
	tag += '				<td width="14"><img src="' + rteImagePath + 'finish.gif" width="14" height="25"></td>';
	tag += '				<td width="100%">';
	tag += '				</td>';
	tag += '			</tr>';
	tag += '		</table>';
	tag += '	</td>';
	tag += '</tr>';
	return tag;
}
function getToolbar2Tag(rteImagePath) {
	var tag = '';
	tag += '<tr>';
	//tag += '	<td bgcolor="#C3DAF9">';
	tag += '	<td bgcolor="#FFFFFF">';
	tag += '		<table cellpadding="0" cellspacing="0" id="tb2" onmousedown="return false;">';
	tag += '			<tr>';
	tag += '				<td width="7"><img src="' + rteImagePath + 'start.gif" width="7" height="25" /></td>';
	tag += '				<td class="rtebg"><img src="' + rteImagePath + 'blank.gif"></td>';
	tag += '				<td class="rtebg">';
	tag += '					<div id="createlink" class="rtebtn1" title="Insert Hyperlink"><a href="javascript:rteBtnCreateLink();" style="cursor:default;"><img src="' + rteImagePath + 'insertlink.gif" border="0"></a></div>';
	tag += '					<div style="display:none;" id="editlink" class="rtebtn1" title="Edit Hyperlink"><a href="javascript:rteBtnEditLink();" style="cursor:default;"><img src="' + rteImagePath + 'insertlink.gif"border="0"></a></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Remove Hyperlink">';
	tag += '					<div id="unlink" class="rtebtn1"><img src="' + rteImagePath + 'unlink.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" id="rtesep5"><img src="' + rteImagePath + 'seperator.gif"></td>';
	tag += '				<td class="rtebg" title="Insert Image">';
	tag += '					<div id="insertimage" class="rtebtn1"><a href="javascript:rteBtnInsertImage();" style="cursor:default;"><img src="' + rteImagePath + 'insertimage.gif" border="0"></a></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Remove Formatting">';
	tag += '					<div id="removeformat" class="rtebtn1"><img src="' + rteImagePath + 'format.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" id="rtesep6"><img src="' + rteImagePath + 'seperator.gif"></td>';
	tag += '				<td class="rtebg" id="tables">';
	tag += '					<table border="0" width="0" cellspacing="0" cellpadding="0" id="table_options_on" style="display:none;">';
	tag += '						<tr>';
	tag += '							<td>';
	tag += '								<div id="inserttable" class="rtebtn1" title="Insert Table"><a href="javascript:rteBtnInsertTable();" style="cursor:default;"><img src="' + rteImagePath + 'inserttable.gif" border="0"></a></div>';
	tag += '								<div id="edittable" class="rtebtn1" title="Edit Table Properties"><a href="javascript:rteBtnEditTable();" style="cursor:default;"><img src="' + rteImagePath + 'inserttable.gif" border="0"></a></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div id="insertcolumnleft" class="rtebtn1" title="Insert Column to the left"><img src="' + rteImagePath + 'insertcolumnleft.gif" onClick="rteBtnInsertTableColumnBefore();"></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div id="insertcolumnright" class="rtebtn1" title="Insert Column to the right"><img src="' + rteImagePath + 'insertcolumnright.gif" onClick="rteBtnInsertTableColumnAfter();"></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div id="insertrowabove" class="rtebtn1" title="Insert Row above"><img src="' + rteImagePath + 'insertrowabove.gif" onClick="rteBtnInsertTableRowBefore();"></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div id="insertrowbelow" class="rtebtn1" title="Insert Row below"><img src="' + rteImagePath + 'insertrowbelow.gif" onClick="rteBtnInsertTableRowAfter();"></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div id="deletecolumn" class="rtebtn1" title="Delete Current column"><img src="' + rteImagePath + 'deletecolumn.gif" onClick="rteBtnDeleteTableColumn();"></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div id="deleterow" class="rtebtn1" title="Delete Current row"><img src="' + rteImagePath + 'deleterow.gif" onClick="rteBtnDeleteTableRow();"></div>';
	tag += '							</td>';
	tag += '						</tr>';
	tag += '					</table>';
	tag += '					<table border="0" width="0" cellspacing="0" cellpadding="0" id="table_options_off">';
	tag += '						<tr>';
	tag += '							<td>';
	tag += '								<div id="inserttable" class="rtebtn1" title="Insert Table"><a href="javascript:rteBtnInsertTable();" style="cursor:default;"><img src="' + rteImagePath + 'inserttable.gif" border="0"></a></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div class="rtebtn5" title="Insert Column to the left"><img src="' + rteImagePath + 'insertcolumnleftgrey.gif"></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div class="rtebtn5" title="Insert Column to the right"><img src="' + rteImagePath + 'insertcolumnrightgrey.gif"></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div class="rtebtn5" title="Insert Row above"><img src="' + rteImagePath + 'insertrowabovegrey.gif"></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div class="rtebtn5" title="Insert Row below"><img src="' + rteImagePath + 'insertrowbelowgrey.gif"></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div class="rtebtn5" title="Delete Current column"><img src="' + rteImagePath + 'deletecolumngrey.gif"></div>';
	tag += '							</td>';
	tag += '							<td>';
	tag += '								<div class="rtebtn5" title="Delete Current row"><img src="' + rteImagePath + 'deleterowgrey.gif"></div>';
	tag += '							</td>';
	tag += '						</tr>';
	tag += '					</table>';
	tag += '				</td>';
	tag += '				<td class="rtebg" id="rtesep7"><img src="' + rteImagePath + 'seperator.gif"></td>';
	tag += '				<td class="rtebg" title="Numbering">';
	tag += '					<div id="insertorderedlist" class="rtebtn1"><img src="' + rteImagePath + 'orderedlist.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Bullets">';
	tag += '					<div id="insertunorderedlist" class="rtebtn1"><img src="' + rteImagePath + 'unorderedlist.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Decrease Indent">';
	tag += '					<div id="outdent" class="rtebtn1"><img src="' + rteImagePath + 'decreaseindent.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Increase Indent">';
	tag += '					<div id="indent" class="rtebtn1"><img src="' + rteImagePath + 'increaseindent.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" id="rtesep8"><img src="' + rteImagePath + 'seperator.gif"></td>';
	tag += '				<td class="rtebg" title="Undo">';
	tag += '					<div id="undo" class="rtebtn1"><img src="' + rteImagePath + 'undo.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" title="Redo">';
	tag += '					<div id="redo" class="rtebtn1"><img src="' + rteImagePath + 'redo.gif"></div>';
	tag += '				</td>';
	tag += '				<td class="rtebg" id="rtesep9"><img src="' + rteImagePath + 'seperator.gif"></td>';
	tag += '				<td class="rtebg" id="cutcopypaste">';
	tag += '					<table border="0" width="0" cellspacing="0" cellpadding="0">';
	tag += '						<tr>';
	if (!document.all || window.opera) {
		tag += '						<td title="Cut">';
		tag += '							<div class="rtebtn5"><img src="' + rteImagePath + 'cutgrey.gif"></div>';
		tag += '						</td>';
		tag += '						<td title="Copy">';
		tag += '							<div class="rtebtn5"><img src="' + rteImagePath + 'copygrey.gif"></div>';
		tag += '						</td>';
		tag += '						<td title="Paste">';
		tag += '							<div class="rtebtn5"><img src="' + rteImagePath + 'pastegrey.gif"></div>';
		tag += '						</td>';
	} else {
		tag += '						<td title="Cut">';
		tag += '							<div id="cut" class="rtebtn1"><img src="' + rteImagePath + 'cut.gif"></div>';
		tag += '						</td>';
		tag += '						<td title="Copy">';
		tag += '							<div id="copy" class="rtebtn1"><img src="' + rteImagePath + 'copy.gif"></div>';
		tag += '						</td>';
		tag += '						<td title="Paste">';
		tag += '							<div id="paste" class="rtebtn1"><img src="' + rteImagePath + 'paste.gif"></div>';
		tag += '						</td>';
	}
	tag += '						</tr>';
	tag += '					</table>';
	tag += '				</td>';
	tag += '				<td width="14"><img src="' + rteImagePath + 'finish.gif" width="14" height="25" /></td>';
	tag += '				<td width="100%">';
	tag += '				</td>';
	tag += '			</tr>';
	tag += '		</table>';
	tag += '	</td>';
	tag += '</tr>';
	return tag;
}
function getToolbar3Tag(rteImagePath) {
	var tag = '';
	tag += '<tr>';
	tag += '	<td bgcolor="#C3DAF9">';
	//tag += '	<td bgcolor="#FFFFFF">';
	tag += '		<table cellpadding="0" cellspacing="0" id="tb3" onmousedown="return false;">';
	tag += '			<tr>';
	tag += '				<td width="7"><img src="' + rteImagePath + 'start.gif" width="7" height="25" /></td>';
	tag += '				<td class="rtebg" title="Form">';
	tag += '							<a href="javascript:rteBtnInsertForm();" style="cursor:default;">';
	tag += '					<div id="insertform" class="rtebtn1"><img src="' + rteImagePath + 'form.gif" border="0"></div>';
	tag += '				</a>';
	tag += '			</td>';
	tag += '				<td class="rtebg" title="Check Box">';
	tag += '				<a href="javascript:rteBtnInsertCheckbox();" style="cursor:default;">';
	tag += '					<div id="form_checkbox" class="rtebtn1"><img src="' + rteImagePath + 'checkbox.gif" border="0"></div>';
	tag += '				</a>';
	tag += '			</td>';
	tag += '				<td class="rtebg" title="Radio Button">';
	tag += '				<a href="javascript:rteBtnInsertRadio();" style="cursor:default;">';
	tag += '					<div id="form_radio" class="rtebtn1"><img src="' + rteImagePath + 'radio.gif" border="0"></div>';
	tag += '				</a>';
	tag += '			</td>';
	tag += '				<td class="rtebg" title="Text Area">';
	tag += '				<a href="javascript:rteBtnInsertTextArea();" style="cursor:default;">';
	tag += '					<div id="form_textarea" class="rtebtn1"><img src="' + rteImagePath + 'textarea.gif" border="0"></div>';
	tag += '				</a>';
	tag += '			</td>';
	tag += '				<td class="rtebg" title="Submit Button">';
	tag += '				<a href="javascript:rteBtnInsertSubmit();" style="cursor:default;">';
	tag += '					<div id="form_submit" class="rtebtn1"><img src="' + rteImagePath + 'submit.gif" border="0"></div>';
	tag += '				</a>';
	tag += '			</td>';
	tag += '				<td class="rtebg" title="Image Button">';
	tag += '				<a href="javascript:rteBtnInsertImageSubmit();" style="cursor:default;">';
	tag += '					<div id="form_image_submit" class="rtebtn1"><img src="' + rteImagePath + 'imagesubmit.gif" border="0"></div>';
	tag += '				</a>';
	tag += '			</td>';
	tag += '				<td class="rtebg" title="Reset Button">';
	tag += '				<a href="javascript:rteBtnInsertReset();" style="cursor:default;">';
	tag += '					<div id="form_reset" class="rtebtn1"><img src="' + rteImagePath + 'reset.gif" border="0"></div>';
	tag += '				</a>';
	tag += '			</td>';
	tag += '				<td class="rtebg" title="Hidden Field">';
	tag += '				<a href="javascript:rteBtnInsertHidden();" style="cursor:default;">';
	tag += '					<div id="form_hidden" class="rtebtn1"><img src="' + rteImagePath + 'hidden.gif" border="0"></div>';
	tag += '				</a>';
	tag += '			</td>';
	tag += '				<td class="rtebg" title="Password Field">';
	tag += '				<a href="javascript:rteBtnInsertPassword();" style="cursor:default;">';
	tag += '					<div id="form_password" class="rtebtn1"><img src="' + rteImagePath + 'password.gif" border="0"></div>';
	tag += '				</a>';
	tag += '			</td>';
	tag += '				<td class="rtebg" title="Text Field">';
	tag += '				<a href="javascript:rteBtnInsertText();" style="cursor:default;">';
	tag += '					<div id="form_textfield" class="rtebtn1"><img src="' + rteImagePath + 'textfield.gif" border="0"></div>';
	tag += '				</a>';
	tag += '			</td>';
	tag += '				<td class="rtebg" id="rtesep10"><img src="' + rteImagePath + 'seperator.gif"></td>';
	tag += '				<td class="rtebg" title="Print">';
	tag += '				<div id="printrte" class="rtebtn1"><img src="' + rteImagePath + 'print.gif" onClick="rteBtnPrint();"></div>';
	tag += '			</td>';
	tag += '				<td class="rtebg" title="Select All">';
	tag += '				<div id="selectall" class="rtebtn1"><img src="' + rteImagePath + 'selectall.gif"></div>';
	tag += '			</td>';
	tag += '			<td id="spellchecker" class="rtebg" title="Spell Check">';
	tag += '				<div id="spellcheck" class="rtebtn5"><img src="' + rteImagePath + 'spellcheckgrey.gif"></div>';
	tag += '			</td>';
	tag += '				<td class="rtebg" id="rtesep11"><img src="' + rteImagePath + 'seperator.gif"></td>';
	tag += '				<td class="rtebg" title="About Free Rich Text Editor">';
	tag += '				<a href="javascript:rteAbout();" style="cursor:default;">';
	tag += '					<div id="aboutrte" class="rtebtn1"><img src="' + rteImagePath + 'about.gif" border="0"></div>';
	tag += '				</a>';
	tag += '			</td>';
	tag += '				<td width="14"><img src="' + rteImagePath + 'finish.gif" width="14" height="25" /></td>';
	tag += '				<td width="100%"></td>';
	tag += '			</tr>';
	tag += '		</table>';
	tag += '	</td>';
	tag += '</tr>';
	return tag;
}
function getViewTag(rteName, rteFormName, rteWidth, rteHeight) {
	var tag = '';
	tag += '<tr>';
	//tag += '	<td style="border:1px solid #C3DAF9; ">';
	tag += '	<td style="border:1px solid #FFFFFF; ">';
	tag += '		<iframe name="' + rteName + '" id="' + rteName + '" style="width:100%; height:' + rteHeight + '; background-color:#FFFFFF;" frameborder="0">';
	tag += '		</iframe>';
	tag += '		<textarea name="' + rteFormName + '" id="' + rteFormName + '" style="display:none;width:' + rteWidth + '; height:' + rteHeight + '; background-color:#FFFFFF; font-family:courier new; font-size:12px; color:#000000; border:0px;">';
	tag += '		</textarea>';
	tag += '		<iframe id="preview_' + rteName + '" style="width:' + rteWidth + '; height:' + rteHeight + '; background-color:#FFFFFF; display:none;" frameborder="0">';
	tag += '		</iframe>';
	tag += '	</td>';
	tag += '</tr>';
	return tag;
}
function getViewModeTag(rteImagePath) {
	var tag = '';
	tag += '<tr id="view_mode">';
	//tag += '	<td bgcolor="#C3DAF9" height="25" class="rtebg">';
	tag += '	<td bgcolor="#FFFFFF" height="25" class="rtebg">';
	tag += '		<table width="100%" cellspacing="0" cellpadding="0" border="0" onmousedown="return false;">';
	tag += '			<tr>';
	tag += '				<td>';
	tag += '					<table width="0" cellspacing="3" cellpadding="0" border="0" class="rtebg">';
	tag += '						<tr>';
	tag += '							<td style="color:#000000; font-family:arial; font-size:11px;">';
	tag += '								<div class="rtebtn9" id="rte_design_mode" onclick="rteModeType(\'rte_design_mode\');" style="line-height:15px;"><img src="' + rteImagePath + 'design.gif">&nbsp;Design</div>';
	tag += '							</td>';
	tag += '							<td style="color:#000000; font-family:arial; font-size:11px;">';
	tag += '								<div class="rtebtn6" id="rte_code_mode" onclick="rteModeType(\'rte_code_mode\');" style="line-height:15px;"><img src="' + rteImagePath + 'code.gif">&nbsp;Code</div>';
	tag += '							</td>';
	tag += '							<td style="color:#000000; font-family:arial; font-size:11px;">';
	tag += '								<div class="rtebtn6" id="rte_preview_mode" onclick="rteModeType(\'rte_preview_mode\');" style="line-height:15px;"><img src="' + rteImagePath + 'preview.gif">&nbsp;Preview</div>';
	tag += '							</td>';
	tag += '						</tr>';
	tag += '					</table>';
	tag += '				</td>';
	tag += '			</tr>';
	tag += '		</table>';
	tag += '	</td>';
	tag += '</tr>';
	return tag;
}
function getEditorTag(rteName, rteFormName, rteWidth, rteHeight, rteImagePath) {
	var tag = '';
	tag += '<input type="hidden" id="preview_css" value="/css/editor_content.css">';
	tag += '<input type="hidden" id="iframe_name" value="' + rteName + '">';
	
	//tag += '<table style="width:' + rteWidth + ';border-left:1px solid #3B619C;border-right:1px solid #3B619C;border-top:1px solid #3B619C;" cellpadding="0" cellspacing="0">';
	tag += '<table style="width:' + rteWidth + ';border:1px solid #CCCCCC;" cellpadding="0" cellspacing="0">';
	
	tag += getToolbar1Tag(rteImagePath);
	tag += getToolbar2Tag(rteImagePath);
	tag += getToolbar3Tag(rteImagePath);
	tag += getViewTag(rteName, rteFormName, rteWidth, rteHeight);
	tag += getViewModeTag(rteImagePath);
	
	tag += '</table>';
	return tag;
}
ViiKii.Editor = {
	isOpened: false,
	isEditorOpened: false,
	closeCallback: null,
	lastOpenedId: null,
	
	openEditor: function(id, height, rtePreloadContent, uploadUrl) {
		rteImageUploadUrl = uploadUrl;
		rteHeight = height + 'px';
		this.isEditorOpened = true;
		this.lastOpenedId = id;
		$(id).innerHTML = getEditorTag(rteName, rteFormName, rteWidth, rteHeight, rteImagePath);
		startRTE(rtePreloadContent);
		menuBuilder();
		
		// because of IE, safari insert image bug
		document.getElementById(rteName).contentWindow.focus();
	},
	setContent: function(content) {
		document.getElementById(rteName).contentWindow.document.body.innerHTML = content;
	},
	setCloseCallback: function(closeCallback) {
		this.closeCallback = closeCallback;
	},
	closeEditor: function() {
		this.isOpened = false;
		this.isEditorOpened = false;
		if($(this.lastOpenedId)) {
			$(this.lastOpenedId).innerHTML = '';
		}
		document.body.focus();
	},
	getEditorContent: function() {
		return getXHTML(trim(document.getElementById(rteName).contentWindow.document.body.innerHTML));
	}
};
ViiKii.Forum = {
	_MAX_FIELD_COUNT: 5,
	_topicFields: [],

	init: function() {
		this._topicFields = [];
	},
	checkField: function(fieldId) {
		if ($('field_chkbox_' + fieldId).src.indexOf('/common/checkbox_wh.gif') >= 0) {
			if (this._topicFields.length < this._MAX_FIELD_COUNT) {
				$('field_chkbox_' + fieldId).src = '/common/checkbox_ch.gif';
				this._topicFields.push(fieldId);
			}
		} else {
			var index = this._topicFields.indexOf(fieldId);
			this._topicFields.splice(index, 1);
			$('field_chkbox_' + fieldId).src = '/common/checkbox_wh.gif';
		}
	},

	addNewTopic: function(backUrl) {
		var frm = $('topic_add_form');
		if(frm['data[topic][title]'].value.length > 255) {
			alert('Title must be 255 characters or less!');
			return;
		}

		var notWhiteSpace = new RegExp(/[^\s]/);

		if (!notWhiteSpace.test(frm['data[topic][tag]'].value) || frm['data[topic][tag]'].value == 'Separate tags with commas.') {
			frm['data[topic][tag]'].value = '';
		}
		if (notWhiteSpace.test(frm['data[topic][title]'].value)) {
			frm['data[topic][title]'].value = this.replaceContent(frm['data[topic][title]'].value);
		} else {
			alert('Not exist Title!');
			return;
		}
		var content = ViiKii.Topic.Editor.NewTopic.getContent();
		if (notWhiteSpace.test(content) && content != "&nbsp;") {
			frm['data[topic][content]'].value = content;
		} else {
			alert('Not exist Content!');
			return;
		}
		frm['data[topic][content]'].value = frm['data[topic][content]'].value;
		frm['data[topic][field]'].value = this._topicFields;
		var param = frm.serialize();

		var ajax = new Ajax.Request(
			'/forums/add_new_topic/'+$('forum_id').value,
			{
				asynchronous: false,
				parameters: param
			}
		);
		this.onAddNewTopic(ajax.evalJSON(), backUrl);
	},
	onAddNewTopic: function(response, backUrl) {
		//alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			document.location = backUrl;
			return;
		}
		switch(response.error) {
		case 'INVALID_FORUM':
			alert('This forum is deleted.');
			document.location = '/forums/forum_list';
			break;
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'DB_ERROR':
			alert('Fail to save a new topic. Please try again!');
			break;
		case 'OUT_OF_LENGTH':
			alert("The content is out of length.");
			return;
		}
	},

	replaceContent: function(value) {
		var carriageReturn = new RegExp(/\n/g);
		var backSlash = new RegExp(/\\/g);
		var quotation = new RegExp(/\'/g);
		var leftBracket = new RegExp(/\</g);
		var rightBracket = new RegExp(/\>/g);
		var urlLink	= new RegExp(/(http|https|ftp|telnet|news):\/\/([a-z0-9_\-]+\.[][a-zA-Z0-9:;&#@=_~%\?\/\.\,\+\-]+)/g);

		if (backSlash.test(value)) {
			value = value.replace(backSlash, "\\\\");
		}
		if (quotation.test(value)) {
			value = value.replace(quotation, "\\\'");
		}
		if (leftBracket.test(value)) {
			value = value.replace(leftBracket, "&lt;");
		}
		if (rightBracket.test(value)) {
			value = value.replace(rightBracket, "&gt;");
		}
		if (carriageReturn.test(value)) {
			value = value.replace(carriageReturn, "<br>");
		}
		return value;
	}
};

ViiKii.Forum.Folder = {
	_folderId: 0,
	_depth: 0,
	_contextMenuOpened: false,
	_popupedList: true,
	
	_isSubFolder: function(depth) {
		return depth == 2;
	},
	refresh: function() {
		new Ajax.Updater(
			'forum_folder_layer',
			'/forums/folders/'+$('forum_folder_group_id').value+'/'+$('forum_folder_type').value,
			{ evalScripts: true }
		);
	},
	popupList: function(isOwner) {
		if (this._popupedList) {
			this._closeList(isOwner);
		} else {
			this._openList(isOwner);
		}
	},
	_openList: function(isOwner) {
		$('forum_folder_list_popup').style.display = 'block';
		$('forum_folder_list_bullet').src = '/common/bullet001_s.gif';
		if (isOwner) {
			$('new_forum_folder_menu').style.display = 'block';
		}
		this._popupedList = true;
	},
	_closeList: function(isOwner) {
		$('forum_folder_list_popup').style.display = 'none';
		$('forum_folder_list_bullet').src = '/common/bullet001_s_rotate.gif';
		if (isOwner) {
			$('new_forum_folder_menu').style.display = 'none';
		}
		this._popupedList = false;
	},
	add: function(event, forumId, parentFolderId) {
		if (this.isOpenEditInputBox()) {
			this.closeEditInputBox();
		}
		Event.stop(event); //For openEditInputBox function
		this.closeContextMenu();
		if (typeof parentFolderId == "undefined") {
			parentFolderId = this._folderId;
		}
		
		var ajax = new Ajax.Request("/forums/addFolder/" + $("forum_folder_forum_id").value + "/" + parentFolderId, {
			asynchronous:false,
			onComplete: function(transport, response) {
				var locked = 0;
				if ("success" == response.result) {
					if (0 == response.parentFolderId) {
						depth = 1;
						var channelId = $F('forum_folder_group_id');
						var tag = "<div id='forum_folder_"+response.folderId+"' class='folder' onclick='ViiKii.Channel.Topic.showFolderTopics("+channelId+", "+response.folderId+", "+depth+")' oncontextmenu='ViiKii.Forum.Folder.onContextMenu(event, "+response.folderId+", "+depth+", "+locked+")'>"
								+ "<span id='forum_folder_name_"+response.folderId+"'>" + response.folderName + "</span> <span>(0)</span></div>"
								+ "<div id='forum_subfolders_"+response.folderId+"' style='display:none;float:left;width:193px;'></div>";
						$('forum_folder_list').update(tag + $("forum_folder_list").innerHTML);
						if ( ! $("forum_folder_list").visible()) {
							$("forum_folder_list").show();
						}
					} else {
						depth = 2;
						var channelId = $F('forum_folder_group_id');
						var tag = "<div id='forum_folder_"+response.folderId+"' class='sub_folder' onclick='ViiKii.Forum.showFolderTopics("+channelId+", "+response.folderId+", "+depth+")' oncontextmenu='ViiKii.Forum.Folder.onContextMenu(event, "+response.folderId+", "+depth+", "+locked+")'>"
								+ "- <span id='forum_folder_name_"+response.folderId+"'>"+response.folderName+"</span> <span>(0)</span>"
								+ "</div>";
						$('forum_subfolders_' + response.parentFolderId).update(tag + $('forum_subfolders_' + response.parentFolderId).innerHTML);
						if ( ! $('forum_subfolders_' + response.parentFolderId).visible()) {
							$('forum_folder_' + response.parentFolderId).setStyle({background : 'rgb(128, 128, 128) url(/img/common/bullet003_ss_down.gif) no-repeat 188px center'});
							$('forum_subfolders_' + response.parentFolderId).show();
						}
					}
					ViiKii.Forum.Folder.openEditInputBox(null, response.channelId, response.folderId, depth);
				} else {
					alert("Fail, to add folder");
				}
			}
		});
	},
	remove: function(forumId) {
		this.closeContextMenu();
		var ajax = new Ajax.Request("/forums/removeFolder/" + $F("forum_folder_forum_id") + "/" + this._folderId, {
			asynchronous:false,
			onComplete: function(transport, response) {
				if ("success" == response.result) {
					if ($("forum_folder_" + response.folderId)) {
						$("forum_folder_" + response.folderId).remove();
					}
					// this condition for only IE browser!!
					if ($("forum_subfolders_" + response.parentFolderId) && $("forum_subfolders_" + response.parentFolderId).innerHTML.trim().empty()) {
						$("forum_subfolders_" + response.parentFolderId).hide();	
					}
					if ($("forum_subfolders_" + response.folderId)) {
						$("forum_subfolders_" + response.folderId).remove();
					}
					if ($("forum_folder_list").innerHTML.trim().empty()) {
						$("forum_folder_list").hide();
					}
				} else {
					alert("Fail, to remove this folder");
				}
			}
		});
	},
	lock: function(forumId) {
		this.closeContextMenu();
		new Ajax.Request('/forums/lockFolder/' + $('forum_folder_forum_id').value + '/' + this._folderId, {asynchronous:false});
		this.refresh();
	},
	unlock: function(forumId) {
		this.closeContextMenu();
		new Ajax.Request('/forums/unLockFolder/' + $('forum_folder_forum_id').value + '/' + this._folderId, {asynchronous:false});
		this.refresh();
	},
	openEditInputBox: function(event, channelId, folderId, depth) {
		if (null != event) {
			Event.stop(event);
		}
		
		if (typeof folderId != "undefined" && typeof depth != "undefined") {
			this._folderId = folderId;
			this._depth = depth;
		}
		this.closeContextMenu();

		this._channelId = channelId;
		this._oldFolderInnerHTML = $('forum_folder_' + this._folderId).innerHTML;
		var folderName = $('forum_folder_name_' + this._folderId).innerHTML;

		var color = '#ffffff';
		if (this._isSubFolder(this._depth)) {
			color = '#808080';
		}

		$('forum_folder_' + this._folderId).innerHTML = "<input id='forum_folder_" 
				+ this._folderId 
				+ "_edit' type='text' onKeyDown='ViiKii.Forum.Folder.onKeyDown(event)' style='width:99%;border:0;background-color:transparent;color:" 
				+ color + "' maxlength='80' onclick='Event.stop(event)'>";
		$('forum_folder_' + this._folderId + '_edit').value = folderName;
		$('forum_folder_' + this._folderId + '_edit').focus();

		this._editInputBoxOpened = true;
	},
	onKeyDown: function(event) {
		switch(event.keyCode) {
			case Event.KEY_RETURN:
				var folderName = $('forum_folder_' + this._folderId + '_edit').value;
				this.closeEditInputBox();
				this.rename(this._channelId, folderName);
				break;
			case Event.KEY_ESC:
				this.closeEditInputBox();
				break;
		}
	},
	isOpenEditInputBox: function() {
		return this._editInputBoxOpened;
	},
	closeEditInputBox: function() {
		$('forum_folder_' + this._folderId).innerHTML = this._oldFolderInnerHTML;
		this._editInputBoxOpened = false;
	},
	rename: function(forumId, folderName) {
		var params = $H(
			{
				'forumId': $('forum_folder_forum_id').value,
				'folderId' : this._folderId,
				'folderName': folderName
			}
		).toQueryString();
		
		var ajax = new Ajax.Request("/forums/renameFolder/", {
			asynchronous:false, 
			parameters:params,
			onComplete: function(transport, response) {
				if ("success" == response.result) {
					if ($("forum_folder_name_" + response.folderId)) {
						$("forum_folder_name_" + response.folderId).update(response.folderName);
					}
				} else {
					alert("Fail, to rename this folder");
				}
			}
		});
	},
	update: function(url, params) {
		if (typeof params == "undefined") {
			params = null;
		}
		var response = new Ajax.Updater(
			'forum_folder_layer',
			url,
			{
				asynchronous: true,
				evalScripts: true,
				parameters: params
			}
		);
	},
	isOpenContextMenu : function() {
		return this._contextMenuOpened;
	},
	closeContextMenu: function() {
		$('forum-folder-context-menu').style.display = 'none';
		this._contextMenuOpened = false;
	},
	onContextMenu: function(event, folderId, depth, locked) {
		if (this.isOpenEditInputBox()) {
			this.closeEditInputBox();
		}
		
		if ($('forum-folder-context-menu') == null) {
			return;
		}

		this._folderId = folderId;
		this._depth = depth;

		if (this._isSubFolder(depth)) {
			this._hiddenAddContextMenu();
		} else {
			this._showAddContextMenu();
		}
		/*
		if (locked) {
			this._showUnLockContextMenu();
		} else {
			this._showLockContextMenu();
		}
		*/

		$('forum-folder-context-menu').style.left = Event.pointerX(event) + 'px';
		$('forum-folder-context-menu').style.top = Event.pointerY(event) + 'px';
		$('forum-folder-context-menu').style.display = 'block';
		this._contextMenuOpened = true;
		Event.stop(event);	// remove document original contextmenu event
	},
	_showAddContextMenu: function() {
		$('forum-folder-context-menu-add').style.display = 'block';
	},
	_hiddenAddContextMenu: function() {
		$('forum-folder-context-menu-add').style.display = 'none';
	},
	_showUnLockContextMenu: function() {
		$('forum-folder-context-menu-lock').style.display = 'none';
		$('forum-folder-context-menu-unlock').style.display = 'block';
	},
	_showLockContextMenu: function() {
		$('forum-folder-context-menu-lock').style.display = 'block';
		$('forum-folder-context-menu-unlock').style.display = 'none';
	},
	popupListLastStatus: function(isOwner) {
		if (this._popupedList) {
			this._openList(isOwner);
		}
	}
};
ViiKii.Forum.TopicList = {
	objectId: 'ViiKii.Forum.TopicList',
	isSelectAll: true,
	topics: {},
	init: function() {
		this.topics = {};
		this.isSelectAll = true;
	},
	addTopic: function(topicId) {
		this.topics[topicId] = false;
	},
	check: function(topicId) {
		this.changeCheck(topicId, !this.topics[topicId]);
	},
	checkAll: function() {
		for(var topic in this.topics) {
			if(this.topics[topic] != this.isSelectAll) {
				this.changeCheck(topic, this.isSelectAll);
			}
		}
		this.changeCheckAll(!this.isSelectAll);
	},
	changeCheckAll: function(checked) {
		this.isSelectAll = checked;
		this.changeCheckImage("ViiKii.Forum.TopicList.checkAll", !checked);
		if(checked) {
			$("ViiKii.Forum.TopicList.checkAllText").innerHTML = "Select All";
		} else {
			$("ViiKii.Forum.TopicList.checkAllText").innerHTML = "Unselect All";
		}
	},
	changeCheck: function(topicId, checked) {
		this.topics[topicId] = checked;
		this.changeCheckImage('topic_checkbox_'+topicId, checked);
	},
	changeCheckImage: function(id, checked) {
		var src = "";
		if(checked) {
			src = "/common/checkbox_ch.gif";
		} else {
			src = "/common/checkbox_wh.gif";
		}
		$(id).src = src;
	},
	getTopics: function() {
		var result = [];
		for(var topic in this.topics) {
			if(this.topics[topic]) {
				result.push(topic);
			}
		}
		return result;
	},
	refreshList: function() {
		if(ViiKii.Util.get(this, 'type') == 'FORUM') {
			ViiKii.Forum.showForumTopics(ViiKii.Util.get(this, 'groupId'), 1, ViiKii.Util.get(this, 'folder'));
		} else if(ViiKii.Util.get(this, 'type') == 'CHANNEL') {
			ViiKii.Channel.Topic.refresh.bind(ViiKii.Channel.Topic);
			ViiKii.Channel.Topic.refresh();
		}
	},
	onDeletedForum: function() {
		if(ViiKii.Util.get(this, 'type') == 'FORUM') {
			alert("This forum is deleted");
			document.location = '/forums/forum_list';
		} else if(ViiKii.Util.get(this, 'type') == 'CHANNEL') {
			this.refreshList();
			ViiKii.Forum.Folder.refresh();
		}
	},
	del: function() {
		if(!this.topicSelected()) {
			alert("Select available topics first.");
			return;
		}
		if (!confirm('Do you really want to remove the topics from this forum?')) {
			return;
		}
		var params = $H(
			{
				'topics': this.getTopics().join(",")
			}
		).toQueryString();
		var ajax = new Ajax.RequestXML(
			'/forums/delete_topics/'+ViiKii.Util.get(this, 'forumId'),
			{
				parameters: params,
				asynchronous: false
			}
		);
		this.onSuccessDelete(ajax);
	},
	onSuccessDelete: function(ajax) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.refreshList();
			ViiKii.Forum.Folder.refresh();
			return;
		}
		switch(response.error) {
		case 'INVALID_FORUM':
			this.onDeletedForum();
			return;
		case 'NOT_OWNER':
			alert("You are not the owner of this forum");
			return;
		case 'INVALID_INPUT':
			alert("Select available topics first!");
			return;
		}
	},
	setAnnounce: function() {
		//alert("set announce: "+forumId+" "+this.getTopics());
		this.setTopicClass('A');
	},
	cancelAnnounce: function() {
		//alert("cancel announce: "+forumId+" "+this.getTopics());
		this.setTopicClass('G');
	},
	setTopicClass: function(topicClass) {
		if(!this.topicSelected()) {
			alert("Select available topics first.");
			return;
		}
		var params = $H(
			{
				'topics': this.getTopics().join(",")
			}
		).toQueryString();
		var ajax = new Ajax.RequestXML(
			'/forums/set_topic_class/'+ViiKii.Util.get(this, 'forumId')+'/'+topicClass,
			{
				parameters: params,
				asynchronous: false
			}
		);
		this.onSetTopicClass(ajax);
	},
	onSetTopicClass: function(ajax) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.refreshList();
			return;
		}
		switch(response.error) {
		case 'INVALID_FORUM':
			this.onDeletedForum();
			return;
		case 'NOT_OWNER':
			alert("You are not the owner of this forum");
			return;
		case 'INVALID_INPUT':
			alert("Select available topics first!");
			return;
		}
	},
	topicSelected: function() {
		return this.getTopics().length > 0; 
	}
};
ViiKii.Forum.TopicList.MoveToPopup = {
	objectId: 'ViiKii.Forum.TopicList.MoveToPopup',
	folders: {},
	open: function() {
		new Ajax.Updater(
			'ViiKii.Forum.TopicList.moveTo',
			'/forums/move_to/'+ViiKii.Util.get(this, 'forumId')+'/'+ViiKii.Util.get(this, 'folder'),
			{ evalScripts: true }
		);
		Element.show('ViiKii.Forum.TopicList.moveTo');
	},
	close: function() {
		Element.hide('ViiKii.Forum.TopicList.moveTo');
	},
	init: function() {
		this.folders = {};
	},
	addFolder: function(folderId) {
		this.folders[folderId] = false;
	},
	check: function(folderId) {
		this.uncheckAll();
		this.changeCheck(folderId, !this.folders[folderId]);
	},
	uncheckAll: function() {
		for(var folder in this.folders) {
			if(this.folders[folder]) {
				this.changeCheck(folder, false);
			}
		}
	},
	changeCheck: function(folderId, checked) {
		this.folders[folderId] = checked;
		this.changeCheckImage('folder_checkbox_'+folderId, checked);
	},
	changeCheckImage: function(id, checked) {
		var src = "";
		if(checked) {
			src = "/common/checkbox_ch.gif";
		} else {
			src = "/common/checkbox_wh.gif";
		}
		$(id).src = src;
	},
	getFolders: function() {
		var result = [];
		for(var folder in this.folders) {
			if(this.folders[folder]) {
				result.push(folder);
			}
		}
		return result;
	},
	move: function() {
		if(ViiKii.Forum.TopicList.getTopics().length == 0) {
			alert("Select available topics first.");
			return;
		}
		if(this.getFolders().length == 0) {
			alert("Select available folder first.");
			return;
		}
		var params = $H(
			{
				'topics': ViiKii.Forum.TopicList.getTopics().join(","),
				'folder': this.getFolders()[0]
			}
		).toQueryString();
		var ajax = new Ajax.RequestXML(
			'/forums/move_topics_to/'+ViiKii.Util.get(this, 'forumId'),
			{
				asynchronous: false,
				parameters: params
			}
		);
		this.onSuccessMove(ajax);
	},
	onSuccessMove: function(ajax) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			alert('Topics are moved successfully!');
			this.close();
			ViiKii.Forum.TopicList.refreshList.bind(ViiKii.Forum.TopicList);
			ViiKii.Forum.TopicList.refreshList();
			ViiKii.Forum.Folder.refresh();
			return;
		}
		switch(response.error) {
		case 'INVALID_FORUM':
			ViiKii.Forum.TopicList.onDeletedForum.bind(ViiKii.Forum.TopicList);
			ViiKii.Forum.TopicList.onDeletedForum();
			return;
		case 'NOW_OWNER':
			alert("You are not the owner of this forum");
			return;
		case 'EMPTY_TOPIC':
			alert("Select available topics first.");
			return;
		case 'EMPTY_FOLDER':
			alert("Select available folder first.");			return;
		case 'INVALID_FOLDER':
			alert("The folder is deleted.");
			ViiKii.Forum.TopicList.MoveToPopup.open();
			return;	
		}
	}
};
ViiKii.Forum.TopicList.SuggestPopup = Object.clone(ViiKii.Forum.TopicList.MoveToPopup);
ViiKii.Forum.TopicList.SuggestPopup.objectId = 'ViiKii.Forum.TopicList.SuggestPopup';
ViiKii.Forum.TopicList.SuggestPopup.open = function() {
	new Ajax.Updater(
		'ViiKii.Forum.TopicList.suggest',
		'/forums/suggest_directory/'+ViiKii.Util.get(this, 'forumId')+'/'+ViiKii.Util.get(this, 'folder'),
		{ evalScripts: true }
	);
	Element.show('ViiKii.Forum.TopicList.suggest');
};
ViiKii.Forum.TopicList.SuggestPopup.close = function() {
	Element.hide('ViiKii.Forum.TopicList.suggest');
};
ViiKii.Forum.TopicList.SuggestPopup.changeCheck = function(folderId, checked) {
	this.folders[folderId] = checked;
	this.changeCheckImage('forum_suggest_checkbox_'+folderId, checked);
};
ViiKii.Forum.TopicList.SuggestPopup.ok = function() {
	if(this.getFolders().length == 0) {
		alert("Select available folder first.");
		return;
	}
	this.close();
	ViiKii.Forum.TopicList.SuggestPopup.Popup.open.bind(ViiKii.Forum.TopicList.SuggestPopup.Popup);
	ViiKii.Forum.TopicList.SuggestPopup.Popup.open(ViiKii.Util.get(this, 'forumId'), this.getFolders()[0]);
};
ViiKii.Forum.TopicList.SuggestPopup.Popup = {
	layerName: 'forum_suggest_popup_layer',
	open: function(forumId, folder) {
		new Ajax.Request(
			'/forums/suggest_popup/' + forumId + '/' + folder,
			{
				onSuccess :this.onOpen.bind(this)
			}
		);
	},
	onOpen: function(transport) {
		var posLeft = (document.body.scrollWidth - 618) / 2;
		var posTop = Position.realOffset(document.body)[1] + 150;
	
		var layerName = this.layerName;
		if ($(layerName)) {
			$(layerName).innerHTML = transport.responseText.stripScripts();
			$(layerName).style.display = 'block';
		} else {
			var e = document.createElement('div');
			e.id = layerName;
			var styles = {
				position :'absolute',
				top :posTop + 'px',
				left :posLeft + 'px',
				width :'310px',
				height :'120px',
				backgroundColor :'#FFFFFF'
			};
			Element.setStyle(e, styles);
			e.innerHTML = transport.responseText.stripScripts();
			document.getElementsByTagName('body')[0].appendChild(e);
		}
		ViiKii.UI.Round.init(layerName, {
			corners :'all',
			borderSize :1
		});
		setTimeout( function() {
			transport.responseText.evalScripts();
		}.bind(this), 0);
	},
	close : function() {
		$(this.layerName).style.display = 'none';
	},
	add : function(forumId, folder) {
		var topicUrl = $('suggsted_topic_url').value;
		topicUrl = topicUrl.trim();
		if (topicUrl == '') {
			alert('Insert available Topic URL first.');
			return;
		}
		var params = $H( {
			topic_url :topicUrl
		}).toQueryString();
		new Ajax.Request(
			'/forums/add_suggest/'+forumId+'/'+folder,
			{
				parameters :params,
				onComplete: this.onAdd.bind(this)
			}
		);
	},
	onAdd : function(transport, response) {
		if (response.result == 'SUCCESS') {
			this.close();
			alert('Suggsted successfully');
			ViiKii.Forum.TopicList.refreshList.bind(ViiKii.Forum.TopicList);
			ViiKii.Forum.TopicList.refreshList();
			ViiKii.Forum.Folder.refresh();
			return;
		}
		switch (response.error) {
		case 'NOT_LOG_IN':
			this.close();
			ViiKii.Login.popUp();
			break;
		case 'INVALID_TOPIC':
			alert('Insert available Topic URL first.');
			break;
		case 'DUP_TOPIC':
			alert('The topic is already suggested.');
			break;
		case 'INVALID_FORUM':
			this.close();
			alert('Invalid forum');
			break;
		}
	}
};
ViiKii.Forum.Translator = {
	objectId: 'ViiKii.Forum.Translator',
	loadPage: function(curPage) {
		ViiKii.Util.set(this, 'curPage', curPage);
		this.updatePage();
	},
	updatePage: function() {
		new Ajax.Updater(
			'ViiKii.Forum.Translator.layer',
			'/forums/translators_new/'+ViiKii.Util.get(this, 'forumId')+'/'+ViiKii.Util.get(this, 'curPage'),
			{ evalScripts: true }
		);
	}
};
ViiKii.Inappro = {
	_itemId: 0,
	_category: '',
	_shadow: null,
	_popupLayer: null,
	_popupId: 'inappropriate_popup_layer',
	_width: 274,
	_height: 175,
	
	isLogined: function() {
		return ViiKii.Util.getDomainCookie('username') != null;
	},
	isPopuped: function() {
		return ($(this._popupId)) ? true : false; 
	},
	update: function() {
		var url = '/inappropriates/popup';
		var response = new Ajax.Updater(
			this._popupLayer,
			url,
			{
				asynchronous: false,
				evalScripts: true,
				parameters: null,
				onFailure: function(e) {
					alert(e.responseText); 
				}
			}
		);
	},
	
	position: function(ele) {
		var doc = document.body && (document.body.scrollTop || document.body.scrollLeft) ? document.body : document.documentElement;
		var pos = [];
		if (ele) {
			pos = Position.cumulativeOffset(ele);
			if ((pos[0] + this._width + 10) > (doc.clientWidth + doc.scrollLeft)) {
				pos[0] -= this._width;
			} else {
				pos[0] += 10;
			}
			if ((pos[1] + this._height) > (doc.clientHeight + doc.scrollTop)) {
				pos[1] -= this._height;
			}
		} else {
			// else case - video player
			pos = Position.cumulativeOffset($('player-panel'));
			pos[0] += 660;
			pos[1] += 324;
		}
		return pos;
	},
	
	popup : function(category, itemId, ele) {
		
		if (!this.isLogined()) {
			ViiKii.Login.popUp();
			return;
		}
		if (this.isPopuped()) {
			return;
		}
		//category : V-video, S-subtitle, B-Board, BT-BoardTranslate, I-Inbox
		this._category = category;
		this._itemId = itemId;
		var pos = this.position(ele);
		
		this._popupLayer = document.createElement('div');
		this._popupLayer.id = this._popupId;
		var style = {
			position: 'absolute',
			left: pos[0] + 'px',
			top: pos[1] + 'px',
			width: this._width + 'px',
			height: this._height + 'px',
			background: '#ffffff',
			"z-index": 5
		};
		
		Element.setStyle(this._popupLayer, style);
		document.getElementsByTagName('body')[0].appendChild(this._popupLayer);
		
		this.update();
		
		ViiKii.UI.Round.init(this._popupLayer, {coners: 'all', borderSize:1});
		this._shadow = new ViiKii.UI.Shadow(this._popupLayer);
		DragHandler.attach(this._shadow.container, $('inappro_popup_desc'));
	},
	
	report: function() {
		var params = $H({
			'category': this._category,
			'item_id': this._itemId,
			'reason': $F('inappro_reason')
		}).toQueryString();
		
		var url = "/inappropriates/report";
		var res = new Ajax.Request(
			url,
			{
				asynchronous: false,
				evalScripts: false,
				parameters: params,
				onComplete: function(transport) {
					//alert(transport.responseText);
				},
				onFailure: function(transport) {
					alert(transport.responseText);
				}
			}
		);
		this.discard();
	},
	discard : function() {
		if ($(this._popupId)) {
			document.getElementsByTagName('body')[0].removeChild($(this._shadow.container));
			this._popupLayer = null;
		}
	},
	popupRevision: function(id) {
		var res = new Ajax.Updater(
			'hidden_inappro',
			'/inappropriates/openSubtitle/' + id,
			{
				asynchronous :true,
				evalScripts :true,
				parameters :null,
				onFailure : function(transport) {
					alert(transport.responseText);
				}
			}
		);
	}
};if (!ViiKii) {
    ViiKii = {};
};
ViiKii.Menu = {
	isEditing: false,
	init: function() {
		this.isEditing = false;
	},
	isLogin: function() {
		return ViiKii.Util.getDomainCookie('username') != null;
	},
	clickCell: function(event) {
		if(!this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}

		var source = Event.element(event);
		var sourceId = source.id.split("_");
		if (this.isLogin() && sourceId[0] == 'cell') {
			this.editCell(source.id);
		} else if (sourceId[0] == 'revision') {
			this.revision(sourceId[1], sourceId[2]);
		} else if (this.isLogin() && sourceId[0] == 'save') {
			this.saveText();
		} else if (this.isLogin() && sourceId[0] == 'cancel') {
			this.onCancelSave();
		}
	},
	revision: function(uiId, languageId) {
		if(this.isEditing) {
			return;
		}
		ViiKii.Menu.Popup.open(uiId, languageId);
	},
	editCell: function(cellId) {
		if(this.isEditing) {
			return;
		}
		var onKeyEnterHandler = this.saveText;
		var onKeyESCHandler = this.onCancelSave;
		this.editableCell.onKeyESCDown = "ViiKii.Menu.onCancelSave()";
		this.editableCell.editCell(cellId);
		this.isEditing = true;
	},
	saveText: function() {
		if(!this.isEditing) {
			return;
		}
		var inputText = this.editableCell.getTextAreaText();
		inputText = inputText.trim();
		this.addTag(this.getMetaId(), this.getLanguage(), inputText);
	},
	getMetaId: function() {
		var cellId = this.editableCell.getCellId();
		return cellId.split("_")[1];
	},
	onRating: function(starBox, params) {
		/*
		ViiKii.TranslateDetails.starBox = starBox;
		var url = '/metas/rating/' + params + '/' + starBox.getPoint();
		new Ajax.Request(
			url,
			{
				asynchronous: true,
				evalScripts: false,
				parameter: null,
				onSuccess: function(transport) {
					if (transport.responseText.isNum()) {
						ViiKii.TranslateDetails.starBox.set(transport.responseText);
					};
				},
				onFailure: function(transport) {
					alert(transport.responseText);
				}
			}
		);
		*/
		alert("Under Construction!!");
	},
	update: function() {
		var req = new Ajax.Request(
			'/menus/listing/',
			{
				method: 'get',
				asynchronous: true,
				onSuccess: function(transport) {
					$('ViiKii.Menu.layer').innerHTML = transport.responseText;
				}
			}
		);
	},
	getLanguage: function() {
		var cellId = this.editableCell.getCellId();
		return cellId.split("_")[2];
	},
	addTag: function(uiId, language, menu) {
		var params=$H(
			{ui_id:uiId, language_id:language, menu:menu}
		).toQueryString();
		
		var xml = new Ajax.RequestXML(
			'/menus/add_menu/',
			{
				asynchronous: false,
				parameters: params
			}
		);
		this.onAddTagSuccess(xml.responseValue);
	},
	onAddTagSuccess: function(xml) {
		var response = xml.response;
		if(response.result == 'SUCCESS') {
			this.onSaveText(parseInt(response.revision, 10));
			this.update();
			return;
		}

		switch(response.error) {
		case 'DUPLICATED':
			alert("Somebody already posted the same translation as yours.");
			this.onCancelSave();
			break;
		case 'NOT_LOG_IN':
			this.onCancelSave();
			ViiKii.Login.popUp();
			break;
		case 'DB_ERROR':
			alert("Fail to add tag.");
			break;
		}
	},
	onSaveText: function(revision) {
		var inputText = this.editableCell.getTextAreaText();
		this.editableCell.setText(inputText, this.editableCell.getTagId(), revision);
		this.isEditing = false;
	},
	onCancelSave: function() {
		this.editableCell.cancelEdit();
		this.isEditing = false;
	},
	editableCell: new ViiKii.UI.EditableCell()
};
ViiKii.Menu.Popup = {
	uiId: 0,
	languageId: '',
	orderBy: '',
	inOrder: '',
	open: function(uiId, languageId) {
		this.uiId = uiId;
		this.languageId = languageId;
		this.orderBy = 'T';
		this.inOrder = '1';
		var req = new Ajax.Request(
			'/menus/popup/'+uiId+"/"+languageId,
			{
				asynchronous: true,
				evalScripts: true,
				onSuccess: this.onOpenMenu
			}
		);
	},
	onOpenMenu: function(transport) {
		var posLeft = (document.body.scrollWidth - 618) / 2;
		var posTop  = Position.realOffset(document.body)[1] + 150;
		
		var layerName = "ViiKii.Menu.Popup.layer";
		if ($(layerName)) {
			$(layerName).innerHTML = transport.responseText;
			$(layerName).style.display = 'block';
		} else {
			var e = document.createElement('div');
			e.id = layerName;
			var styles = {
				position: 'absolute',
				top:posTop+'px',
				left:posLeft+'px',
				width: '672px',
				height: '521px',
				backgroundColor: '#FFFFFF'
			};
			Element.setStyle(e, styles);
			e.innerHTML = transport.responseText;
			document.getElementsByTagName('body')[0].appendChild(e);
		}
		ViiKii.UI.Round.init(layerName, {corners:'all', borderSize:1});
	},
	inapproprite: function(menuId) {
		alert("Under Construction!!");
	},
	del: function(menuId) {
		if (!confirm('Do you really want to delete this translation?')) {
			return;
		}
		var ajax = new Ajax.RequestXML(
			'/menus/delete_menu/'+menuId,
			{
				asynchronous: false,
				method: 'get'
			}
		);
		this.onDeleteMenu(ajax);
	},
	onDeleteMenu: function(ajax) {
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.refresh();
			return;
		}
		switch(response.error) {
		case 'NOT_OWNER':
			this.refresh();
			break;
		case 'DB_ERROR':
			alert("Fail to delete translation.");
			break;
		}
	},
	addMenu: function() {
		var menu = $('ViiKii.Menu.Popup.input').value;
		if(menu == '') {
			alert("Insert available translation first");
			return;
		}
		var params=$H(
			{ui_id:this.uiId, language_id:this.languageId, menu:menu}
		).toQueryString();
		var ajax = new Ajax.RequestXML(
			'/menus/add_menu/',
			{
				asynchronous: false,
				parameters: params
			}
		);
		this.onAddMenuSuccess(ajax);
	},
	onAddMenuSuccess: function(ajax) {
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.refresh();
			return;
		}

		switch(response.error) {
		case 'DUPLICATED':
			alert("Somebody already posted the same translation as yours.");
			break;
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'DB_ERROR':
			alert("Fail to add translation.");
			break;
		}
	},
	refresh: function() {
		this.loadList(this.uiId, this.languageId, this.orderBy, this.inOrder);
	},
	loadList: function(uiId, languageId, orderBy, inOrder) {
		var req = new Ajax.Updater(
			'ViiKii.Menu.Popup.listLayer',
			'/menus/popup_listing/'+uiId+'/'+languageId+'/'+orderBy+'/'+inOrder,
			{
				asynchronous: true,
				method: 'get',
				evalScripts: true
			}
		);
	},
	select: function(uiId, languageId, menuId, type) {
		var ajax = new Ajax.RequestXML(
			'/menus/select_menu/'+uiId+'/'+languageId+'/'+menuId+'/'+type,
			{
				asynchronous: false,
				method: 'get'
			}
		);
		this.onSelectMenu(ajax);
	},
	onSelectMenu: function(ajax) {
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.refresh();
			return;
		}

		switch(response.error) {
		case 'INVALID_MENU':
		case 'NOT_ADMIN':
			this.refresh();
			break;
		case 'DB_ERROR':
			alert("Fail to select translation.");
			break;
		}
	},
	close: function() {
		Element.hide("ViiKii.Menu.Popup.layer");
		ViiKii.Menu.update();
	}
};
ViiKii.Pay = {
	isDonated: false,
	donate: function() {
		this.confirm();
	},
	confirm: function() {
		var selectBox;
		var cardNumber = $('cardnumber').value;
		selectBox = $('expdate_month');
		var expireMonth = selectBox.options[selectBox.selectedIndex].value;
		selectBox = $('expdate_year');
		var expireYear = selectBox.options[selectBox.selectedIndex].value;
		var securityCode = $('cvv2').value;
		var country = $('country_dropdown').value;
		var addr_1 = $('addr_1').value;
		var addr_2 = $('addr_2').value;
		var city = $('city').value;
		var state = $('state').value;
		var firstName = $('firstname').value;
		var lastName = $('lastname').value;
		var paymentId = $('payment_id').value;
		
		if(ViiKii.Pay.States[country]) {
			selectBox = $('state_dropdown');
			state = selectBox.options[selectBox.selectedIndex].value;
		}
		var zip = $('zip').value;
		
		if(cardNumber == '') {
			alert('Insert available card number first!');
			return;
		}
		if(expireMonth == '0') {
			alert('Select available card expiration month first!');
			return;
		}
		if(expireYear == '0') {
			alert('Select available card expiration year first!');
			return;
		}
		if(securityCode.length < 3) {
			alert('Insert available security code first!');
			return;
		}
		if(firstName == '') {
			alert('Insert available first name first!');
			return;
		}
		if(lastName == '') {
			alert('Insert available last name first!');
			return;
		}
		if(addr_1 == '') {
			alert('Insert available address first!');
			return;
		}
		if(city == '') {
			alert('Insert available city first!');
			return;
		}
		if(state == '') {
			alert('Insert available state first!');
			return;
		}
		if(zip == '') {
			alert('Insert available zip code first!');
			return;
		}
		/*
		var message = 'cardNumber '+cardNumber;
		message += '\n expireMonth '+expireMonth;
		message += '\n expireYear '+expireYear;
		message += '\n securityCode '+securityCode;
		message += '\n firstName '+firstName;
		message += '\n lastName '+lastName;
		message += '\n country '+country;
		message += '\n addr_1 '+addr_1;
		message += '\n addr_2 '+addr_2;
		message += '\n city '+city;
		message += '\n state '+state;
		message += '\n zip '+zip;
		message += '\n payment_id '+paymentId;
		alert(message);
		*/
		var params = $H({
			'card_number'	: cardNumber,
			'expire_month'	: expireMonth,
			'expire_year'	: expireYear,
			'security_code'	: securityCode,
			'country'		: country,
			'first_name'	: firstName,
			'last_name'		: lastName,
			'addr_1'		: addr_1,
			'addr_2'		: addr_2,
			'city'			: city,
			'state'			: state,
			'zip'			: zip
		}).toQueryString();
		if(this.isDonated) {
			return;
		}
		this.isDonated = true;
		this.request(paymentId, params);
	},
	request: function(paymentId, params) {
		new Ajax.Request(
			'/payments/card/'+paymentId,
			{
				parameters: params,
				onComplete: this.onDonate.bind(this)
			}
		);
	},
	onDonate: function(transport, response) {
		//alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			//alert('Thank you for your donation!');
			document.location = '/payments/success/'+response.payment_id;
			return;
		}
		this.isDonated = false;
		switch(response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'INVALID_PAYMENT':
			alert('This donation is invalid');
			document.location = '/payments/donate';
			break;
		case 'INVALID_CARD_NUMBER':
			alert('Insert available card number first!');
			break;
		case 'INVALID_CARD_TYPE':
			alert('Sorry but Visa, MasterCard, American Express, and Discover only.');
			break;
		case 'EMPTY_EXPIRE_MONTH':
			alert('Select available card expiration month first!');
			break;
		case 'EMPTY_EXPIRE_YEAR':
			alert('Select available card expiration year first!');
			break;
		case 'EMPTY_SECURITY_CODE':
			alert('Insert available security code first!');
			break;
		case 'EMPTY_COUNTRY':
			alert('Select available country first!');
			break;
		case 'EMPTY_FIRST_NAME':
			alert('Insert available first name first!');
			break;
		case 'EMPTY_LAST_NAME':
			alert('Insert available last name first!');
			break;
		case 'EMPTY_ADDRESS_1':
			alert('Insert available address first!');
			break;
		case 'EMPTY_CITY':
			alert('Insert available city first!');
			break;
		case 'EMPTY_STATE':
			alert('Insert available state first!');
			break;
		case 'EMPTY_ZIP':
			alert('Insert available zip code first!');
			break;
		case 'CURL_ERROR':
			alert(response.message);
			break;
		case 'PAYPAL_ERROR':
			alert(response.message);
			break;
		case 'INVALID_USER':
			alert('You are not a registerd user');
			break;
		}
	},
	refresh: function() {
		document.location = '/payments/donate';
	}
};
ViiKii.Pay.States = {"US":{"":"- State -","AL":"Alabama [AL]","AK":"Alaska [AK]","AZ":"Arizona [AZ]","AR":"Arkansas [AR]","CA":"California [CA]","CO":"Colorado [CO]","CT":"Connecticut [CT]","DE":"Delaware [DE]","DC":"District Of Columbia [DC]","FL":"Florida [FL]","GA":"Georgia [GA]","HI":"Hawaii [HI]","ID":"Idaho [ID]","IL":"Illinois [IL]","IN":"Indiana [IN]","IA":"Iowa [IA]","KS":"Kansas [KS]","KY":"Kentucky [KY]","LA":"Louisiana [LA]","ME":"Maine [ME]","MD":"Maryland [MD]","MA":"Massachusetts [MA]","MI":"Michigan [MI]","MN":"Minnesota [MN]","MS":"Mississippi [MS]","MO":"Missouri [MO]","MT":"Montana [MT]","NE":"Nebraska [NE]","NV":"Nevada [NV]","NH":"New Hampshire [NH]","NJ":"New Jersey [NJ]","NM":"New Mexico [NM]","NY":"New York [NY]","NC":"North Carolina [NC]","ND":"North Dakota [ND]","OH":"Ohio [OH]","OK":"Oklahoma [OK]","OR":"Oregon [OR]","PA":"Pennsylvania [PA]","PR":"Puerto Rico [PR]","RI":"Rhode Island [RI]","SC":"South Carolina [SC]","SD":"South Dakota [SD]","TN":"Tennessee [TN]","TX":"Texas [TX]","UT":"Utah [UT]","VT":"Vermont [VT]","VI":"Virgin Islands [VI]","VA":"Virginia [VA]","WA":"Washington [WA]","WV":"West Virginia [WV]","WI":"Wisconsin [WI]","WY":"Wyoming [WY]","AS":"American Samoa [AS]","FM":"Federated States Of Micronesia [FM]","GU":"Guam [GU]","MH":"Marshall Islands [MH]","AA":"Military Americas, Florida [AA]","AP":"Military California, Pacific [AP]","AE":"Military International, New York [AE]","MP":"Northern Mariana Islands [MP]","PW":"Palau [PW]"},"CA":{"":"- State -","AB":"Alberta","BC":"British Columbia","MB":"Manitoba","NB":"New Brunswick","NL":"Newfoundland & Labrador","NT":"Northwest Territories","NS":"Nova Scotia","NU":"Nunavut","ON":"Ontario","PE":"Prince Edward Island","QC":"Quebec","SK":"Saskatchewan","YT":"Yukon"}};
ViiKii.Pay.Donate = {
	lastSelectedPeriod: '',
	isAnonymous: false,
	anonymous: function() {
		this.setAnonymous(!this.isAnonymous)
	},
	periods: {'period_30':30, 'period_45':45, 'period_90':90, 'period_365':365, 'period_0':0},
	selectPeriod: function(selected) {
		this.unselectLast();
		$(selected).src = "/common/bullet_on.gif";
		this.lastSelectedPeriod = selected.id;
		$('amount_input').disabled = selected.id != 'period_0';
		if(selected.id == 'period_0') {
			$('amount_input').focus();
		}
	},
	setAnonymous: function(isAnonymous) {
		this.isAnonymous = isAnonymous;
		if($('send_anonymously')) {
			$('send_anonymously').src = this.isAnonymous?'/common/checkbox_ch.gif':'/common/checkbox_wh.gif';
		}
	},
	unselectLast: function() {
		if($(this.lastSelectedPeriod)) {
			$(this.lastSelectedPeriod).src = "/common/bullet_off.gif";
		}
	},
	donate: function(isCard) {
		var form = $('donate_form');
		var days = this.periods[this.lastSelectedPeriod];
		var amount = $('amount_input').value;
		if(days == 0) {
			amount = amount.replace(new RegExp(/[^0-9\.]+/g), '');
			amount = isNaN(amount) ? 0 : amount;
			amount = Math.floor(amount*100)/100;
			if(amount < 34.99) {
				alert('The amount should be more than $34.99');
				return;
			}
		}
		form.action = '/payments/donate';
		form.period.value = days;
		form.amount.value = amount;
		form.is_anonymous.value = this.isAnonymous?'T':'F';
		if($('gift_message')) {
			form.message.value = $('gift_message').value;
		}
		if($('gift_to')) {
			form.send_to.value = $('gift_to').value;
		}
		form.is_card.value = isCard;
		form.submit();
	},
	confirmPaypal: function() {
		var params = $H({
			'token'	: $('token').value
		}).toQueryString();
		var res = new Ajax.Request(
			'/payments/confirm_paypal',
			{
				parameters: params,
				onComplete: this.onConfirmPaypal.bind(this)
			}
		);
	},
	onConfirmPaypal: function(transport, response) {
		//alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			//alert('Donated Successfully');
			document.location = '/payments/success/'+response.payment_id;
			return;
		}
		switch(response.error) {
		case 'INVALID_TOKEN':
			alert('Unable to process');
			break;
		case 'CURL_ERROR':
			alert('Unable to process');
			break;
		case 'PAYPAL_ERROR':
			alert('Unable to process');
			break;
		}
	}
};
ViiKii.Pay.Manage = {
	objectId: 'ViiKii.Pay.Manage',
	refresh: function() {
		new Ajax.Updater(
			'payment_list',
			'/payments/manage/'+ViiKii.Util.get(this, 'curPage'),
			{
				evalScripts: true
			}
		)
	},
	loadPage: function(curPage) {
		ViiKii.Util.set(this, 'curPage', curPage);
		this.refresh();
	},
	refund: function(transactionId) {
		if (!confirm('Are you sure to refund this payment?')) {
			return;
		}
		new Ajax.Request(
			'/payments/refund/'+transactionId,
			{
				onComplete: this.onRefund.bind(this)
			}
		);
	},
	onRefund: function(transport, response) {
		//alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			alert('Refunded Successfully!');
			this.refresh();
			return;
		}
		switch(response.error) {
		case 'INVALID_PAYMENT':
			this.refresh();
			break;
		case 'NOT_CONFIRMED':
			alert('The payment is not completed');
			this.refresh();
			break;
		case 'NOT_ADMIN':
			alert('You are not the admin');
			document.location = '/';
			break;
		case 'CURL_ERROR':
			alert(response.message);
			break;
		case 'PAYPAL_ERROR':
			alert(response.message);
			break;
		}
	}
};
ViiKii.Pay.Manage.Investigate = {
	loadPage: function(curPage) {
		new Ajax.Updater(
			'transaction_list',
			'/payments/investigate/'+curPage,
			{ evalScripts: true }
		)
	}
};
ViiKii.Lolly = {
	buy: function() {
		$('lolly_form').send_to.value = $('gift_to')?$('gift_to').value:'';
		$('lolly_form').message.value = $('gift_message')?$('gift_message').value:'';
		var message = "";
		message += "is_gift "+$('lolly_form').is_gift.value +"\n";
		message += "pay_type "+$('lolly_form').pay_type.value +"\n";
		message += "type_id "+$('lolly_form').type_id.value +"\n";
		message += "is_anonymous "+$('lolly_form').is_anonymous.value +"\n";
		message += "send_to "+$('lolly_form').send_to.value +"\n";
		message += "message "+$('lolly_form').message.value +"\n";
//		alert(message);
		
		$('lolly_form').action = '/payments/lolly';
		$('lolly_form').submit();
	},
	setAnonymous: function(anonymous) {
		if(!$('send_anonymously')) {
			return;
		}
		$('lolly_form').is_anonymous.value = anonymous;
		if(anonymous == 'T') {
			$('send_anonymously').src = "http://vkcommon.viikii.net/checkbox_ch.gif";
		} else {
			$('send_anonymously').src = "http://vkcommon.viikii.net/checkbox_wh.gif";
		}
	},
	toggleAnonymous: function() {
		if($('lolly_form').is_anonymous.value == 'T') {
			this.setAnonymous('F');
		} else {
			this.setAnonymous('T');
		}
	},
	unselectLast: function() {
		var lollyAmounts = $$('.lolly_amounts');
		for(var i=0; i<lollyAmounts.length; i++) {
			lollyAmounts[i].src = "/common/bullet_off.gif";
		}
	},
	selectType: function(selected) {
		this.unselectLast();
		$(selected).src = "/common/bullet_on.gif";
		$('lolly_form').type_id.value = selected.id;
	},
	paymentMethod: function(method) {
		Element.hide('select_lolly');
		$('lolly_form').pay_type.value = method;
		new Ajax.Updater(
			'select_lolly',
			'/payments/select_lolly/'+method,
			{
				evalScripts: true,
				onComplete: function(transport) {
					Element.show('select_lolly');
					var position = Position.positionedOffset($('choose_payment'));
					window.scrollTo(0, position[1]);
				}
			}
		)
	}
};
ViiKii.Lolly.Card = Object.clone(ViiKii.Pay);
ViiKii.Lolly.Card.request = function(paymentId, params) {
	new Ajax.Request(
		'/payments/lolly_confirm_card/'+paymentId,
		{
			parameters: params,
			onComplete: this.onDonate.bind(this)
		}
	);
};
ViiKii.Lolly.Card.onDonate = function(transport, response) {
//	alert(transport.responseText);
	if(response.result == 'SUCCESS') {
		//alert('Thank you for your donation!');
		document.location = '/payments/lolly_success/'+response.payment_id;
		return;
	}
	this.isDonated = false;
	switch(response.error) {
	case 'NOT_LOG_IN':
		ViiKii.Login.popUp();
		break;
	case 'INVALID_PAYMENT':
		alert('This purchase is invalid');
		document.location = '/payments/lolly';
		break;
	case 'INVALID_CARD_NUMBER':
		alert('Insert available card number first!');
		break;
	case 'INVALID_CARD_TYPE':
		alert('Sorry but Visa, MasterCard, American Express, and Discover only.');
		break;
	case 'EMPTY_EXPIRE_MONTH':
		alert('Select available card expiration month first!');
		break;
	case 'EMPTY_EXPIRE_YEAR':
		alert('Select available card expiration year first!');
		break;
	case 'EMPTY_SECURITY_CODE':
		alert('Insert available security code first!');
		break;
	case 'EMPTY_COUNTRY':
		alert('Select available country first!');
		break;
	case 'EMPTY_FIRST_NAME':
		alert('Insert available first name first!');
		break;
	case 'EMPTY_LAST_NAME':
		alert('Insert available last name first!');
		break;
	case 'EMPTY_ADDRESS_1':
		alert('Insert available address first!');
		break;
	case 'EMPTY_CITY':
		alert('Insert available city first!');
		break;
	case 'EMPTY_STATE':
		alert('Insert available state first!');
		break;
	case 'EMPTY_ZIP':
		alert('Insert available zip code first!');
		break;
	case 'CURL_ERROR':
		alert(response.message);
		break;
	case 'PAYPAL_ERROR':
		alert(response.message);
		break;
	case 'INVALID_USER':
		alert('You are not a registerd user');
		break;
	}
};
ViiKii.Lolly.Paypal = {
	confirm: function() {
		var params = $H({
			'token'	: $('token').value
		}).toQueryString();
		var res = new Ajax.Request(
			'/payments/lolly_confirm_paypal',
			{
				parameters: params,
				onComplete: this.onConfirm.bind(this)
			}
		);
	},
	onConfirm: function(transport, response) {
//		alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			document.location = '/payments/lolly_success/'+response.payment_id;
			return;
		}
		switch(response.error) {
		case 'INVALID_TOKEN':
			alert('Unable to process. Invalid Transaction');
			break;
		case 'CURL_ERROR':
			alert("Unable to process. Paypal doesn't response");
			break;
		case 'PAYPAL_ERROR':
			alert('Unable to process');
			break;
		}
	}
};
ViiKii.Purchase = {
	
};
ViiKii.Purchase.SpeedTest = {
	open: function(videoId, selectMode) {
		ViiKii.UI.Popup.create('lolly_popup');
		new Ajax.Updater(
			'lolly_popup',
			'/lollies/speed_test/'+videoId+'/'+selectMode,
			{ evalScripts: true }
		);
	},
	close: function() {
		Element.hide('lolly_popup');
	},
	backToBuyVideo: function() {
		ViiKii.Purchase.BuyVideo.open($('lolly_video_id').value, 'none', $('select_mode').value);
	}
};
ViiKii.Purchase.BuyVideo = {
	open: function(videoId, videoMode, selectMode) {
		videoMode = videoMode?videoMode:'none';
		selectMode = selectMode?selectMode:'';
		
		ViiKii.UI.Popup.create('lolly_popup');
		new Ajax.Updater(
			'lolly_popup',
			'/lollies/buy_video/'+videoId+'/'+videoMode+'/'+selectMode,
			{ evalScripts: true }
		);
	},
	check: function() {
		ViiKii.Video.Plugin.check("OFxXSXGd4hs", this.onCheck.bind(this));
	},
	onCheck: function(youtubeId, streamUrl) {
//		TODO: remove here
//		this.buy();
//		return;
		
		if(streamUrl) {
			this.buy();
		} else {
			alert('Please install and run ViiKii Desktop Plug-in');
		}
	},
	buy: function() {
//		alert('buy '+$('lolly_video_id').value+' '+$('video_mode').value);
		new Ajax.Request(
			'/lollies/on_buy_video/'+$('lolly_video_id').value+'/'+$('video_mode').value,
			{
				evalScripts: true,
				onComplete: this.onBuy.bind(this)
			}
		);
	},
	onBuy: function(transport, response) {
		if(response.result == 'SUCCESS') {
			alert('Successfully puchased.');
			if(response.video_mode == 'dw') {
				this.open(response.video_id, '', 'dw');
			} else {
				document.location = response.url;
			}
			return;
		}
		switch(response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			return;
		case 'INVALID_VIDEO_MODE':
			alert('This video don\'t support the type. Please select other purchase type');
			return;
		case 'INVALID_VIDEO':
			alert('Invalid video');
			return;
		case 'INVALID_USER':
			alert('Invalid user');
			return;
		case 'NOT_ENOUGH_BALANCE':
			alert('You don\'t have enough Łolly. Please buy Łolly');
			return;
		case 'ALREADY_PUCHASED':
			alert('You have already puchased this video.');
			document.location = response.url;
			return;
		case 'DB_ERROR':
			alert('Fail to buy video. Please try again.');
			return;
		}
	},
	gift: function() {
		alert('gift '+$('lolly_video_id').value+' '+$('video_mode').value);
	},
	openMode: function(videoMode) {
		this.open($('lolly_video_id').value, videoMode);
	},
	openSpeedTest: function() {
		ViiKii.Purchase.SpeedTest.open($('lolly_video_id').value, $('video_mode').value);
	},
	close: function() {
		Element.hide('lolly_popup');
	}
};
ViiKii.PendingQuestion = {
	popUpLayerName: 'pend_listing',

	update: function() {
		this.pageNum = 1;
		if(typeof this.inlanguage == 'undefined') {
			this.inlanguage = 'all';
		}
		if(typeof this.rate == 'undefined') {
			this.rate = 0;
		}
		if(typeof this.time == 'undefined') {
			this.time = 1;
		}
		if(typeof this.languageId == 'undefined') {
			this.languageId = '';
		}
		this.updateSnapShot();
	},

	updateSnapShot: function() {
		var url = "/pendingqts/snapshot/";
		var response = new Ajax.Updater('pending_snapshot', url, {
				asynchronous: true,
				evalScripts: true,
				parameters: null,
				onSuccess: this.onCompleteLoadList,
				onFailure: this.onErrorLoadList
			});
	},

	loadPage: function(pageNum) {
		this.pageNum = pageNum;
		if(typeof this.inlanguage == 'undefined') {
			this.inlanguage = 'all';
		}
		if(typeof this.rate == 'undefined') {
			this.rate = 0;
		}
		if(typeof this.time == 'undefined') {
			this.time = 1;
		}
		if(typeof this.languageId == 'undefined') {
			this.languageId = '';
		}
		this.updateList();
	},

	loadLanguage: function(langid) {
		this.languageId = langid;
		this.inlanguage = 'about';
		this.pageNum = 1;
		if(typeof this.rate == 'undefined') {
			this.rate = 0;
		}
		if(typeof this.time == 'undefined') {
			this.time = 1;
		}
		this.updateList();
	},

	selectLanguage: function(language) {
		this.inlanguage = language;
		this.pageNum = 1;
		if(typeof this.rate == 'undefined') {
			this.rate = 0;
		}
		if(typeof this.time == 'undefined') {
			this.time = 1;
		}
		if(typeof this.languageId == 'undefined') {
			this.languageId = '';
		}
		this.updateList();
	},

	sortByRate: function() {
		this.time = 0;
		if(typeof this.rate == 'undefined' || this.rate == 0) {
			this.rate = -1;
		}
		this.rate *= -1;
		this.pageNum = 1;
		if(typeof this.inlanguage == 'undefined') {
			this.inlanguage = 'all';
		}
		if(typeof this.languageId == 'undefined') {
			this.languageId = '';
		}
		this.updateList();
	},

	sortByTime: function() {
		this.rate = 0;
		if(typeof this.time == 'undefined' || this.time == 0) {
			this.time = -1;
		}
		this.time *= -1;

		this.pageNum = 1;
		if(typeof this.inlanguage == 'undefined') {
			this.inlanguage = 'all';
		}
		if(typeof this.languageId == 'undefined') {
			this.languageId = '';
		}
		this.updateList();
	},

	updateList: function() {
		var url = "/pendingqts/pendingqt/";
		var requestUrl = url + this.pageNum + '/' + this.inlanguage + '/' + this.rate + '/' + this.time + '/' + this.languageId;
//		alert(requestUrl);
		var response = new Ajax.Updater('pend_main', requestUrl, {
				asynchronous: true,
				evalScripts: true,
				parameters: null,
				onSuccess: this.onCompleteLoadList,
				onFailure: this.onErrorLoadList
			});
	},

	onCompleteLoadList: function(transport) {
//		$(ViiKii.PendingQuestion.popUpLayerName).innerHTML = transport.responseText;
	},

	onErrorLoadList: function() {
		alert('failed');
	}
};
ViiKii.round = {
    _setOptions: function(options) {
        this.options = {
            corners : 'all',
            radius : 5,
            color : 'fromElement',
            bgColor : 'fromParent',
            borderSize : 0,
            borderColor : '#000'
            //transition : Effect.Transitions.circIn
        };
        Object.extend(this.options, options || {});
        if (this.options.radius < 2) this.options.radius = 2;
        if (this.options.borderSize > 1) this.options.borderSize = 1;
    },

    init: function(elements, options) {
	    this._setOptions(options);
        if ($(elements) == null) {
            this.element = elements.split(',');
            this.element.type = 'class';
            for (var i = 0, len = this.element.length; i < len; i++)
                this.round(this.element[i]);
        }
        else {
            this.element = $(elements);
            this.element.type = 'id';
            this.round(this.element);
        }
    },

    round: function(element){
		if (this.element.type == 'class') {
            var el = $$(element);
            for (var i = 0, len = el.length; i < len; i++) {
                this._renderBorder(el[i]);
                if (this._isTopRounded()) this._render(el[i], 'top');
                if (this._isBottomRounded()) this._render(el[i], 'bottom');
            }
        }
        else {
            this._renderBorder(element);
            if (this._isTopRounded()) this._render(element, 'top');
            if (this._isBottomRounded()) this._render(element, 'bottom');
        }
    },

    _renderBorder: function(element) {
		Element.setStyle(element, Element.getStyle(element, 'position') != 'static' || {position:'relative'});

        var defValue = element.innerHTML;
        element.innerHTML = '';
        var e = document.createElement('div');
        var styles = {
            display: 'block',
			height:'100%',
			clear: 'both',
            borderLeft: (this.options.borderSize > 0 ? parseInt(this.options.borderSize) + "px solid " + this.options.borderColor : ''),
            borderRight: (this.options.borderSize > 0 ? parseInt(this.options.borderSize) + "px solid " + this.options.borderColor : '')
        };
        tmpH = parseInt(element.getStyle('height')) - (this._isTopRounded() ? this.options.radius : 0) - (this._isBottomRounded() ? this.options.radius : 0);
        e.innerHTML = defValue;
        Element.setStyle(e, styles);
        element.appendChild(e);
    },

    _render: function(element, position) {
        if (!position) return;
        var e = document.createElement('div');
        var styles = {
            position: 'absolute',
            display: 'block',
			left: '0px',
			width: '100%',
            borderColor: '',
            backgroundColor: ''
        };

        var color = this._background(e);
        var borderColor = this._background(element.parentNode);
        var margin = this._getMargin(this.options.radius, (this.options.borderSize < 1 ? 1 : this.options.borderSize));
        var border = this.options.borderSize;
        var corners = {
            element: element,
            position: position,
            borderColor: this._background(element.parentNode)
        };

        var pos = this.options.radius;
        var borderSpace = 0;
        var borderSize = this.options.borderSize - 1;
        for (var i = 0; i < margin.length; i++) {
            if (i >= this.options.borderSize - 1 && this.options.borderSize > 0) {
                borderSpace = pos - (this.options.radius-margin[i][0]);
                pos = this.options.radius - margin[i][0];
                borderSpace = borderSpace == 0 ? 1 + borderSize : borderSpace + borderSize;
            }
            el = this._createCorner(corners, margin[i], borderSpace, i);
            (position != 'bottom' ? e.appendChild(el) : e.insertBefore(el, e.firstChild));
        }
        if (position != 'bottom') {
 			Element.setStyle(e, Object.extend(styles, {top:'0px'}));
            element.insertBefore(e, element.firstChild);
        }
        else {
 			Element.setStyle(e, Object.extend(styles, {bottom:'0px', clear:'both'}));
            element.appendChild(e);
        }
    },

    _createCorner: function(corners, margin, borderSpace, n) {
        var e = document.createElement('div');
        var borderWidth = parseInt(this.options.radius - margin[0]);
        var styles = {
			borderStyle: 'solid',
            borderWidth: '0px',
            display: 'block',
            overflow: 'hidden',
            margin: '0px ' + parseInt(Element.getStyle(corners.element, 'Right')) + 'px 0px ' + parseInt(Element.getStyle(corners.element, 'Left')) + 'px',
            height: '1px',
            borderColor: corners.borderColor,
            backgroundColor: 'transparent'
        };
        var positions = this._whichSide(corners.position);
        switch (positions) {
            case 'left'  : Object.extend(styles, {borderLeftWidth: borderWidth + 'px', borderRightWidth: '0px'}); break;
            case 'right' : Object.extend(styles, {borderLeftWidth: '0px', borderRightWidth: borderWidth + 'px'}); break;
            default      : Object.extend(styles, {borderLeftWidth: borderWidth + 'px', borderRightWidth: borderWidth + 'px'}); break;
        };
        Element.setStyle(e, styles);

        if (this.options.borderSize > 0) {
            var bgColor = (n < this.options.borderSize) ? this.options.borderColor : 'transparent';
            var el = '<b style="border-style:solid; border-color:' + this.options.borderColor + '; border-width:0px ' + borderSpace + 'px; margin: 0px; overflow: hidden; display: block; height: 1px; background-color:' + bgColor + ';"></b>';
            e.innerHTML = el;
        }
        return e;
    },

    _borderColor : function(color, bgColor) {
        return (!color ? this.options.color : color);
    },

    _background: function(element) {
        try {
            var actualColor = Element.getStyle(element, "backgroundColor");
            if ( actualColor.match(/^(transparent|rgba\(0,\s*0,\s*0,\s*0\))$/i) && element.parentNode )
                return this._background(element.parentNode);
            if ( actualColor == null ) return '#FFFFFF';
            else return actualColor;
        } catch(err){ return '#FFFFFF'; }
    },

    _whichSide: function(side) {
        if (side == 'top') {
            if (this._hasString(this.options.corners, 'all', 'top')) return '';
            if (this.options.corners.indexOf('tl') >= 0 && this.options.corners.indexOf('tr') >= 0) return '';
            if (this.options.corners.indexOf('tl') >= 0) return 'left';
            else if(this.options.corners.indexOf('tr') >= 0) return 'right';
            return '';
        }
        else if (side == 'bottom') {
            if (this._hasString(this.options.corners, 'all', 'bottom')) return '';
            if (this.options.corners.indexOf('bl') >= 0 && this.options.corners.indexOf('br') >= 0) return '';
            if (this.options.corners.indexOf('bl') >= 0) return 'left';
            else if(this.options.corners.indexOf('br') >= 0) return 'right';
            return '';
        }
        else {
            return '';
        }
    },

    _getMargin: function(ratio, border, rtn) {
        var x,y,th;
        if(ratio == 0) return [0, 0];
        if(!rtn) {
            var rtn = [];
            for(var i=0, k=(ratio+border-2); i<=k; i++) { rtn[i] = [1000, 0]; }
        }
        y = ratio - 1;
        th = -3 - (ratio*2);
        for(x = 0; x < y; x++) {
            if(th < 0) { th += 6 + (x << 2); }
            else { th += 10+((x-y) << 2); y--; }
            rtn = this._border(rtn, x, ratio+border-y-2);
            rtn = this._border(rtn, y, ratio+border-x-2);
        }
        border--;
        if(border > 0) this._getMargin(ratio+1,border,rtn);
        return rtn;
    },

    _border: function(rtn, x, y) {
        if(!rtn[y]) rtn[y] = [0, 0];
        if(rtn[y][0] > x) rtn[y][0] = x;
        if(rtn[y][1] < x) rtn[y][1] = x;
        return rtn;
    },

    _hasString: function(str) {
        for(var i=1 ; i<arguments.length ; i++)
            if (str.indexOf(arguments[i]) >= 0)
                return true;
        return false;
    },

    _isTopRounded: function() {
        return this._hasString(this.options.corners, 'all', 'top', 'tl', 'tr');
    },

    _isBottomRounded: function() {
        return this._hasString(this.options.corners, 'all', 'bottom', 'bl', 'br');
    }
};
ViiKii.Subhead = {
	add: function(videoId, language, subhead) {
		var res = new Ajax.Request(
				'/subheads/add',
				{
					asynchronous: false,
					evalScripts: false,
					parameters: $H({
							'videoId': videoId,
							'languageId': language,
							'subhead': subhead}).toQueryString()
				}
			);
		return res.evalJSON();
	},
	remove: function(id) {
		var res = new Ajax.Request('/subheads/remove/' + id, {
				asynchronous: false,
				parameters: null,
				evalScripts: false
			});
		return res.evalJSON();
	},
	rating: function(id, point) {
		var res = new Ajax.Request('/subheads/rating/' + id + '/' + point, {
				asynchronous: false,
				parameters: null,
				evalScripts: false
			});
		return res.evalJSON();
	}
};var InterestedLanguage = {
	version: '0.1',
	name: 'InterestedLanguage',
	languages: null,
	set: function(languages) {
		arr = [1,2,3,4,5,6];
		this.languages = languages;
	},
	get: function() {
		return this.languages;
	}
};

var SubtitleDiscussion = {
	version: '0.1',
	name: 'SubtitleDiscussion',

	videoId: '',
	scrollBar: null,

	prefixWrapLayerId: 'sd_discussion_wrap_',				//defined views/subtitles/listing.thtml
	prefixInputFormLayerId: 'sd_input_', 					//defined views/comments/list_in_subtitle.thtml
	prefixLanguageRadioImageId: 'sd_language_',				//defined this script(dynamically generated)
	prefixReplyLanguageRadioImageId: 'sd_reply_language_',	// define this script(dynamically generated)

	addUrl: '/subtitles/add_comment',
	listUrl: '/subtitles/popup_comment',

	selectedRadioImgSrc: '/common/bullet_on.gif',
	radioImgSrc: '/common/bullet_off.gif',

	layerName: function(subtitleId) {
		return this.prefixWrapLayerId + subtitleId;
	},

	show: function(videoId, subtitleId, page, islogin) {
//alert('videoId='+videoId+', subtitleId='+subtitleId+', this.listUrl='+this.listUrl+', islogin'+islogin);
		this.videoId = videoId;
		this.islogin = islogin;
		if(typeof this.subtitleId != 'undefined' && this.subtitleId != subtitleId) {
			if($('sd_discussion_wrap_'+this.subtitleId) != null) {
				Element.setStyle($('sd_discussion_wrap_'+this.subtitleId), {display:'none'});
			}
		}
		this.deleteCancel();
		this.subtitleId = subtitleId;
		var url = this.listUrl + '/' + subtitleId + '/' + page;
		var layer = $(this.layerName(subtitleId));
		var show = Element.getStyle(layer, 'display');
		Element.setStyle(layer, {display:(show=='none'?'block':'none')});

		var response = new Ajax.Updater(
			this.layerName(subtitleId),
			url,
			{
				asynchronous:true,
				evalScripts:true,
				parameters:null,
				onFailure: this.onError,
				onComplete: function(transport) {
					if(SubtitleDiscussion.scrollBar != null) {
						SubtitleDiscussion.scrollBar.update();
					}
				}
			}
		);
	},

	addComment: function(type, rid) {
		if(false == this.logIn()) {	return; }
		if (!this.isvideo()) { return; }

		var frm = $('detpop_Input'+rid);

		var notWhiteSpace = new RegExp(/[^\s]/);
		var quotation = new RegExp(/\'/g);
		var backSlash = new RegExp(/\\/g);
		var urlLink	= new RegExp(/(http|https|ftp|telnet|news):\/\/([a-z0-9_\-]+\.[][a-zA-Z0-9:;&#@=_~%\?\/\.\,\+\-]+)/g);

		if (type != 'T') {
			if (!notWhiteSpace.test(frm['data[content]'].value)) {
				alert('Type the comment please!!');
				return;
			}
			if (backSlash.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value.replace(backSlash, "\\\\");
			}
			if (quotation.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value.replace(quotation, "\\\'");
			}
			if (urlLink.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value.replace(urlLink, "<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>");
			}
		}
		else {
			if (!notWhiteSpace.test(frm['data[translate]'].value)) {
				alert('Type the comment please!!');
				return;
			}
			if (backSlash.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value.replace(backSlash, "\\\\");
			}
			if (quotation.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value.replace(quotation, "\\\'");
			}
			if (urlLink.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value.replace(urlLink, "<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>");
			}
		}
		var ele = frm['data[language_id]'];
		if (ele.length) {
			for (i = 0; i < ele.length; i++) {
				if (ele[i].checked) {
					language_id = ele[i].value;
				}
			}
		}
		else {
			language_id = ele.value;
		}

		var params = 'data[category]=S'
				 + '&data[video_id]=' + this.videoId
				 + '&data[content_type]='+ type
				 + '&data[language_id]='+ language_id
				 + '&data[tag_id]=0'
				 + '&data[content]=' + encodeURIComponent(frm['data[content]'].value);

		var rtn = new Ajax.Request(this.addUrl + '/' + rid,	{
				asynchronous: false,
				method: 'post',
				parameters: params,
				onSuccess: this.onCallback,
				onFailure: this.onError
			}
		);
	},

	showReply: function(type, id, language, depth, subtitleid) {
		if(false == this.logIn()) {	return;	}
		if (!this.isvideo()) { return; }
		var languages = ViiKii.Languages.getActiveInterestedLanguageCodes();
		var idx = '';

		var str = '';
		var radio_language =  '';
		var checked = 'checked';
		value = '';
		var commenttype = '';
		var i;

		if(type == 'T') {
			var cnt = 0;
			for(i=0; i<languages.length; i++) {
				idx = languages[i];
				if (idx != language) {
					radio_language = '<input type="hidden" name="data[language_id]" id="rlbl" value="'+ idx +'" />\n';
					cnt++;
				}
			}
			if(cnt > 1) {
				radio_language = '	<div id="setLang'+ id +'" class="s_post" style="float:left; width:390px; height:18px; margin:2px 0 0 2px; background-color:#FFF;">\n<div style="float:left; margin-top:0px;">\n';
				for(i=0; i<languages.length; i++) {
					idx = languages[i];
					if (idx != language) {
						radio_language += '<input type="radio" name="data[language_id]" value="'+ idx +'" id="rlbl' + id + idx + '" onfocus="this.blur();" '+ checked +'/><label for="rlbl' + id + idx + '">'+ idx +'</label>\n';
						checked = '';
					}
				}
				radio_language += ' </div>\n'
							   +  '<div style="float:left; padding-top:2px;">\n'
							   +  '<span onclick="Element.setStyle($(\'setLang'+id+'\'), {display:\'none\'});" style="cursor:pointer; margin-left:20px; border:0px solid red;">[OK]</span>\n</div>\n</div>\n';
			}
		}
		else {
			radio_language = '	<div id="setLang'+ id +'" class="s_post" style="float:left; width:374px; height:18px; margin:2px 0 0 1px; background-color:#FFF;">\n<div style="float:left; margin-top:0px;">\n';
			for(i=0; i<languages.length; i++) {
				idx = languages[i];
				radio_language += '<input type="radio" name="data[language_id]" value="'+ idx +'" id="rlbl' + id + idx + '" onfocus="this.blur();" '+ checked +'/><label for="rlbl' + id + idx + '">'+ idx +'</label>\n';
				checked = '';
			}
			radio_language += ' </div>\n'
						   +  '<div style="float:left; padding-top:2px;">\n'
						   +  '<span onclick="Element.setStyle($(\'setLang'+id+'\'), {display:\'none\'});" style="cursor:pointer; margin-left:20px; border:0px solid red;">[OK]</span>\n</div>\n</div>\n';
		}

		str +=	'<form id="frmComment'+ id +'" onSubmit="return false;" style="margin:0px;">\n'
			+	'	<input type="hidden" name="data[page]" value="1" />\n'
			+	'	<input type="hidden" name="data[content_type]" id="content_type" value="'+ type.toUpperCase() +'" />\n'
			+	' 	<input type="hidden" name="data[category]" id="category" value="S" />\n';

		switch (type.toUpperCase()) {
		case 'Q' :
			value = 'Comment';	commenttype = '\'C\'';
			str += '	<input type="hidden" name="data[subtitle_id]" value="'+subtitleid+'"/>'
				+  '	<input type="hidden" name="data[video_id]" value="'+this.videoId+'"/>'
				+  '	<input type="hidden" name="data[tag_id]" value="0"/>\n'
				+  '	<div style="float:left; width:410px; height:20px;">\n'
				+  radio_language
				+  '	<textarea name="data[content]" id="add_content" style="width:404px; height:18px; overflow-y:auto; border:1px solid #888888;"></textarea>\n'
				+  '	</div>\n';
			break;
		case 'T' :
			value = 'Translate';	commenttype = '\'T\'';
			str += '	<input type="hidden" name="data[subtitle_id]" value="'+subtitleid+'"/>'
				+  '	<input type="hidden" name="data[video_id]" value="'+this.videoId+'"/>'
				+  '	<input type="hidden" name="data[tag_id]" value="0"/>\n'
				 + '	<div style="float:left; width:410px; height:20px;">\n'
				 +  radio_language
				 + '	<textarea name="data[translate]" id="add_content" style="width:404px; height:18px; overflow-y:auto; border:1px solid #888888;" ></textarea>\n'
				 + '	</div>\n';
			break;
		case 'A' :
		case 'C' :
			value = 'Comment';	commenttype = '\'C\'';
			str += '	<input type="hidden" name="data[subtitle_id]" value="'+subtitleid+'"/>'
				+  '	<input type="hidden" name="data[video_id]" value="'+this.videoId+'"/>'
				+  '	<input type="hidden" name="data[tag_id]" value="0"/>\n'
				 + '	<div style="float:left; width:410px; height:20px;">\n'
				 + radio_language
				 + '	<textarea name="data[content]" id="add_content" style="width:404px; height:18px; overflow-y:auto; border:1px solid #888888;" ></textarea>\n'
				 + '	</div>\n';
			break;
		default :
			str = '';
			break;
		}
		str += '<div style="float:left;">\n'
			+  '	<div class="clsButtonReply" onclick="SubtitleDiscussion.addReply($(\'frmComment'+ id +'\'), \''+ id +'\', '+ commenttype +');" style="margin-left:3px; padding-top:2px; height:18px;">'+ value +'</div>\n';
		if('Q' == type.toUpperCase()) {
			str += '	<div class="clsButtonReply" onclick="SubtitleDiscussion.addReply($(\'frmComment'+ id +'\'), \''+ id +'\', \'A\');" style="margin-left:3px; padding-top:2px; height:18px;">Answer</div>\n';
		}

		str += '	<div class="clsButtonReply" onclick="SubtitleDiscussion.removeTag('+id+');" style="margin-left:3px; padding-top:2px; height:18px;">Discard</div>\n'
			+  '</div>\n'
			+  '</form>\n';

		ele = $('subpost'+id);
		ele.innerHTML = str;
		Element.setStyle(ele, {display:'block'});
	},

	removeTag: function(id) {
		$('subpost'+id).removeChild($('frmComment'+ id));
		Element.setStyle($('subpost'+id), {display:'none'});
	},

	addReply : function(frm, rid, type) {
//alert(frm +', '+ rid +', '+ type);
		if(false == this.logIn()) {	return;	}
		if (!this.isvideo()) { return; }
		var notWhiteSpace = new RegExp(/[^\s]/);
		var quotation = new RegExp(/\'/g);
		var backSlash = new RegExp(/\\/g);
		var urlLink	= new RegExp(/(http|https|ftp|telnet|news):\/\/([a-z0-9_\-]+\.[][a-zA-Z0-9:;&#@=_~%\?\/\.\,\+\-]+)/g);

		if (type != 'T') {
			if (!notWhiteSpace.test(frm['data[content]'].value)) {
				alert('Type the comment please!!');
				return;
			}

			if (backSlash.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value.replace(backSlash, "\\\\");
			}

			if (quotation.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value.replace(quotation, "\\\'");
			}

			if (urlLink.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value.replace(urlLink, "<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>");
			}
		}
		else {
			if (!notWhiteSpace.test(frm['data[translate]'].value)) {
				alert('Type the comment please!!');
				return;
			}

			if (backSlash.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value.replace(backSlash, "\\\\");
			}

			if (quotation.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value.replace(quotation, "\\\'");
			}

			if (urlLink.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value.replace(urlLink, "<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>");
			}
		}

		if (typeof type != 'undefined') {
			frm['data[content_type]'].value = type.toUpperCase();
		}
		var url = '/subtitles/add_reply/' + (typeof rid == 'undefined' ? '' : rid);
		var param = frm.serialize();
		var response = new Ajax.Request( url, {
					asynchronous: false,
					parameters: param,
					onSuccess: this.onCallback,
					onFailure: this.onError
				});
	},

	inapproprite: function(cat, id, type) {
//alert('cat='+cat+', id='+id+', type='+type);
		if(false == this.logIn()) {	return; }
		if (!this.isvideo()) { return; }
		tagid = type.toLowerCase() + '_del' + id;
		var position = Position.positionedOffset($(tagid));
		if(false == this.logIn()) {
			return;
		}
		else {
			ViiKii.Inappro.init(cat, id, position, type);
		}
	},

	deleteMessage: function(id, type, subtitleid) {
//alert('id='+id+' type='+type+' subtitleid='+subtitleid);
		if(false == this.logIn()) {	return; }
		if (!this.isvideo()) { return; }
//ViiKii.UI.Round.init('st_del_msg'+subtitleid, {radius:4});
		ele = type.toLowerCase() + '_del' + id;
		var position = Position.positionedOffset($(ele));
		var str = '<div id="td_msg" style="">'
			 + '	<div style="width:300px; height:15px;"><img src="/common/close.gif" style="cursor:pointer;" border="0" align="right" onclick="SubtitleDiscussion.deleteCancel();"></div>'
			 + '	<div style="width:280px; height:15px; padding-left:20px; text-align:left;">Do you really want to delete this message?</div>'
			 + '	<div style="width:280px; height:15px;"></div>'
			 + '	<div style="width:300px; height:30px;">'
			 + '		<div style="float:left;height:30px;width:140px;margin:0 12 0 0;text-align:center;"><a href="javascript:SubtitleDiscussion.deleteComment('+ id +', \''+ type +'\', '+ subtitleid +');">yes</a></div>'
			 + '		<div style="float:left;height:30px;width:140px;text-align:left;"><a href="javascript:SubtitleDiscussion.deleteCancel();">cancel</a></div>'
			 + '	</div>'
			 + '</div>'
			 + '';

		$('st_del_msg'+subtitleid).innerHTML = str;
		Element.setStyle($('st_del_msg'+subtitleid), {left:position[0]-300+'px', top:position[1]+'px', border:'1px solid gray', display:'block'});
	},

	deleteComment: function(rid, type, subtitleid) {
//alert('rid='+rid+', type='+type+', subtitleid='+subtitleid);
		var param = '';
		param += 'data[subtitle_id]='+ subtitleid + "&data[video_id]=" + this.videoId;

		var url = '/subtitles/delete_comment/'+ (typeof rid == 'undefined' ? '' : rid) +'/'+ type;
		Element.setStyle($('st_del_msg'+subtitleid), {display:'none'});
		var response = new Ajax.Request( url, {
					asynchronous: true,
					evalScripts: true,
					parameters: param,
					onSuccess: this.onCallback,
					onFailure: this.onError
				});
	},

	deleteCancel: function() {
		if($('td_msg') != null) {
			$('st_del_msg'+this.subtitleId).removeChild($('td_msg'));
		}
		Element.setStyle($('st_del_msg'+this.subtitleId), {display:'none'});
	},

	rateComment : function(thumb, id, rate, cat) {
//alert(thumb +','+ id +','+ rate +','+ cat);
		if(false == this.logIn()) {	return; }
		if (!this.isvideo()) { return; }

		cat = (!cat) ? 'S' : cat.toUpperCase();
		var container = cat.toLowerCase() + '_rate' + id;
		container = (!container) ? cat.toLowerCase() + '_rate' + id : container;
		var response = new Ajax.Updater(container, '/subtitles/rate_comment/'+ cat +'/'+ id +'/'+ thumb +'/'+ rate, {asynchronous:true, evalScripts:true});
	},

	showTrans: function(discussionId) {
		var e = $('TransMore'+discussionId);
		var show = Element.getStyle(e, 'display');
		Element.setStyle(e, {display:(show=='none'?'block':'none')});
	},

	loadPage: function(pageNum, subtitleid) {
		this.refreshComment(subtitleid, pageNum);
	},

	refreshComment: function(subtitleid, pageNum) {
//alert(subtitleid+','+pageNum);
		var url = this.listUrl + '/' + subtitleid +'/' + pageNum;
		var rtn1 = new Ajax.Updater('sd_discussion_wrap_'+subtitleid, url, {
				asynchronous: false,
				evalScripts: true,
				parameters: null
			});

		url = '/subtitle_revisions/discussions/'+ subtitleid;
		var rtn2 = new Ajax.Updater('sd_count_'+subtitleid, url, {
				asynchronous: false,
				evalScripts: true,
				parameters: null
			});

		if(this.scrollBar != null) {
			this.scrollBar.update();
		}

		if (ViiKii.Board) { ViiKii.Board.list(); }
	},

	logIn: function() {
		if(this.islogin) {
			return true;
		}
		else {
			alert('Not logined!!');
			return false;
		}
	},

	isvideo: function(callback) {
		var xml = new Ajax.Request('/videos/isvideo/'+this.videoId, {asynchronous: false});
		var rtn = xml.transport.responseText;
		if (!rtn) {
			setTimeout(function(){alert("Sorry!\nThis video was deleted while you are watching it."); document.location = '/';}, 100);
			return false;
		}
		else {
			return true;
		}
	},

	onCallback: function(trasnport) {
		if ('NOT_PERMISSION' == trasnport.responseText) {
			alert("You don't have permission");
			return;
		}
//		var arrayToken = trasnport.responseText.split(',', 3);
		SubtitleDiscussion.refreshComment(trasnport.responseText, 1);
	},

	onError: function() {}

};//SubtitleDiscussion


ViiKii.Subtitle = {

	add: function(videoId, segmentId, languageId, subtitle, sort) {
		if (Object.isUndefined(sort)) {
			sort = 'R';
		}
		var params = $H(
			{
				'videoId': videoId,
				'segmentId': segmentId,
				'languageId': languageId,
				'subtitle': subtitle,
				'sort': sort
			}
		).toQueryString();
		
		var responseXml = new Ajax.RequestXML(
			'/subtitles/add',
			{
				asynchronous: false,
				method: 'post',
				parameters: params
//				,onComplete: function(rtn) {alert(rtn.responseText);}
			}
		);
		return responseXml.responseValue.response;
	},

	remove: function(videoId, segmentId, subtitleId, languageId, sort) {
		if (Object.isUndefined(sort)) {
			sort = 'R';
		}
		var url = '/subtitles/remove/' + videoId + '/' + segmentId + '/' + subtitleId + '/' + languageId + '/' + sort;
		var responseXml = new Ajax.RequestXML(
			url,
			{
				asynchronous: false,
				method: 'get',
				parameters: null
			}
		);
		return responseXml.responseValue.response;
	},

	rating: function(videoId, subtitleId, point) {
		var url = '/subtitles/rating/' + videoId + '/' + subtitleId + '/' + point;
		var responseXml = new Ajax.RequestXML(
			url,
			{
				asynchronous: false,
				method: 'get',
				parameters: null
			}
		);
		return responseXml.responseValue.response;
	}
};//End of ViiKii.Subtitle


ViiKii.Subtitle.HistoryPopup = {
	_layerId: 'subtitle_history_popup_layer',
	_titleLayerId: 'subtitle_revision_title',
	_layer: null,
	_shadow: null,
	_videoId: 0,
	_segmentId: 0,
	_languageId: null,
	_openerSorted: 'R',
	_sort: 'R',
	_isSortOrderDESC: true,

	getVideoId: function() {
		return ViiKii.Subtitle.HistoryPopup._videoId;
	},

	ErrorHandler: {
		handle: function(err) {
			switch(err) {
				case 'not_logined':
					alert('not logined!');
					break;
				case 'not_existed_segment':
					alert('The manager of this video just re-deployed the segments.\nThis video will be reloaded now to reflect the latest change');
					ViiKii.Subtitle.HistoryPopup.close();
					ViiKii.Subtitle.HistoryPopup.reloadOpener();
					break;
				case 'not_existed_subtitle', 'EM001':
					alert('The manager of this video just re-deployed the segments.\nThis video will be reloaded now to reflect the latest change');
					ViiKii.Subtitle.HistoryPopup.close();
					ViiKii.Subtitle.HistoryPopup.reloadOpener();
					break;
				case 'not_existed_video':
					alert("Sorry!\nThis video was deleted while you are watching it.");
					document.location = "/";
					break;
				case 'not_published_video':
					alert("This video is not published by the video manager yet.");
					document.location = "/";
					break;
				case 'error_add':
					alert("error: add subtitle");
					document.location.reload();
					break;
				case 'EM005':
					alert("Some body already posted the same sentence as yours.");
					break;
				case 'not_permission':
					alert("You don't have permission");
					break;
				case 'subtitle_locked':
					alert("[] subtitle locked by the manager");
					break;
				default:
					alert('un-known error');
					if (ViiKii.Subtitle.HistoryPopup.opened()) {
						ViiKii.Subtitle.HistoryPopup.close();
					}
					break;
			}
		}
	},

	_create: function() {
		if ($(this._layerId)) {
			return $(this._layerId);
		} else {
			var layer = document.createElement('div');
			layer.id = this._layerId;
			var style = {
				position: 'absolute',
				left: '260px',
				top: '200px',
				width: '732px',
				height: '480px',
				background: '#ffffff'
			};

			Element.setStyle(layer, style);
			document.getElementsByTagName('body')[0].appendChild(layer);
			return layer;
		}
	},

	drawRound: function() {
		if (this._layer) {
			ViiKii.UI.Round.init(this._layer, {coners: 'all', borderSize:1});
			if (!this._shadow) {
				this._shadow = new ViiKii.UI.Shadow(this._layer);
			}
		}
	},

	attachDragEvent: function() {
		if (this._shadow) {
			DragHandler.attach(this._shadow.container, $(this._titleLayerId));
		}
	},

	_validateOpening: function(videoId, segmentId) {
		var url = '/subtitles/validatePpupHistory/' + videoId + '/' + segmentId;
		var responseXml = new Ajax.RequestXML(
			url,
			{
				asynchronous: false,
				parameters: null,
				onFailure: function(transport) { alert(transport.responseText); }
			}
		);
		return responseXml.responseValue.response;
	},

	open: function(videoId, segmentId, languageId, sort) {
		if ($(this._layer)) {
			this.close();
		}
		var validated = this._validateOpening(videoId, segmentId);

		if (validated.result.status.equals('error')) {
			this.ErrorHandler.handle(validated.result.error);
			return;
		}

		this._videoId = videoId;
		this._segmentId = segmentId;
		this._languageId = languageId;
		this._layer = this._create();
		this._openerSorted = sort;
		this._sort = sort;

		if (this._layer) {
			this.update();
		}
		var posLeft = (document.body.scrollWidth - 662) / 2;
		var posTop  = Position.realOffset(document.body)[1] + 150;
		var styles = {left:posLeft+'px',top:posTop+'px', position:'absolute', 'z-index':5};
		Element.setStyle($(this._shadow.container), styles);
		
	},

	close: function() {
		if ($(this._layerId)) {
			document.getElementsByTagName('body')[0].removeChild($(this._shadow.container));
		}

		this._clearStatus();
		SubtitleDiscussion.scrollBar = null;

		if (ViiKii.Video.Player.loaded()) {
			ViiKii.Video.Player.revisionPopupCancel();
		} else if (ViiKii.My.subtitles.loaded) {
			ViiKii.My.subtitles.reload();
		}
	},

	reloadOpener: function() {
		if (ViiKii.Video.Player.loaded()) {
			ViiKii.Video.Player.subtitleReload();
		} else {
			document.location.reload();
		}
	},

	_clearStatus: function() {
		this._layer = null;
		this._shadow = null;
		this._videoId = 0;
		this._segmentId = 0;
		this._languageId = null;
		this._openerSorted = 'R';
		this._sort = 'R';
	},

	update: function() {
		ViiKii.Tracker.track("/TRACK/subtitles/revion_popup/" + this._segmentId);
//		var url = '/subtitles/popupHistory/' + this._segmentId + '/' + this._languageId + '/' + this._openerSorted + '/' + this._sort;
		var url = '/subtitle_revisions/popup/' + this._segmentId + '/' + this._languageId + '/' + this._sort;
		var response = new Ajax.Updater(
			this._layer,
			url,
			{
				asynchronous: false,
				evalScripts: true,
				parameters: null,
				onFailure: function(transport) { alert(transport.responseText); },
				onComplete: function(transport) {
					ViiKii.Subtitle.HistoryPopup.drawRound();
					ViiKii.Subtitle.HistoryPopup.attachDragEvent();
				}
			}
		);
	},
	
	test_update: function(segmentId, languageId, sort) {
		
	},

	_updateList: function(segmentId, languageId, sort, isSortOrderDESC) {
		var sortOption = (isSortOrderDESC)? "DESC" : "ASC";	//true-1:DESC, false-0:ASC
//		var url = '/subtitles/popupListInSegment/' + segmentId + '/' + languageId + '/' + sort + '/' + sortOption;
		var url = '/subtitle_revisions/subtitles/' + segmentId + '/' + languageId + '/' + sort + '/' + sortOption;
		var response = new Ajax.Updater(
			'popup-history-list',
			url,
			{
				asynchronous: true,
				evalScripts: true,
				parameters: null,
				onFailure: function(transport) { alert(transport.responseText); }
			}
		);
	},

	save: function() {
		var response = ViiKii.Subtitle.add(this._videoId,
			this._segmentId, this._languageId, $('data[RevisionPopupSubtitle][subtitle]').value, this._openerSorted);
		
		if (response.result.status.equals('success')) {
			this._sort = 'P';	// after save, recent sorting.
			this.update();

			if (ViiKii.Video.Player.loaded()) {
				var subtitle = Object.isNull(response.result.subtitle.content) ? "" : response.result.subtitle.content;
				ViiKii.Video.Player.revisionPopupSave(subtitle);
			} else {
				ViiKii.Subtitle.Seeall.update();
			}
		} else {
			if (response.result.error == 'subtitle_locked') {
				msg = ViiKii.Languages.SelectBox._language[ViiKii.Languages.SelectBox._languageId.indexOf(this._languageId)] + " subtitle locked by the manager"; 
				alert(msg);
				return;
			}
			this.ErrorHandler.handle(response.result.error);
			return;
		}
	},

	remove: function(subtitleId) {
		if (confirm('Do you really want to delete this subtitle?')) {
			var response = ViiKii.Subtitle.remove(this._videoId, this._segmentId, subtitleId, this._languageId, this._openerSorted);
			//this._videoId == 2224
			if (response.result.status.equals('success')) {
				this.update();

				if (ViiKii.Video.Player.loaded()) {
					if (response.result.subtitle == null) {
						ViiKii.Video.Player.revisionPopupModify(0, '', '', '');
					} else {
						var subtitle = response.result.subtitle;
						subtitle.content = (null == subtitle.content)? '' : subtitle.content;
						ViiKii.Video.Player.revisionPopupModify(1, subtitle.content, subtitle.user_name, subtitle.revision);
					}
				} else {
					ViiKii.Subtitle.Seeall.update();
				}
			} else {
				this.ErrorHandler.handle(response.result.error);
				return;
			}
		}
	},

	rating: function(starBox, subtitleId) {
		var response = ViiKii.Subtitle.rating(ViiKii.Subtitle.HistoryPopup.getVideoId(), subtitleId, starBox.getPoint());
		if (response.result.status.equals('success')) {
			ViiKii.Subtitle.HistoryPopup.update();
			if (ViiKii.Video.Player.loaded()) {
				var subtitle = response.result.subtitle;
				subtitle.content = (null == subtitle.content)? '' : subtitle.content;
				ViiKii.Video.Player.revisionPopupModify(1, subtitle.content, subtitle.user_name, subtitle.revision);
			}
		} else if (response.result.status.equals('error')) {
			ViiKii.Subtitle.HistoryPopup.ErrorHandler.handle(response.result.error);
			return;
		}
	},
	
	rating2: function(starBox, params) {
		//params = 109_100;
		var videoId = params.substr(0, params.indexOf('_'));
		var	subtitleId = params.substr(params.indexOf('_')+1);
		var response = ViiKii.Subtitle.rating(videoId, subtitleId, starBox.getPoint());
		
		if (response.result.status.equals('success')) {
			ViiKii.My.subtitles.reload();
		} else if (response.result.status.equals('error')) {
			ViiKii.Subtitle.HistoryPopup.ErrorHandler.handle(response.result.error);
			return;
		}
	},

	_equalsLastSort: function(sort) {
		return this._sort == sort;
	},

	_setSort: function(sort) {
		if (this._equalsLastSort(sort)) {
			this._isSortOrderDESC = !this._isSortOrderDESC;
		} else {
			this._sort = sort;
			this._isSortOrderDESC = true;
		}
	},

	sortingRecent: function() {
		this._setSort('R');
		this._updateList(this._segmentId, this._languageId, this._sort, this._isSortOrderDESC);
	},

	sortingPopular: function() {
		this._setSort('P');
		this._updateList(this._segmentId, this._languageId, this._sort, this._isSortOrderDESC);
	},

	sortingDiscussion: function() {
		this._setSort('D');
		this._updateList(this._segmentId, this._languageId, this._sort, this._isSortOrderDESC);
	}
};//End of ViiKii.Subtitle.HistoryPopup

ViiKii.Subtitle.Contributors = {
	objectId: 'ViiKii.Subtitle.Contributors',
	loadPage: function(curPage) {
		ViiKii.Util.set(this, 'curPage', curPage);
		this.updatePage();
	},
	updatePage: function() {
		new Ajax.Updater(
			'ViiKii.Subtitle.Contributors.content',
			'/subtitles/contributors/'+ViiKii.Util.get(this, 'curPage'),
			{
				evalScripts: true,
				method: 'get'
			}
		)
	}
};
ViiKii.Subtitle.Export = {
	save: function() {
		var languageSelect = $('language_select');
		var languageId =  languageSelect.options[languageSelect.selectedIndex].value;
		if(languageId == "0") {
			alert('Select a Language First!');
			return;
		}
		var params = $H({
			'sign': $('offset_sign').value,
			'hour': $('offset_hour').value,
			'min': $('offset_min').value,
			'sec': $('offset_sec').value,
			'msec': $('offset_msec').value
		}).toQueryString();
		new Ajax.Request(
			'/caption_exporter/on_export/'+$('video_id').value+'/'+languageId,
			{
				evalScripts: true,
				parameters: params,
				onComplete: this.onSave.bind(this)
			}
		);
	},
	onSave: function(transport, response) {
		if(response.result == "SUCCESS") {
			document.location = response.url;
			return;
		}
		switch(response.error) {
		case 'NOT_ADMIN':
			alert('You are not an administrator.');
			return;
		case 'INVALID_VIDEO':
			alert('This video is deleted.');
			return;
		case 'INVALID_SIGN':
			alert("Please insert available sign (+/-).");
			$('offset_sign').focus();
			return;
		case 'INVALID_HOUR':
			alert("Please insert available hour.");
			$('offset_hour').focus();
			return;
		case 'INVALID_MIN':
			alert("Please insert available minute.");
			$('offset_min').focus();
			return;
		case 'INVALID_SEC':
			alert("Please insert available second.");
			$('offset_sec').focus();
			return;
		case 'INVALID_MSEC':
			alert("Please insert available msec.");
			$('offset_msec').focus();
			return;
		}
	}
};
ViiKii.Subtitle.Seeall = {
	version: '0.1',
	name: 'Subtitle.SeeAll',
	isLogin: function(){
		return (ViiKii.Util.getDomainCookie('username') == null ? false : true);
	},
	isEditing: false,
	videoId: '',
	sort: 'P',
	revision: 0,
	flashGotoPage: function() {
		this.isEditing = false;
		if(Object.isUndefined(ViiKii.Video) || Object.isNull(ViiKii.Video.getId())) {
			return;
		}
		this.videoId = ViiKii.Video.getId();
		var response = new Ajax.Request(
			'/videos/isvideo/'+this.videoId, {
				method: 'get',
				onSuccess: function(transport) {
					if (transport.responseText) {
						document.location = '/subtitles/seeall/' + ViiKii.Subtitle.Seeall.videoId;
					}
					else  {
						setTimeout(function(){alert("Sorry!\nThis video was deleted while you are watching it.");}, 100);
					}
				}
			}
		);
	},
	attach: function(subject) {
		subject.attach(this);
	},
	update: function() {
		new Ajax.Updater('seeall_wrap', '/ci/index.php/subtitle_seeall/load/' + this.videoId, {evalScripts:true});
	},
	onErrorPage: function() {},
	sortList: function(sort) {
		this.sort = sort;
		this.update();
	},
	clickCell: function(event) {
		if (!this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}
		var source = Event.element(event);
		var sourceId = source.id.split("_");
	
		if (this.isLogin && sourceId[0] == 'cell') {
			this.revision = source.getAttribute('rev');
			this.editCell(source.id);
		} else if (sourceId[0] == 'revision') {
			this.showRevision(source.id);
		} else if (this.isLogin && sourceId[0] == 'save') {
			this.saveText();
		} else if (this.isLogin && sourceId[0] == 'cancel') {
			this.onCancelSave();
		}
	},
	showRevision: function(itemId) {
		if (this.isEditing) { return; }
		var items = itemId.split("_");
		if (items[0] != 'revision') {
			return false;
		}
		if (items.length < 3) {
			return false;
		}
		ViiKii.Subtitle.HistoryPopup.open(this.videoId, items[1], items[2], 'P');
	},
	editCell: function(cellId) {
		if(this.isEditing) {
			return;
		}
		this.editableCell.onKeyEnterDown = "ViiKii.Subtitle.Seeall.saveText()";
		this.editableCell.onKeyESCDown = "ViiKii.Subtitle.Seeall.onCancelSave()";
		this.editableCell.editCell(cellId);
		this.isEditing = true;
	},
	onKeyDown: function(event) {
		var keyCode = this.getKeyCode(event);
		switch(keyCode) {
		case 13:
			this.saveText();
			break;
		case 27:
			this.onCancelSave();
			break;
		}
	},
	getKeyCode: function(event) {
		if (window.event) {
			return window.event.keyCode;
		}
		if (event) {
			return event.which;
		}
	},
	getAttribute: function(type) {
		var rtn = '';
		var cellId = this.editableCell.getCellId();
		var ele = cellId.split("_");
		switch (type) {
			case "segment"   : rtn = ele[1]; break; 
			case "language"  : rtn = ele[2]; break; 
			case "starttime" : rtn = ele[3]; break; 
			case "endtime"   : rtn = ele[4]; break;
			case "revision"  : rtn = ele[5]; break;
			default:  
		}
		return rtn;
	},
	saveText: function() {
		if(!this.isEditing) {
			return;
		}
		var subtitle = this.editableCell.getTextAreaText();
		/* white-space check removed..
		if(!/[^\s]/.test(inputText)) {
			this.onCancelSave();
			return;
		}
		*/
		
		var params = $H({
				'video'    : this.videoId,
				'segment'  : this.getAttribute('segment'),
				'starttime': this.getAttribute('starttime'),
				'endtime'  : this.getAttribute('endtime'),
				'language' : this.getAttribute('language'),
				'subtitle' : subtitle,
				'revision' : this.revision,
				'sort'     : this.sort
			}).toQueryString();
		var responseXml = new Ajax.RequestXML(
			'/subtitles/seeallAdd/',
			{
				asynchronous: false,
				method: 'post',
				parameters: params
				//,onComplete: function(rtn) {alert(rtn.responseText);}
			}
		);
		rtn = responseXml.responseValue.response;
		if (rtn.result=="SUCCESS") {
			this.onSaveText(rtn.revision, subtitle);
		}
		else {
			switch (rtn.error) {
				case 'EG000':
					alert("Sorry!\nThis video was deleted while you are watching it.");
					document.location = '/';
					break;
				case 'EG001':
					alert("Sorry!\nSent invalid datas.");
					document.location.reload();
					break;
				case 'EG002':
					alert("You don't have permission");
					document.location.reload();
					break;
				case 'EG003':
					msg = ViiKii.Languages.SelectBox._language[ViiKii.Languages.SelectBox._languageId.indexOf(this.getAttribute('language'))] + " subtitle locked by the manager";
					alert(msg);
					break;
				case 'EM001':
					alert("The manager of this video just re-deployed the segments.\nThis video will be reloaded now to reflect the latest change");
					document.location.reload();
					break;
				case 'EG100':
					alert("Sorry!\nDB-Error : HANDLER FOR SQLEXCEPTION.");
					document.location.reload();
					break;
				case 'EM005':
					alert("Some body already posted the same sentence as yours.");
					break;
				default:
					alert("add Subtitle fail");
					document.location.reload();
					break;
			}
			this.onCancelSave();
		}
	},
	onSaveText: function(revision, subtitle) {
		var cellId = this.editableCell.getCellId().split("_");
		var revisionId = cellId.without(cellId[0]).join("_");
		var inputText = subtitle;
		this.editableCell.setText(inputText, revisionId, revision);
		this.isEditing = false;
	},
	onCancelSave: function() {
		this.editableCell.cancelEdit();
		this.isEditing = false;
	},
	editableCell: new ViiKii.UI.EditableCell()
};
ViiKii.Synopsis = {
	add: function(videoId, language, synopsis) {
		var res = new Ajax.Request('/synopses/add', {asynchronous: false,
					evalScripts: false,
					parameters: $H({
							'videoId': videoId,
							'languageId': language,
							'synopsis': synopsis}).toQueryString()
			});
		return res.evalJSON();
	},
	remove: function(id) {
		var res = new Ajax.Request('/synopses/remove/' + id, {
				asynchronous: false,
				parameters: null,
				evalScripts: false
			});
		return res.evalJSON();
	},
	rating: function(id, point) {
		var res = new Ajax.Request('/synopses/rating/' + id + '/' + point, {
				asynchronous: false,
				parameters: null,
				evalScripts: false
			});
		return res.evalJSON();
	}
};ViiKii.TabPanel = Class.create();
ViiKii.TabPanel.prototype = {
	initialize: function(headers, contents, options) {
		if (typeof headers == 'string') headers = $$(headers);
		if (typeof contents == 'string') contents = $$(contents);

		this.headers = headers;
		this.contents = contents;
		this.options = Object.extend ({
			delay: 100,
			opacity: false
		}, options || {});

		//contents.each ( function(e) { if (e) Element.hide(e); } );
		contents.each ( function(e) { if (e) Element.setStyle(e, {left:'1000px', top:'1000px'}); } );
		this.hoverSet = new ViiKii.HoverSet(headers, options);
		this.selectionSet = new ViiKii.SelectionSet(headers, Object.extend(this.options, {onSelect: this.onSelect.bind(this)}));
		this.transition(this.selected);
	},

	onSelect: function(header) {
	  	if (this.selected == this.contentOf(header)) return;
		var panel = this.contentOf(header);
		if (this.selected)
			this.transition(panel)
		else
			Element.setStyle(panel, {left:'-10px', top:'-10px'});
			//Element.show(panel);
		this.selected = panel;

		var callback = header.getAttribute('func');
		if (typeof callback != 'undefined' && callback != 'null') rtn = eval(callback);
	},

	transition: function(element){
		if (this.selected) Element.hide(this.selected);
		Element.show(element);
	},
	contentOf: function(header){ return this.contents[this.headers.indexOf(header)]}
};

ViiKii.HoverSet = Class.create();
ViiKii.HoverSet.prototype = {
	initialize: function(hoverSet, options) {
 		if (typeof hoverSet == 'string') hoverSet = $$(hoverSet)
 		this.hoverSet = hoverSet;
		this.options  = options || [];
		this.hoverClassName = this.options.hoverClass || 'hover';
		this.hoverNodes     = this.options.hoverNodes || function(e){return [e]};
		this.onHoverHandler = this._onHover.bind(this);
		this.unHoverHandler = this._unHover.bind(this);
		this.hoverSet.each((function(e) {Event.observe(e, "mousemove", new ViiKii.EventWrapper(this.onHoverHandler,e).wrapper);}).bind(this));
		this.hoverSet.each((function(e) {Event.observe(e, "mouseout",  new ViiKii.EventWrapper(this.unHoverHandler,e).wrapper);}).bind(this));
	},
	over: function(target) { this.hoverNodes(target).each((function(t){Element.classNames(t).add(this.hoverClassName)}).bind(this)); },
	out: function(target)  { this.hoverNodes(target).each((function(t){Element.classNames(t).remove(this.hoverClassName)}).bind(this)); },
	_onHover: function(event, target) { this.over(target); },
	_unHover: function(event, target) { this.out(target); }
};
ViiKii.SelectionSet = Class.create();
ViiKii.SelectionSet.prototype = {
	initialize: function(selectionSet, options) {
    if (typeof selectionSet == 'string') selectionSet = $$(selectionSet)
		this.selectionSet = selectionSet;
		this.options = options || [];
		this.selectedClassName = this.options.selectedClass || 'selected';
		this.selectedNodes = this.options.selectedNodes || function(e) { return e };
		this.clickHandler = this._click.bind(this);
		this.onSelect = this.options.onSelect;
		this.selectionSet.each((function(e) {Event.observe(e, "click", new ViiKii.EventWrapper(this.clickHandler,e).wrapper);}).bind(this));
		this.selectIndex(this.options.selectedIndex || 0)
	},
	select: function(target) {
		if (this.selected == target) return;
		if (this.selected) new Element.classNames(this.selectedNodes(this.selected)).remove(this.selectedClassName);

		var index = this.selectionSet.indexOf(target);
		if (this.onSelect) try{ this.onSelect(target, index) } catch (e) {};

		this.selected = target;
		new Element.classNames(this.selectedNodes(this.selected)).add(this.selectedClassName);
	},
	selectIndex: function(index) { this.select(this.selectionSet[index]) },
	_click: function(event, target) { this.select(target); }
};
ViiKii.EventWrapper = Class.create();
ViiKii.EventWrapper.prototype = {
  initialize: function(handler, target){
    this.handler = handler;
    this.target = target;
    this.wrapper = this.wrapperCall.bindAsEventListener(this)
  },
  wrapperCall: function(event){
    this.handler(event, this.target)
  }
};
ViiKii.Title = {
	add: function(videoId, language, title) {
		var res = new Ajax.Request('/titles/add', {asynchronous: false,
				evalScripts: false,
				parameters: $H({
					'videoId': videoId,
					'languageId': language,
					'title': title}).toQueryString()
			});
		return res.evalJSON();
	},
	remove: function(id) {
		var res = new Ajax.Request('/titles/remove/' + id, {
				asynchronous: false,
				parameters: null,
				evalScripts: false
			});
		return res.evalJSON();
	},
	rating: function(id, point) {
		var res = new Ajax.Request('/titles/rating/' + id + '/' + point, {
				asynchronous: false,
				parameters: null,
				evalScripts: false
			});
		return res.evalJSON();
	}
};
ViiKii.Topic = {};

ViiKii.Topic.New = {
	objectId: 'ViiKii.Topic.New',
	mode: '',
	setMode: function(mode) {
		this.mode = mode;
	},
	update: function() {
		ViiKii.Topic.New.TopicList.refresh.bind(ViiKii.Topic.New.TopicList);
		ViiKii.Topic.New.TopicList.refresh();
		
		ViiKii.Topic.Editor.Reply.closeLastEditor();
		if(this.mode == 'POST') {
			this.updateContents();
		} else if(this.mode == 'TRANSLATION') {
			ViiKii.Topic.New.Main.Translation.updateContent.bind(ViiKii.Topic.New.Main.Translation);
			ViiKii.Topic.New.Main.Translation.updateContent();
		} else if(this.mode == 'EDIT') {
			ViiKii.Topic.New.Main.Edit.updateContent.bind(ViiKii.Topic.New.Main.Edit);
			ViiKii.Topic.New.Main.Edit.updateContent();
		}
	},
	updateContents: function() {
		new Ajax.Updater(
			'ViiKii.Topic.New.contents',
			'/topics/topic/'+ViiKii.Util.get(this, 'type')+'/'+ViiKii.Util.get(this, 'groupId')+'/'+ViiKii.Util.get(this, 'topicId'),
			{
				method: 'get',
				evalScripts: true
			}
		);
	}
};
ViiKii.Topic.New.TopicList = {
	objectId: 'ViiKii.Topic.New.TopicList',
	loadPage: function(curPage) {
		ViiKii.Util.set(this, 'curPage', curPage);
		this.refresh();
	},
	refresh: function() {
		new Ajax.Updater(
			'ViiKii.Topic.New.TopicList.content',
			'/topics/post_topics/'+ViiKii.Util.get(this, 'forumId')+'/'+ViiKii.Util.get(this, 'curPage'),
			{
				evalScripts: true
			}
		);
	}
};
ViiKii.Topic.New.Main = {
	objectId: 'ViiKii.Topic.New.Main',
	isLogin: function() {
		return ViiKii.Util.getDomainCookie('username') !== null;
	},
	rate: function(descriptionId, type) {
		if(!this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}
		var ajax =	new Ajax.RequestXML(
						'/topics/rate_description/'+descriptionId+'/'+type,
						{
							method: 'get',
							asynchronous: false
						}
					);
		this.onSuccessRate(ajax);
	},
	onSuccessRate: function(ajax) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.showDescriptions('all', 'one');
			return;
		}
		switch(response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			return;
		case 'ALREADY_RATED':
			alert("You have been rated!");
			this.showDescriptions('all', 'one');
			return;
		case 'INVALID_REPLY':
			alert('This content was deleted!');
			this.showDescriptions('all', 'one');
			return;
		}
	},
	showDescriptions: function(language, show) {
		new Ajax.Updater(
			'ViiKii.Topic.New.Main.layer',
			'/topics/new_post_main/'+ViiKii.Util.get(this, 'type')+'/'+ViiKii.Util.get(this, 'groupId')+'/'+ViiKii.Util.get(this, 'topicId')+'/'+language+'/'+show,
			{
				method: 'get',
				evalScripts: true
			}
		);
	},
	removeMain: function(isCopier) {
		switch(ViiKii.Util.get(this, 'type')) {
		case 'FORUM':
		case 'CHANNEL':
			this.removeFromForum(isCopier);
			break;
		case 'MY':
			this.removeFromMyViiKii(isCopier);
			break;
		}
	},
	removeFromMyViiKii: function(isCopier) {
		var message = 'Do you really want to delete this topic?';
		if(isCopier) {
			message = 'Do you want to remove this topic from your page?';
		}
		if (!confirm(message)) {
			return;
		}
		new Ajax.Request(
			'/my_topics/del/'+ViiKii.Util.get(this, 'groupId')+'/'+ViiKii.Util.get(this, 'topicId'),
			{
				onSuccess: this.onRemoveFromMyViiKii.bind(this)
			}
		);
	},
	onRemoveFromMyViiKii: function(transport, response) {
		//alert(transport.responseText);
		if(response.result == 'SUCCESS') {
			alert('Successfully removed');
			ViiKii.My.Topic.TopicList.loadPage.bind(ViiKii.My.Topic.TopicList);
			ViiKii.My.Topic.TopicList.loadPage(1);
			ViiKii.My.Folder.reloadFolderList(ViiKii.Util.get(this, 'groupId'), 'TP');
			return;
		}
	},
	removeFromForum: function(isCopier) {
		var message =	'You cannot delete this topic in this forum\n' +
						'but can remove the topic from this forum.\n' +
						'Do you want to remove it from this forum?';
		if(isCopier) {
			message = 'Do you want to remove this topic from this forum?';
		}
		if (!confirm(message)) {
			return;
		}
		var ajax = new Ajax.RequestXML(
			'/topics/remove_topic/'+ViiKii.Util.get(this, 'groupId')+'/'+ViiKii.Util.get(this, 'topicId'),
			{
				method: 'get',
				asynchronous: false
			}
		);
		this.onRemoveFromForum(ajax, isCopier);
	},
	onRemoveFromForum: function(ajax, isCopier) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			var forumUrl = response.forum_url;
			if(isCopier) {
				alert(	'Successfully removed. However you still have this topic in\n' +
                    	'your page. To delete this topic completely, delete it on\n' +
                    	'your personal page.');
			} else {
				alert('Successfully removed.');
			}
			document.location = '/forums/forum/'+forumUrl;
			return;
		}
		switch(response.error) {
		case 'NOT_OWNER':
			alert("You are not the publisher of this topic.");
			return;
		case 'NOT_LINKED':
			alert("This topic is already removed from this forum");
			return;
		case 'DB_ERROR':
			alert("Fail to remove. Please try again");
			return;
		case 'INVALID_FORUM':
			alert("The forum is deleted by owner");
			document.location = '/forums/forum_list';
			return;
		}
	},
	deleteMain: function(descriptionId) {
		if (!confirm(	'Once you delete it, this translation in your personal page\n'+
						'and other forums will be also deleted and you cannot\n'+
                		'restore it.\n'+
                		'Do you want to delete this translation completely?')) {
			return;
		}
		var ajax = new Ajax.RequestXML(
			'/topics/delete_description/'+descriptionId,
			{
				method: 'get',
				asynchronous: false
			}
		);
		this.onSuccessDeleteMain(ajax);
	},
	onSuccessDeleteMain: function(ajax) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.showDescriptions('all', 'one');
			return;
		}
		switch(response.error) {
		case 'INVALID_DESCRIPTION':
			alert("This description is already deleted.");
			return;
		case 'NOT_OWNER':
			alert("You are not the owner of this description.");
			return;
		case 'INVALID_TOPIC':
			alert("This topic is already deleted");
			return;
		case 'DB_ERROR':
			alert("Fail to delete. Please try again");
			return;
		}
	}
};
ViiKii.Topic.New.Main.CopyToPopup = {
	objectId: 'ViiKii.Topic.New.Main.CopyToPopup',
	folders: {},
	open: function(topicId) {
		new Ajax.Updater(
			'ViiKii.Topic.New.Main.copyTo',
			'/topics/copy_to/'+topicId,
			{
				method: 'get',
				evalScripts: true
			}
		);
		Element.show('ViiKii.Topic.New.Main.copyTo');
	},
	close: function() {
		Element.hide('ViiKii.Topic.New.Main.copyTo');
	},
	init: function() {
		this.folders = {};
	},
	addFolder: function(folderId) {
		this.folders[folderId] = false;
	},
	check: function(folderId) {
		this.uncheckAll(folderId);
		this.changeCheck(folderId, !this.folders[folderId]);
	},
	uncheckAll: function(folderId) {
		var newFolder = folderId.split("_");
		for(var folder in this.folders) {
			var oldFolder = folder.split("_");
			if(oldFolder[0] == newFolder[0] && oldFolder[1] ==  newFolder[1] && oldFolder[2] != newFolder[2]) {
				if(this.folders[folder]) {
					this.changeCheck(folder, false);
				}
			}
		}
	},
	changeCheck: function(folderId, checked) {
		this.folders[folderId] = checked;
		this.changeCheckImage('folder_checkbox_'+folderId, checked);
	},
	changeCheckImage: function(id, checked) {
		var src = "";
		if(checked) {
			src = "/common/checkbox_ch.gif";
		} else {
			src = "/common/checkbox_wh.gif";
		}
		$(id).src = src;
	},
	getFolders: function() {
		var result = [];
		for(var folder in this.folders) {
			if(this.folders[folder]) {
				result.push(folder);
			}
		}
		return result;
	},
	copy: function() {
		if(this.getFolders().length == 0) {
			alert("Select available folder first.");
			return;
		}
		var params = $H(
			{
				'folders': this.getFolders().join(",")
			}
		).toQueryString();
		var ajax = new Ajax.RequestXML(
			'/topics/copy_topics_to/'+ViiKii.Util.get(this, 'topicId'),
			{
				asynchronous: false,
				parameters: params
			}
		);
		this.onSuccessCopy(ajax);
	},
	onSuccessCopy: function(ajax) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			alert('Topics are suggested successfully!');
			this.close();
			return;
		}
		switch(response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			return;
		case 'EMPTY_FOLDER':
			alert("Select available folder first.");
			return;	
		}
	}
};
ViiKii.Topic.New.Main.Edit = {
	objectId: 'ViiKii.Topic.New.Main.Edit',
	isLogin: function() {
		return ViiKii.Util.getDomainCookie('username') !== null;
	},
	display: function(topicId, origin) {
		if(!this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}
		if(ViiKii.Editor.isOpened) {
			if(ViiKii.Editor.closeCallback) {
				if(!ViiKii.Editor.closeCallback()) {
					return;
				}
			}
		}
		new Ajax.Updater (
			'ViiKii.Topic.New.contents',
			'/topics/post_main_edit/'+topicId+'/'+origin,
			{
				method: 'get',
				evalScripts: true
			}
		);
	},
	updateContent: function() {
		this.display(ViiKii.Util.get(this, 'topicId'), ViiKii.Util.get(this, 'origin'));
	}
};
ViiKii.Topic.New.Main.Translation = {
	objectId: 'ViiKii.Topic.New.Main.Translation',
	isLogin: function() {
		return ViiKii.Util.getDomainCookie('username') !== null;
	},
	display: function(topicId, origin) {
		if(!this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}
		if(ViiKii.Editor.isOpened) {
			if(ViiKii.Editor.closeCallback) {
				if(!ViiKii.Editor.closeCallback()) {
					return;
				}
			}
		}
		new Ajax.Updater (
			'ViiKii.Topic.New.contents',
			'/topics/post_main_translation/'+topicId+'/'+origin,
			{
				method: 'get',
				evalScripts: true
			}
		);
	},
	updateContent: function() {
		this.display(ViiKii.Util.get(this, 'topicId'), ViiKii.Util.get(this, 'origin'));
	}
};
ViiKii.Topic.New.Reply = {
	objectId: 'ViiKii.Topic.New.Reply',
	isLogin: function() {
		return ViiKii.Util.getDomainCookie('username') !== null;
	},
	rate: function(replyId, type, origin) {
		if(!this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}
		var ajax =	new Ajax.RequestXML(
						'/topics/rate_reply/'+replyId+'/'+type,
						{
							method: 'get',
							asynchronous: false
						}
					);
		this.onSuccessRate(ajax, origin);
	},
	onSuccessRate: function(ajax, origin) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.refreshReply(origin);
			return;
		}
		switch(response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			return;
		case 'ALREADY_RATED':
			alert("You have been rated!");
			this.refreshReply(origin);
			return;
		case 'INVALID_REPLY':
			alert('This content was deleted!');
			this.refreshReply(origin);
			return;
		}
	},
	showReplies: function(replyId, language, show) {
		ViiKii.Topic.Editor.Reply.closeLastEditor();
		new Ajax.Updater(
			'reply_'+replyId,
			'/topics/new_post_reply/'+ViiKii.Util.get(this, 'topicId')+'/'+replyId+'/'+language+'/'+show,
			{
				method: 'get',
				evalScripts: true
			}
		);
	},
	refreshReply: function(origin) {
		ViiKii.Topic.Editor.Reply.closeLastEditor();
		new Ajax.Updater(
			'reply_'+origin,
			'/topics/new_post_reply/'+ViiKii.Util.get(this, 'topicId')+'/'+origin,
			{
				method: 'get',
				evalScripts: true,
				onComplete: function() {
					this.showNewEditor();
				}.bind(ViiKii.Topic.Editor.Reply)
			}
		);
	},
	updateReplies: function(page) {
		ViiKii.Topic.Editor.Reply.closeLastEditor();
		new Ajax.Updater(
			'ViiKii.Topic.New.replies',
			'/topics/new_post_replies/'+ViiKii.Util.get(this, 'topicId')+'/'+page,
			{
				method: 'get',
				evalScripts: true
			}
		);
	},
	refreshReplies: function() {
		this.updateReplies(1);
	},
	deleteReply: function(contentType, replyId) {
		if (!confirm('Do you really want to delete this content?')) {
			return;
		}
		var ajax = new Ajax.RequestXML(
			'/topics/delete_reply/'+replyId,
			{
				method: 'get',
				asynchronous: false
			}
		);
		this.onSuccessDeleteReply(ajax, contentType);
	},
	onSuccessDeleteReply: function(ajax, contentType) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			if(contentType == 'T') {
				this.refreshReply(response.origin);
			} else {
				this.refreshReplies();
			}
			return;
		}
		switch(response.error) {
		case 'INVALID_REPLY':
			alert('Invalid content. Please try again!!');
			return;
		case 'NOT_OWNER':
			alert('You are not the owner of this content');
			return;
		}
	}};
ViiKii.Topic.Editor = {
	getEditLanguages: function(oldLanguage, originalLanguage) {
		var languages = ViiKii.Languages.getActiveInterestedLanguageCodes();
		var originIndex = languages.indexOf(originalLanguage);
		if(originIndex != -1) {
			languages.splice(originIndex, 1);
		}
		if(languages.indexOf(oldLanguage) == -1) {
			languages.unshift(oldLanguage);
		}
		return languages;
	},
	getTranslateLanguages: function(originalLanguage) {
		var languages = ViiKii.Languages.getActiveInterestedLanguageCodes();
		var originIndex = languages.indexOf(originalLanguage);
		if(originIndex != -1) {
			languages.splice(originIndex, 1);
		}
		return languages;
	},
	getLanguageTag: function(id, onclick, languageId, checked) {
		var tag = '';
		tag += "<div style=\"float:left;cursor:pointer;\" onclick=\""+onclick+"('"+id+"', '"+languageId+"')\">";
		if(checked) {
			tag += "<div style=\"float:left;\">";
			tag += "<img id='"+id+".language_"+languageId+"' src='/common/bullet_on18.gif'/>";
			tag += "</div>";
		} else {
			tag += "<div style=\"float:left;\">";
			tag += "<img id='"+id+".language_"+languageId+"' src='/common/bullet_off18.gif'/>";
			tag += "</div>";
		}
		tag += "<div class=\"default\" style=\"float:left;\">"+ViiKii.Languages.SelectBox.convertToName(languageId)+"</div>";
		tag += '</div>' 			
		return tag;
	},
	getLanguagesTag: function(id, onclick, languages, selectedIndex) {
		var tag = ''
		for(var i=0; i<languages.length; i++) {
			if(i != 0) {
				tag += '<div style="float:left;width:5px;height:18px;"></div>'
			}
			tag += this.getLanguageTag(id, onclick, languages[i], i==selectedIndex);
		}
		return tag;
	}
};
ViiKii.Topic.Editor.Main = {
};
ViiKii.Topic.Editor.NewTopic = {
	showEditor: function(uploadUrl) {
		var uploadUrl = uploadUrl+'?type=TOPIC_DESCRIPTION&user_name='+ViiKii.Util.getDomainCookie('username');
		ViiKii.Editor.openEditor('ViiKii.Topic.New.NewTopic.content', 429, '&nbsp;', uploadUrl);
	},
	getContent: function() {
		return ViiKii.Editor.getEditorContent();
	}
};
ViiKii.Topic.Editor.Main.Translation = {
	objectId: 'ViiKii.Topic.Editor.Main.Translation',
	save: function() {
		var title = $("ViiKii.Topic.New.Main.Translation.title").value;
		var content = ViiKii.Editor.getEditorContent();
		var message = "title: "+title+"\n";
		message += "language: "+ViiKii.Util.get(this, 'languageId')+"\n";
		message += "content: "+content+"\n";
		//alert(message);
		
		var params = $H(
			{title:	title,
			content: content,
			topic_id: ViiKii.Util.get(this, 'topicId'),
			language_id: ViiKii.Util.get(this, 'languageId'),
			content_type: 'T'}).toQueryString();
			
		var ajax = new Ajax.RequestXML(
			'/topics/add_description/',
			{
				asynchronous: false,
				parameters: params
			}
		);
		this.onSuccessSave(ajax);
	},
	onSuccessSave: function(ajax) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.closeEditor();
			ViiKii.Topic.New.updateContents.bind(ViiKii.Topic.New);
			ViiKii.Topic.New.updateContents();
			return;
		}
		switch(response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			return;
		case 'EMPTY_INPUT':
			alert("Insert available contents first.");
			return;
		case 'EMPTY_LANGUAGE':
			alert("Select available language first.");
			return;
		case 'EMPTY_TITLE':
			alert("Insert available title first.");
			return;
		case 'EMPTY_CONTENT':
			alert("Insert available content first.");
			return;
		case 'DB_ERROR':
			alert('Fail to translate topic description!\nPlease try again!.');
			return;
		case 'OUT_OF_LENGTH':
			alert("The content is out of length.");
			return;
		}
	},
	discard: function() {
		ViiKii.Topic.Editor.Main.Translation.closeEditor();
		ViiKii.Topic.New.updateContents.bind(ViiKii.Topic.New);
		ViiKii.Topic.New.updateContents();
	},
	selectLanguage: function(componentId, languageId) {
		var languages = ViiKii.Topic.Editor.getTranslateLanguages(ViiKii.Util.get(this, 'originalLanguage'));
		for(var i=0; i<languages.length; i++) {
			if(languages[i] == languageId) {
				$(componentId+".language_"+languages[i]).src = "/common/bullet_on18.gif";
			} else {
				$(componentId+".language_"+languages[i]).src = "/common/bullet_off18.gif";
			}
		}
		ViiKii.Util.set(this, 'languageId', languageId);
		//this.setLanguage(languageId);
	},
	showEditor: function(uploadUrl) {
		var languages = ViiKii.Topic.Editor.getTranslateLanguages(ViiKii.Util.get(this, 'originalLanguage'));
		var languagesTag = ViiKii.Topic.Editor.getLanguagesTag('translation', "ViiKii.Topic.Editor.Main.Translation.selectLanguage", languages, 0);
		$("ViiKii.Topic.New.Main.Translation.languageSelector").innerHTML = languagesTag;
		
		ViiKii.Util.set(this, 'languageId', languages[0]);
		
		var uploadUrl = uploadUrl+'?type=TOPIC_DESCRIPTION&user_name='+ViiKii.Util.getDomainCookie('username');
		ViiKii.Editor.openEditor('ViiKii.Topic.New.Main.Translation.editor', this.getContentHeight(), '', uploadUrl);
		var content = $('ViiKii.Topic.New.Main.Translation.content').innerHTML;
		ViiKii.Editor.setContent(content);
	},
	getContentHeight: function() {
		var contentHeight = Element.getHeight('ViiKii.Topic.New.Main.Translation.content');
		if(contentHeight < 36) {
			return 36;
		}
		return contentHeight;
	},
	closeEditor: function() {
		ViiKii.Editor.closeEditor();
	}
};
ViiKii.Topic.Editor.Main.Edit = {
	objectId: 'ViiKii.Topic.Editor.Main.Edit',
	save: function() {
		var title = $("ViiKii.Topic.Editor.Main.Edit.title").value;
		var content = ViiKii.Editor.getEditorContent();
		var message = "title: "+title+"\n";
		message += "language: "+ViiKii.Util.get(this, 'languageId')+"\n";
		message += "content: "+content+"\n";
		message += "description id: "+ViiKii.Util.get(this, 'descriptionId')+"\n";
		//alert(message);
		var params = $H(
			{
				title:	title,
				content: content,
				topic_id: ViiKii.Util.get(this, 'topicId'),
				language_id: ViiKii.Util.get(this, 'languageId'),
				content_type: 'E',
				description_id: ViiKii.Util.get(this, 'descriptionId')
			}
		).toQueryString();
			
		var ajax = new Ajax.RequestXML(
			'/topics/add_description/',
			{
				asynchronous: false,
				parameters: params
			}
		);
		this.onSuccessSave(ajax);
	},
	onSuccessSave: function(ajax) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.closeEditor();
			ViiKii.Topic.New.updateContents.bind(ViiKii.Topic.New);
			ViiKii.Topic.New.updateContents();
			return;
		}
		switch(response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			return;
		case 'EMPTY_INPUT':
			alert("Insert available contents first.");
			return;
		case 'EMPTY_LANGUAGE':
			alert("Select available language first.");
			return;
		case 'EMPTY_TITLE':
			alert("Insert available title first.");
			return;
		case 'EMPTY_CONTENT':
			alert("Insert available content first.");
			return;
		case 'DB_ERROR':
			alert('Fail to translate topic description!\nPlease try again!.');
			return;
		case 'INVALID_DESCRIPTION':
			alert("This content is deleted.");
			return;
		case 'NOT_OWNER':
			alert("You are not the owner of this content");
			return;
		case 'OUT_OF_LENGTH':
			alert("The content is out of length.");
			return;
		}
	},
	discard: function() {
		ViiKii.Topic.Editor.Main.Edit.closeEditor();
		ViiKii.Topic.New.updateContents.bind(ViiKii.Topic.New);
		ViiKii.Topic.New.updateContents();
	},
	selectLanguage: function(componentId, languageId) {
		var languages = ViiKii.Topic.Editor.getEditLanguages(ViiKii.Util.get(this, 'oldLanguage'), ViiKii.Util.get(this, 'originalLanguage'));
		for(var i=0; i<languages.length; i++) {
			if(languages[i] == languageId) {
				$(componentId+".language_"+languages[i]).src = "/common/bullet_on18.gif";
			} else {
				$(componentId+".language_"+languages[i]).src = "/common/bullet_off18.gif";
			}
		}
		ViiKii.Util.set(this, 'languageId', languageId);
	},
	showEditor: function(uploadUrl) {
		var oldLanguage = ViiKii.Util.get(this, 'oldLanguage');
		var languages = ViiKii.Topic.Editor.getEditLanguages(oldLanguage, ViiKii.Util.get(this, 'originalLanguage'));
		var oldLanguageIndex = languages.indexOf(oldLanguage);
		var languagesTag = ViiKii.Topic.Editor.getLanguagesTag('edit', "ViiKii.Topic.Editor.Main.Edit.selectLanguage", languages, oldLanguageIndex);
		$("ViiKii.Topic.Editor.Main.Edit.languageSelector").innerHTML = languagesTag;
		
		ViiKii.Util.set(this, 'languageId', oldLanguage);
		
		var uploadUrl = uploadUrl+'?type=TOPIC_DESCRIPTION&user_name='+ViiKii.Util.getDomainCookie('username');
		ViiKii.Editor.openEditor('ViiKii.Topic.Editor.Main.Edit.editor', this.getContentHeight(), '', uploadUrl);
		var content = $('ViiKii.Topic.Editor.Main.Edit.content').innerHTML;
		ViiKii.Editor.setContent(content);
	},
	getContentHeight: function() {
		var contentHeight = Element.getHeight('ViiKii.Topic.Editor.Main.Edit.content');
		if(contentHeight < 36) {
			return 36;
		}
		return contentHeight;
	},
	closeEditor: function() {
		ViiKii.Editor.closeEditor();
	}
};
ViiKii.Topic.Editor.Reply = {
	objectId: 'ViiKii.Topic.Editor.Reply',
	lastComponentId: null,
	newComponentId: null,
	newContentInfos: new Object(),
	editorComponentId: null,
	contentInfos: new Object(),
	isLogin: function() {
		return ViiKii.Util.getDomainCookie('username') !== null;
	},
	setNewEditor: function(componentId, contentType, reffer, depth, originalLanguage) {
		this.newComponentId = componentId;
		this.newContentInfos = {
			'content_type': contentType,
			'reffer': reffer,
			'depth': depth
		};
	},
	showNewEditor: function() {
		if($(this.newComponentId)) {
			this.showEditor(this.newComponentId, this.newContentInfos.content_type, this.newContentInfos.reffer, this.newContentInfos.depth, '');
		}
	},
	showEditor: function(componentId, contentType, reffer, depth, originalLanguage) {
		if((this.newComponentId != componentId) && !this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}
		if(ViiKii.Editor.isOpened) {
			if(ViiKii.Editor.closeCallback) {
				if(!ViiKii.Editor.closeCallback()) {
					return;
				}
			}
		}
		this.lastComponentId = componentId;
		
		ViiKii.Editor.setCloseCallback(this.onCloseEditor.bind(this));
		ViiKii.Editor.isOpened = true;
		this.editorComponentId = componentId;
		
		this.contentInfos[componentId] = {
			'content_type': contentType,
			'reffer': reffer,
			'depth': depth
		};
		Element.show(componentId);
		var languages;
		if(contentType == 'E') {
			languages = [originalLanguage];
		} else {
			languages = ViiKii.Topic.Editor.getTranslateLanguages(originalLanguage);
		}
		var languagesTag = ViiKii.Topic.Editor.getLanguagesTag(componentId, "ViiKii.Topic.Editor.Reply.selectLanguage", languages, 0);
		$(componentId+".languageSelector").innerHTML = languagesTag;
		
		if(contentType == 'T') {
			$(componentId+".message").innerHTML = "Translate into";
		} else {
			$(componentId+".message").innerHTML = "Leave your comment here."
		}
		
		if(languages.length == 1 && contentType != 'O') {
			this.selectLanguage(componentId, languages[0]);
		} else {
			this.setLanguage(componentId, languages[0]);
			var editorHeight = 71;
			$(componentId+".boundary").style.height = (editorHeight + this.getContentHeight(contentType, reffer))+'px';
		}
	},
	closeLastEditor: function() {
		if(this.lastComponentId) {
			this.closeEditor(this.lastComponentId);
			this.showNewEditor();
		}
	},
	getContentHeight: function(contentType, reffer) {
		if(contentType == 'T' || contentType == 'E') {
			var contentHeight = Element.getHeight("editor_content_"+reffer);
			if(contentHeight < 36) {
				return 36;
			}
			return contentHeight;
		}
		return 129;
	},
	selectLanguage: function(componentId, languageId) {
		this.setLanguage(componentId, languageId);
		if(!this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}
		Element.hide(componentId+'.boundary');
		Element.show(componentId+'.editor');
		
		var contentType = this.contentInfos[componentId].content_type;
		var reffer = this.contentInfos[componentId].reffer;
		
		var content = '';
		if(contentType == 'T' || contentType == 'E') {
			content = $("editor_content_"+reffer).innerHTML;
		}
		var uploadUrl = ViiKii.Util.get(this, 'uploadUrl')+'?type=TOPIC_REPLY&user_name='+ViiKii.Util.getDomainCookie('username');
		ViiKii.Editor.openEditor(componentId+'.editorContent', this.getContentHeight(contentType, reffer), '', uploadUrl);
		ViiKii.Editor.setContent(content);
	},
	setLanguage: function(componentId, languageId) {
		this.contentInfos[componentId].language_id = languageId;
	},
	discard: function(componentId) {
		this.closeEditor(componentId);
		this.showNewEditor();
	},
	closeEditor: function(componentId) {
		ViiKii.Editor.closeEditor();
		if($(componentId)) {
			Element.hide(componentId);
			Element.show(componentId+'.boundary');
			Element.hide(componentId+'.editor');
		}
	},
	save: function(componentId) {
		var content = ViiKii.Editor.getEditorContent();
		this.contentInfos[componentId].content = content;
		this.contentInfos[componentId].topic_id = ViiKii.Util.get(this, 'topicId');
		
		var message = "";
		message += "reply_id: "+componentId+"\n";
		message += "topic_id: "+this.contentInfos[componentId].topic_id+"\n";
		message += "content_type: "+this.contentInfos[componentId].content_type+"\n";
		message += "reffer: "+this.contentInfos[componentId].reffer+"\n";
		message += "depth: "+this.contentInfos[componentId].depth+"\n";
		message += "language: "+this.contentInfos[componentId].language_id+"\n";
		message += "content: "+this.contentInfos[componentId].content+"\n";
		//alert(message);
		
		var params = $H(this.contentInfos[componentId]).toQueryString();
		var ajax = new Ajax.RequestXML(
			'/topics/add_reply/',
			{
				asynchronous: false,
				parameters: params
			}
		);
		this.onSuccessSave(ajax, componentId);
	},
	onSuccessSave: function(ajax, componentId) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			var contentType = this.contentInfos[componentId].content_type;
			this.closeEditor(componentId);
			if(contentType == 'O' || contentType == 'R') {
				ViiKii.Topic.New.Reply.refreshReplies.bind(ViiKii.Topic.New.Reply);
				ViiKii.Topic.New.Reply.refreshReplies();
			} else {
				ViiKii.Topic.New.Reply.refreshReply.bind(ViiKii.Topic.New.Reply);
				ViiKii.Topic.New.Reply.refreshReply(response.origin);
			}
			alert("Saved successfully!");
			return true;
		}
		switch(response.error) {
		case 'EMPTY_INPUT':
			alert("Insert available reply first.");
			break;
		case 'DB_ERROR':
			alert("Fail to save. Please try again!");
			break;
		case 'ORIGIN_DELETED':
			alert("Original post was deleted by owner.");
			break;
		case 'UNKNOWN_TYPE':
			alert("Unknown content type!");
			break;
		case 'TOO_MUCH_DEPTH':
			alert("Too much depth");
			break;
		case 'OUT_OF_LENGTH':
			alert("The content is out of length.");
			return;
		}
		return false;
	},
	isEditorVisible: function(componentId) {
		if(!$(componentId)) {
			return false;
		}
		if($(componentId).style.display != 'none') {
			return true;
		}
		if($(componentId+".editor").style.display != 'none') {
			return true;
		}
		return false;
	},
	onCloseEditor: function() {
		if(ViiKii.Editor.isEditorOpened && this.isEditorVisible(this.editorComponentId)) {
			if(confirm("Do you want to save the post?")) {
				if(this.save(this.editorComponentId)) {
					return false;
				}
				return false;
			} else {
				this.closeEditor(this.editorComponentId);
				return true;
			}
		}
		this.closeEditor(this.editorComponentId);
		return true;
	}
};
ViiKii.Topic.Latest = {
	loadPage: function(curPage) {
		new Ajax.Updater(
			'ViiKii.Topic.LatestTopic.layer',
			'/topics/latest_topics/'+curPage,
			{
				evalScripts: true
			}
		);
	}
};
ViiKii.Topic.LatestChannel = {
	loadPage: function(curPage) {
		new Ajax.Updater(
			'latest_channels_layer',
			'/topics/latest_channels/'+curPage,
			{
				evalScripts: true
			}
		);
	}
};
ViiKii.Topic.Main = {
	update: function() {
		ViiKii.Topic.Latest.loadPage(1);
		ViiKii.Topic.LatestChannel.loadPage(1);
	}
};
ViiKii.Topic.ChannelList = {
	loadPage: function(curPage) {
		new Ajax.Updater(
			'topic_channel_list',
			'/topics/channel_list/'+$('topic_id').value+'/'+curPage,
			{ evalScripts: true }
		)
	}
};
ViiKii.TranslateDetails = {
	_videoId: 0,
	_category: null,
	_metaId: 0,
	_language: '',
	isEditing: false,
	sortOn: 'R',
	starBox: null,
	background: '',
	videoId: 0,
	isLogin: function() {
		return ViiKii.Util.getDomainCookie('username') != null;
	},
	flashGotoPage: function() {
		if(Object.isUndefined(ViiKii.Video) || Object.isNull(ViiKii.Video.getId())) {
			return;
		}
		this.init();
		document.location = '/metas/init/' + ViiKii.Video.getId();
	},
	init: function() {		this.sortOn = 'R';
		this.isEditing = false;
	},
	update: function() {
		var response = new Ajax.Updater(
			'ViiKii.TranslateDetails.title',
			'/metas/video_title/' + this.videoId,
			{
				asynchronous: true,
				evalScripts: false,
				parameters: null,
				onFailure: function(transport) {
					alert(transport.responseText);
				}
			}
		);
		this.showList(this.sortOn);
	},
	showList: function(sortOn) {
		this.sortOn = sortOn;
		var response =	new Ajax.Request(
							'/metas/listing/' + this.videoId + '/' + sortOn + '/' + this.background,
							{
								asynchronous: true,
								evalScripts: true,
								parameters: null,
								onSuccess: this.onCompleteLoadList.bind(this)
							}
						);
	},
	onCompleteLoadList: function(transport) {
		$("TranslateDetailsList").innerHTML = transport.responseText;
		this.isEditing = false;
	},
	onRating: function(starBox, params) {
		ViiKii.TranslateDetails.starBox = starBox;
		var url = '/metas/rating/' + params + '/' + starBox.getPoint();
		var response = new Ajax.Request(
			url,
			{
				asynchronous: true,
				evalScripts: false,
				parameter: null,
				onSuccess: function(transport) {
					if (transport.responseText.isNum()) {
						ViiKii.TranslateDetails.starBox.set(transport.responseText);
					}
				},
				onFailure: function(transport) {
					alert(transport.responseText);
				}
			}
		);
	},
	clickCell: function(event) {
		if(!this.isLogin()) {
			ViiKii.Login.popUp();
			return;
		}

		var source = Event.element(event);
		var sourceId = source.id.split("_");
		
		this._category = sourceId[1];
		if (this._category == 'title' || this._category == 'subhead' || this._category == 'synopsis') {
			this._videoId = sourceId[2];
		} else {
			this._metaId = sourceId[2];
		}
		this._language = sourceId[3];
		
		if (this.isLogin() && sourceId[0] == 'cell') {
			this.editCell(source.id);
		} else if (sourceId[0] == 'revision') {
			this.revision(this._category, sourceId[2], sourceId[3]);
		} else if (this.isLogin() && sourceId[0] == 'save') {
			this.saveText();
		} else if (this.isLogin() && sourceId[0] == 'cancel') {
			this.onCancelSave();
		}
	},
	revision: function(category, id, language) {
		if(!this.isEditing) {
			ViiKii.TranslateDetails.Popup.open(category, id, language);
		}
	},
	editCell: function(cellId) {
		if(this.isEditing) {
			return;
		}
		this.editableCell.onKeyEnterDown = "ViiKii.TranslateDetails.saveText()";
		this.editableCell.onKeyESCDown = "ViiKii.TranslateDetails.onCancelSave()";
		this.editableCell.editCell(cellId);
		this.isEditing = true;
	},
	createTag: function(metaId, language, tag) {
		var frm = $('tagFrm');
		frm['data[Tag][video_id]'].value = ViiKii.TranslateDetails.videoId;
		frm['data[Tag][meta_id]'].value = metaId;
		frm['data[Tag][language_id]'].value = language;
		frm['data[Tag][tag]'].value = tag;
		return frm;
	},
	addTag: function(metaId, language, tag) {
		var requestFrm = this.createTag(metaId, language, tag);
		var url = '/metas/add_tag/';
		var ajax = new Ajax.RequestXML(
			url,
			{
				asynchronous: false,
				method: 'post',
				parameters: Form.serialize(requestFrm)
			}
		);
		return ajax.responseValue.response;
	},
	addMeta: function(type) {
		var param = "data[Meta][video_id]="+this.videoId;
		param += "&data[Meta][type]="+type;
		var xml = new Ajax.RequestXML(	'/metas/add_meta/',
										{	asynchronous: false,
											method: 'post',
											parameters: param
										});

		this.onSuccessAddMeta(xml);
	},
	onSuccessAddMeta: function(xml) {
		var response = xml.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.update();
			return;
		}
		switch(response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'INVALID_VIDEO':
			alert("Sorry!\nThis video was deleted while you are watching it.");
			document.location = '/';
			break;
		case 'NOT_OWNER':
		case 'EMPTY_INPUT':
		case 'TOO_MANY_META':
			this.update();
			break;
		}
	},
	getCategory: function() {
		return this._category;
	},
	getVideoId: function() {
		return this._videoId;
	},
	getMetaId: function() {
		return this._metaId;
	},
	getLanguage: function() {
//		return cellId.split("_")[3];
		return this._language;
	},
	saveText: function() {
		if(!this.isEditing) {
			return;
		}
		var inputText = this.editableCell.getTextAreaText();
		inputText = inputText.trim();
		inputText = inputText.split("<BR>").join("");
		inputText = inputText.split("<br>").join("");
		if(inputText == "") {
			this.onCancelSave();
			return;
		}
		
		if (inputText.getBytes() > 255) {
			alert('up to 255 characters');
			this.cancelSave();
			return;
		}
		
		var res = '';
		switch (this.getCategory()) {
		case 'title':
				res = ViiKii.Title.add(this.getVideoId(), this.getLanguage(), inputText);
				break;
			case 'subhead':
				res = ViiKii.Subhead.add(this.getVideoId(), this.getLanguage(), inputText);
				break;
			case 'synopsis':
				res = ViiKii.Synopsis.add(this.getVideoId(), this.getLanguage(), inputText);
				break;
			case 'tag':
				res = this.addTag(this.getMetaId(), this.getLanguage(), inputText);
				break;
		}
		if (res.result == 'SUCCESS') {
			this.update();
		} else {
			this.onError(res.error);
		}
	},
	onError: function(err) {
		switch (err) {
		case 'INVALID_VIDEO':
			alert("Sorry!\nThis video was deleted while you are watching it.");
			document.location = '/';
			break;
		case 'DUPLICATED':
			alert("Somebody already posted the same sentence as yours.");
			ViiKii.TranslateDetails.onCancelSave();
			break;
		case 'NOT_LOG_IN':
			ViiKii.TranslateDetails.onCancelSave();
			ViiKii.Login.popUp();
			break;
		case 'DB_ERROR':
			alert("Fail to add.");
			break;
		}
	},
	onSaveText: function(revision) {
		var inputText = this.editableCell.getTextAreaText();
		this.editableCell.setText(inputText, this.editableCell.getTagId(), revision);
		this.isEditing = false;
	},
	onCancelSave: function() {
		this.editableCell.cancelEdit();
		this.isEditing = false;
	},
	editableCell: new ViiKii.UI.EditableCell()
};
ViiKii.TranslateDetails.Popup = {
	version: '0.1',
	name: 'ViiKii.TranslateDetails.Popup',
	videoId: 0,
	metaId: 1,
	language: 'en',
	orderBy: 'T',
	inOrder: true,
	popUpLayerName: 'ViiKii.TranslateDetails.Popup',
	scrollBar: null,
	_layerShadow: null,
	_revisionPopupLayerId: 'revision_popup_layer',
	_category: '',
	_videoId: null,
	_language: null,
	
	getCategory: function() {
		return this._category;
	},
	getVideoId: function() {
		return this._videoId;
	},
	getLanguage: function() {
		return this._language;
	},
	open: function(category, id, language) {
		var urls = {title: '/titles/revisions', subhead: '/subheads/revisions', synopsis: '/synopses/revisions', tag: '/metas/popup'};
		this._category = category;
		this.metaId = id;
		this.language = language;
		this._language = language;
		this._videoId = id;
		this.orderBy = 'T';
		this.inOrder = true;
		var response = new Ajax.Request(urls[category] + '/'+ id + '/' + this.language, {
				asynchronous: false, evalScripts: true, parameters: null}
			);
		this.doneOpen(response.transport);
	},
	doneOpen: function(transport) {
		var layer = this.createPopupLayer();
		layer.update(transport.responseText);
		ViiKii.UI.Round.init(layer, {corner:'all', borderSize:1});
		this._layerShadow = new ViiKii.UI.Shadow(layer);
		DragHandler.attach(this._layerShadow.container, $('revision_caption_div'));
	},
	createPopupLayer: function() {
		this._revisionPopupLayerId = 'revision_popup_layer';
		if (!$('revision_popup_layer')) {
			var left = (document.body.scrollWidth - 618) / 2;
			var top = Position.realOffset(document.body)[1] + 150;
			var styles = {
				position: 'absolute',
				top: top + 'px',
				left: left + 'px',
				width: '672px',
				height: '521px',
				'background-color': '#ffffff'
			};
			var e = document.createElement('div');
			e.id = 'revision_popup_layer';
			Element.setStyle(e, styles);
			document.getElementsByTagName('body')[0].appendChild(e);
		}
		return $('revision_popup_layer');
	},
	close: function() {
		document.getElementsByTagName('body')[0].removeChild($(this._layerShadow.container));
		this._shadow = null;
	},
	save: function(text) {
		if (text.value.getBytes() > 255) {
			alert('up to 255 characters');
			text.select();
			return;
		}
		
		var response = null;
		switch (this._category) {
		case 'title':
			response = ViiKii.Title.add(this._videoId, this._language, text.value);
			break;
		case 'subhead':
			response = ViiKii.Subhead.add(this._videoId, this._language, text.value);
			break;
		case 'synopsis':
			response = ViiKii.Synopsis.add(this._videoId, this._language, text.value);
			break;
		case 'tag':
			response = this.addTagFrm();
			break;
		}
		
		if ('SUCCESS' != response.result) {
			this.onError(response.error);
			return;
		}
		this.update(this._category, this._videoId, this._language);
		ViiKii.TranslateDetails.update();
	},
	update: function(category, id, language) {
		var urls = {title: '/titles/revisions', subhead: '/subheads/revisions', synopsis: '/synopses/revisions', tag: '/metas/popup'};
		var response = new Ajax.Request(urls[category] + '/'+ id + '/' + this.language, {
			asynchronous: false, evalScripts: true, parameters: null}
		);
		$(this._revisionPopupLayerId).update(response.transport.responseText);
		ViiKii.UI.Round.init($(this._revisionPopupLayerId), {corners:'all', borderSize:1});
		DragHandler.attach(this._layerShadow.container, $('revision_caption_div'));
	},
	remove: function(id) {
		if (confirm('Do you really want to delete this subhead?')) {
			var res = null;
			switch (this._category) {
			case 'title':
				res = ViiKii.Title.remove(id);
				break;
			case 'subhead':
				res = ViiKii.Subhead.remove(id);
				break;
			case 'synopsis':
				res = ViiKii.Synopsis.remove(id);
				break;
			}
			if ('SUCCESS' != res.result) {
				this.onError(res.error);
				return;
			}
			this.update(this._category, this._videoId, this._language);
			ViiKii.TranslateDetails.update();
		}
	},
	rating: function(starBOX, params) {	//params[0]-video_id, params[1]-languageId, params[2]-id
		var res = null;
		switch (ViiKii.TranslateDetails.Popup.getCategory()) {
		case 'title':
			res = ViiKii.Title.rating(params[2], starBOX.getPoint());
			break;
		case 'subhead':
			res = ViiKii.Subhead.rating(params[2], starBOX.getPoint());
			break;
		case 'synopsis':
			res = ViiKii.Synopsis.rating(params[2], starBOX.getPoint());
			break;
		default:
			return;
		}
		if ('SUCCESS' != res.result) {
			ViiKii.TranslateDetails.Popup.onError(res.error);
			return;
		}
		ViiKii.TranslateDetails.Popup.update(ViiKii.TranslateDetails.Popup.getCategory(), 
				ViiKii.TranslateDetails.Popup.getVideoId(), ViiKii.TranslateDetails.Popup.getLanguage());
		ViiKii.TranslateDetails.update();
	},
	del: function(tagId) {
		if (!confirm('Do you really want to delete this subtitle?')) {
			return;
		}
		var xml = new Ajax.RequestXML(
			'/metas/del_tag/'+tagId,
			{
				asynchronous: false,
				method: 'post',
				parameters: null
			}
		);
		this.onDeleteTagSuccess(xml);
	},
	onDeleteTagSuccess: function(xml) {
		var response = xml.responseValue.response;
		if(response.result == 'SUCCESS') {
			this.refreshPopupList();
			ViiKii.TranslateDetails.update();
			return;
		}

		switch(response.error) {
		case 'INVALID_VIDEO':
			alert("Sorry!\nThis video was deleted while you are watching it.");
			document.location = '/';
			break;
		case 'NOT_EXIST':
			this.refreshPopupList();
			return;
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'NOT_OWNER':
			this.refreshPopupList();
			break;
		}
	},
	addTagFrm: function() {
		var requestFrm = $('popupTagFrm');
		if(requestFrm['data[Tag][tag]'].value == "") {
			return;
		}
		requestFrm['data[Tag][video_id]'].value = this.videoId;
		var url = '/metas/add_tag/';
		var xml = new Ajax.RequestXML(
			url,
			{
				asynchronous: false,
				method: 'post',
				parameters: Form.serialize(requestFrm)
			}
		);
		return xml.responseValue.response;
	},
	refreshPopupList: function() {
		var response = new Ajax.Request(
			'/metas/popup_listing/'+ this.metaId + "/" +this.language +"/" + this.orderBy +"/" + this.inOrder,
			{
				asynchronous: true,
				evalScripts: true,
				parameters: null,
				onSuccess: this.onCompleteLoadPopupList,
				onFailure: this.onErrorLoadPopupList
			}
		);
	},
	loadList: function(orderBy, inOrder) {
		this.orderBy = orderBy;
		this.inOrder = inOrder;
		this.refreshPopupList();
	},
	onCompleteLoadPopupList: function(transport) {
		$('TranslateDetailsPopupList').innerHTML = transport.responseText.stripScripts();
		transport.responseText.evalScripts();
		if(this.scrollBar != null) {
			this.scrollBar.update();
		}
	},
	onErrorLoadPopupList: function(event) {
		alert("load translate details popup list fail");
	},
	showComment: function(tagid, islogin) {
// alert('tagid='+tagid+', this.tagid='+this.tagid+', islogin='+islogin);
		this.islogin = islogin;
		if(typeof this.tagid != 'undefined' && this.tagid != tagid) {
			if($('detpop_post_'+this.tagid) != null) {
				Element.setStyle($('detpop_post_'+this.tagid), {display:'none'});
			}
		}
		this.deleteCancel();
		this.tagid = tagid;
		var e = $('detpop_post_'+tagid);
		var show = Element.getStyle(e, 'display');

		var styles = {
				width: '569px',
// height: '250px',
				display: (show=='none'?'block':'none')
			};
		Element.setStyle(e, styles);
		this.refreshComment(tagid, 1);
		this.scrollBar.update();
	},

	addComment: function(type, rid) {
		if(false == this.logIn()) {
			return;
		}
// alert('type='+type+', tagid='+rid);
		var frm = $('detpop_Input'+rid);

		var notWhiteSpace = new RegExp(/[^\s]/);
		var quotation = new RegExp(/\'/g);
		var backSlash = new RegExp(/\\/g);
		var urlLink	= new RegExp(/(http|https|ftp|telnet|news):\/\/([a-z0-9_\-]+\.[][a-zA-Z0-9:;&#@=_~%\?\/\.\,\+\-]+)/g);

		if (type != 'T') {
			if (!notWhiteSpace.test(frm['data[content]'].value)) {
				alert('Type the comment please!!');
				return;
			}

			if (backSlash.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value.replace(backSlash, "\\\\");
			}

			if (quotation.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value.replace(quotation, "\\\'");
			}

			if (urlLink.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value.replace(urlLink, "<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>");
			}
		}
		else {
			if (!notWhiteSpace.test(frm['data[translate]'].value)) {
				alert('Type the comment please!!');
				return;
			}

			if (backSlash.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value.replace(backSlash, "\\\\");
			}

			if (quotation.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value.replace(quotation, "\\\'");
			}

			if (urlLink.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value.replace(urlLink, "<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>");
			}
		}

		var ele = frm['data[language_id]'];
		if (ele.length) {
			for (i = 0; i < ele.length; i++) { if (ele[i].checked) { language_id = ele[i].value; } }
		}
		else {
			language_id = ele.value;
		}

		var params = 'data[category]=V'
				 + '&data[video_id]=' + ViiKii.TranslateDetails.Popup.videoId
				 + '&data[content_type]='+ type
				 + '&data[language_id]='+ language_id
				 + '&data[subtitle_id]=0'
				 + '&data[content]=' + encodeURIComponent(frm['data[content]'].value);
		var url = '/metas/add_comment/'+ rid;
		var xml = new Ajax.Request(url,	{
						asynchronous: false,
						method: 'post',
						parameters: params,
						onSuccess: this.onCallback,
						onFailure: this.onError
					});
	},

	showReply: function(type, id, language, depth, tagid) {
		if(false == this.logIn()) { return; }
		if (!this.isvideo()) { return; }
		var languages = ViiKii.Languages.getActiveInterestedLanguageCodes();

		var str = '';
		var radio_language =  '';
		var checked = 'checked';
		var value = '';
		var commenttype = '';
		var idx = '';
		var i;

		if(type == 'T') {
			var cnt = 0;
			for(i=0; i<languages.length; i++) {
				idx = languages[i];
				if (idx != language) {
					radio_language = '<input type="hidden" name="data[language_id]" id="rlbl" value="'+ idx +'" />\n';
					cnt++;
				}
			}
			if(cnt > 1) {
				radio_language = '	<div id="setLang'+ id +'" class="s_post" style="float:left; width:390px; height:18px; margin:2px 0 0 2px; background-color:#FFF;">\n<div style="float:left; margin-top:0px;">\n';
				for(i=0; i<languages.length; i++) {
					idx = languages[i];
					if (idx != language) {
						radio_language += '<input type="radio" name="data[language_id]" value="'+ idx +'" id="rlbl' + id + idx + '" onfocus="this.blur();" '+ checked +'/><label for="rlbl' + id + idx + '">'+ idx +'</label>\n';
						checked = '';
					}
				}
				radio_language += ' </div>\n'
							   +  '<div style="float:left; padding-top:2px;">\n'
							   +  '<span onclick="Element.setStyle($(\'setLang'+id+'\'), {display:\'none\'});" style="cursor:pointer; margin-left:20px; border:0px solid red;">[OK]</span>\n</div>\n</div>\n';
			}
		}
		else {
			radio_language = '	<div id="setLang'+ id +'" class="s_post" style="float:left; width:374px; height:18px; margin:2px 0 0 1px; background-color:#FFF;">\n<div style="float:left; margin-top:0px;">\n';
			for(i=0; i<languages.length; i++) {
				idx = languages[i];
				radio_language += '<input type="radio" name="data[language_id]" value="'+ idx +'" id="rlbl' + id + idx + '" onfocus="this.blur();" '+ checked +'/><label for="rlbl' + id + idx + '">'+ idx +'</label>\n';
				checked = '';
			}
			radio_language += ' </div>\n'
						   +  '<div style="float:left; padding-top:2px;">\n'
						   +  '<span onclick="Element.setStyle($(\'setLang'+id+'\'), {display:\'none\'});" style="cursor:pointer; margin-left:20px; border:0px solid red;">[OK]</span>\n</div>\n</div>\n';
		}

		str +=	'<form id="frmComment'+ id +'" onSubmit="return false;" style="margin:0px;">\n'
			+	'	<input type="hidden" name="data[page]" value="1" />\n'
			+	'	<input type="hidden" name="data[content_type]" id="content_type" value="'+ type.toUpperCase() +'" />\n'
			+	' 	<input type="hidden" name="data[category]" id="category" value="V" />\n';

		switch (type.toUpperCase()) {
		case 'Q' :
			value = 'Comment';	commenttype = '\'C\'';
			str += '	<input type="hidden" name="data[subtitle_id]" value="0"/>'
				+  '	<input type="hidden" name="data[video_id]" value="0"/>'
				+  '	<input type="hidden" name="data[tag_id]" value="'+tagid+'"/>\n'
				+  '	<div style="float:left; width:410px; height:20px; border;1px solid red;">\n'
				+  radio_language
				+  '	<textarea name="data[content]" id="add_content" style="width:404px; height:18px; overflow-y:auto; border:1px solid #888888;"></textarea>\n'
				+  '	</div>\n';
			break;
		case 'T' :
			value = 'Translate';	commenttype = '\'T\'';
			str += '	<input type="hidden" name="data[subtitle_id]" value="0"/>'
				+  '	<input type="hidden" name="data[video_id]" value="0"/>'
				+  '	<input type="hidden" name="data[tag_id]" value="'+tagid+'"/>\n'
				 + '	<div style="float:left; width:410px; height:20px; border;1px solid blue;">\n'
				 +  radio_language
				 + '	<textarea name="data[translate]" id="add_content" style="width:404px; height:18px; overflow-y:auto; border:1px solid #888888;" ></textarea>\n'
				 + '	</div>\n';
			break;
		case 'A' :
		case 'C' :
			value = 'Comment';	commenttype = '\'C\'';
			str += '	<input type="hidden" name="data[subtitle_id]" value="0"/>'
				+  '	<input type="hidden" name="data[video_id]" value="0"/>'
				+  '	<input type="hidden" name="data[tag_id]" value="'+tagid+'"/>\n'
				 + '	<div style="float:left; width:410px; height:20px; border;1px solid yellow;">\n'
				 + radio_language
				 + '	<textarea name="data[content]" id="add_content" style="width:404px; height:18px; overflow-y:auto; border:1px solid #888888;" ></textarea>\n'
				 + '	</div>\n';
			break;
		default :
			str = '';
			break;
		}
		str += '<div style="float:left;">\n'
			+  '	<div class="clsButtonReply" onclick="ViiKii.TranslateDetails.Popup.addReply($(\'frmComment'+ id +'\'), \''+ id +'\', '+ commenttype +');" style="margin-left:3px; padding-top:2px; height:18px;">'+ value +'</div>\n';
		if('Q' == type.toUpperCase()) {
			str += '	<div class="clsButtonReply" onclick="ViiKii.TranslateDetails.Popup.addReply($(\'frmComment'+ id +'\'), \''+ id +'\', \'A\');" style="margin-left:3px; padding-top:2px; height:18px;">Answer</div>\n';
		}

		str += '	<div class="clsButtonReply" onclick="ViiKii.TranslateDetails.Popup.removeTag('+id+');" style="margin-left:3px; padding-top:2px; height:18px;">Discard</div>\n'
			+  '</div>\n'
			+  '</form>\n';

		ele = $('subpost'+id);
		ele.innerHTML = str;
		Element.setStyle(ele, {display:'block'});
	},

	removeTag: function(id) {
		$('subpost'+id).removeChild($('frmComment'+ id));
		Element.setStyle($('subpost'+id), {display:'none'});
	},

	addReply : function(frm, rid, type) {
// alert(frm +', '+ rid +', '+ type);
		var notWhiteSpace = new RegExp(/[^\s]/);
		var quotation = new RegExp(/\'/g);
		var backSlash = new RegExp(/\\/g);
		var urlLink	= new RegExp(/(http|https|ftp|telnet|news):\/\/([a-z0-9_\-]+\.[][a-zA-Z0-9:;&#@=_~%\?\/\.\,\+\-]+)/g);

		if (type != 'T') {
			if (!notWhiteSpace.test(frm['data[content]'].value)) {
				alert('Type the comment please!!');
				return;
			}

			if (backSlash.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value.replace(backSlash, "\\\\");
			}

			if (quotation.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value.replace(quotation, "\\\'");
			}

			if (urlLink.test(frm['data[content]'].value)) {
				frm['data[content]'].value = frm['data[content]'].value.replace(urlLink, "<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>");
			}
		}
		else {
			if (!notWhiteSpace.test(frm['data[translate]'].value)) {
				alert('Type the comment please!!');
				return;
			}

			if (backSlash.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value.replace(backSlash, "\\\\");
			}

			if (quotation.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value.replace(quotation, "\\\'");
			}

			if (urlLink.test(frm['data[translate]'].value)) {
				frm['data[translate]'].value = frm['data[translate]'].value.replace(urlLink, "<a href=\"$1://$2\" target=\"_blank\">$1://$2</a>");
			}
		}

// this.showPost(false);
		if (typeof type != 'undefined') {
			frm['data[content_type]'].value = type.toUpperCase();
		}
		var url = '/metas/add_reply/' + (typeof rid == 'undefined' ? '' : rid);
		var param = frm.serialize();

		var response = new Ajax.Request( url, {
					asynchronous: false,
					parameters: param,
					onSuccess: this.onCallback,
					onFailure: this.onError
				});
	},

	deleteMessage: function(id, type, tagid) {
// alert('id='+id+' type='+type+' tagid='+tagid);
		this.deleteCancel();
		if(false == this.logIn()) {	return;	}
		if (!this.isvideo()) { return; }

		ele = type.toLowerCase() + '_del' + id;
		var position = Position.positionedOffset($(ele));

		var str = '<div id="td_msg" style="">'
			 + '	<div style="width:300px; height:15px;"><img src="/common/close.gif" style="cursor:pointer;" border="0" align="right" onclick="ViiKii.Board.deleteCancel();"></div>'
			 + '	<div style="width:280px; height:15px; padding-left:20px; text-align:left;">Do you really want to delete this message?</div>'
			 + '	<div style="width:280px; height:15px;"></div>'
			 + '	<div style="width:300px; height:30px;">'
			 + '		<div style="float:left;height:30px;width:140px;margin:0 12 0 0;text-align:center;"><a href="javascript:ViiKii.TranslateDetails.Popup.deleteComment('+ id +', \''+ type +'\', '+ tagid +');">yes</a></div>'
			 + '		<div style="float:left;height:30px;width:140px;text-align:left;"><a href="javascript:ViiKii.TranslateDetails.Popup.deleteCancel();">cancel</a></div>'
			 + '	</div>'
			 + '</div>'
			 + '';

		$('del_msg'+tagid).innerHTML = str;
		Element.setStyle($('del_msg'+tagid), {left:position[0]-300+'px', top:position[1]+'px', border:'1px solid gray', display:'block'});
	},

	deleteComment: function(rid, type, tagid) {
// alert('rid='+rid+', type='+type+', tagid='+tagid);
		var param = '';
		param += 'data[tag_id]='+ tagid;

		var url = '/metas/delete_comment/'+ (typeof rid == 'undefined' ? '' : rid) +'/'+ type;
		Element.setStyle($('del_msg'+tagid), {display:'none'});
		var reponse = new Ajax.Request( url, {
					asynchronous: true,
					evalScripts: true,
					parameters: param,
					onSuccess: this.onCallback,
					onFailure: this.onError
				});
	},

	deleteCancel: function() {
		if($('td_msg') != null) {
			$('del_msg'+this.tagid).removeChild($('td_msg'));
		}
		Element.setStyle($('del_msg'+this.tagid), {display:'none'});
	},

	refreshComment: function(tagid, pageNum) {
		var url = '/metas/popup_comment/'+ tagid +'/'+ pageNum;
		var rtn1 = new Ajax.Updater('detpop_post_'+tagid, url, {
				asynchronous: true,
				evalScripts: true,
				parameters: null
			});
		var rtn2 = new Ajax.Updater('detpop_count_'+tagid, '/metas/popup_count/'+ tagid, {
				asynchronous: true,
				evalScripts: true,
				parameters: null
			});

		if(this.scrollBar != null) {
			this.scrollBar.update();
		}
	},

	rateComment : function(thumb, id, rate, cat) {
// alert(thumb +','+ id +','+ rate +','+ cat);
		if(false == this.logIn()) {	return;	}
		if (!this.isvideo()) { return; }

		cat = (!cat) ? 'V' : cat.toUpperCase();
		var container = cat.toLowerCase() + '_rate' + id;
		container = (!container) ? cat.toLowerCase() + '_rate' + id : container;
		var response = new Ajax.Updater(container, '/metas/rate_comment/'+ cat +'/'+ id +'/'+ thumb +'/'+ rate, {asynchronous:true, evalScripts:true});
	},

	showTrans: function(id) {
		var e = $('TransMore'+id);
		var show = Element.getStyle(e, 'display');
		Element.setStyle(e, {display:(show=='none'?'block':'none')});
	},

	loadPage: function(pageNum, tagid) {
		this.refreshComment(tagid, pageNum);
	},

	onCallback: function(trasnport) {
// alert(trasnport.responseText);
// var arrayToken = trasnport.responseText.split(',', 3);
		ViiKii.TranslateDetails.Popup.refreshComment(trasnport.responseText, 1);
	},

	logIn: function() {
		if(this.islogin) {
			return true;
		}
		else {
			alert('Not logined!!');
			return false;
		}
	},
	isvideo: function(callback) {
		var xml = new Ajax.Request('/videos/isvideo/'+this.videoId, {asynchronous: false});
		var rtn = xml.transport.responseText;
		if (!rtn) {
			setTimeout(function(){alert("Sorry!\nThis video was deleted while you are watching it."); document.location = '/';}, 100);
			return false;
		}
		else {
			return true;
		}
	},
	onError: function(err) {
		switch(err) {
		case 'INVALID_VIDEO':
			alert("Sorry!\nThis video was deleted while you are watching it.");
			document.location = '/';
			break;
		case 'DUPLICATED':
			alert("Somebody already posted the same sentence as yours.");
			break;
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'DB_ERROR':
			alert("Fail to add tag.");
		case 'LAST_ONE':
			alert("Sorry!\nThis title is last one. cannot delete");
			break;
		}
	}
};
ViiKii.User = {
	logout : function() {
		var url = '/logout';
		var response = new Ajax.Request(url, {
			asynchronous : true,
			evalScripts : false,
			parameters : null,
			onFailure : function(transport) {
				alert(transport.responseText);
			},
			onSuccess : function(transport) {
				document.location.reload();
			}
		});
	}
};

ViiKii.User.Manage = {
	loadPage : function(curPage) {
		new Ajax.Updater('manage_content', '/users/listing/' + curPage, {
			evalScripts : true
		});
	}
};

ViiKii.User.Form = {
	_name : 'ViiKii.User.Form',
	_version : '0.1',
	_validatedUserName : false,
	_validatedEmail : false,
	_validatedPassword : false,
	_validatedVerifyPassword : false,
	_validatedCode : false,
	_alt : null,
	languageLayerIds : [ 'first-language', 'second-language', 'third-language',
			'fourth-language', 'fithd-language' ],
	_selectedLanguageIds : [],
	_curLanguageBoxIdx : 0,
	_userName : '',
	_error : '',

	init : function() {
		this._alt = ViiKii.UI.AltPool.create();
		var userNameObserver = new Form.Element.Observer('userName', 1, ViiKii.User.Form.checkUserName);
		var emailObserver = new Form.Element.Observer('email', 1, ViiKii.User.Form.checkEmail);
		var passwordObserver = new Form.Element.Observer('password', 1, ViiKii.User.Form.checkPassword);
		var verifyObserver = new Form.Element.Observer('verifyPassword', 1, ViiKii.User.Form.verifyPassword);
		this._selectedLanguageIds = [];
		this._curLanguageBoxIdx = 0;
		this._validatedUserName = false;
		this._validatedEmail = false;
		this._validatedPassword = false;
		this._validatedVerifyPassword = false;
		this._validatedCode = false;
	},
	getSelectedLanguages : function() {
		return this._selectedLanguageIds;
	},
	alt : function(element, msg) {
		var position = Position.positionedOffset($(element));
		ViiKii.User.Form._alt.alt(position[0] + 100, position[1] - 26, msg);
	},
	altUserName : function(msg) {
		this.alt('userName', msg);
	},
	altEmail : function(msg) {
		this.alt('email', msg);
	},
	altPassword : function(msg) {
		this.alt('password', msg);
	},
	altVerifyPassword : function(msg) {
		this.alt('verifyPassword', msg);
	},
	altSignCode : function(msg) {
		this.alt('code', msg);
	},
	checkUserName : function() {

		var userName = $('userName').value.trim();
		if (!userName.isAlnum()) {
			ViiKii.User.Form._validatedUserName = false;
			ViiKii.User.Form.altUserName('only letters(a-z), numbers(0-9)');
			return;
		}

		var userNameLength = userName.length;
		if (userNameLength < 4) {
			ViiKii.User.Form._validatedUserName = false;
			ViiKii.User.Form.altUserName('too short!');
			return;
		}
		
		new Ajax.Request('/users_available/name/' + userName, {
			asynchronous : true,
			evalScripts: true,
			parameters: null,
			onComplete: function(transport, response) {
				if (response.available) {
					ViiKii.User.Form._validatedUserName = true;
					ViiKii.User.Form.altUserName('Available username!');
				} else {
					ViiKii.User.Form._validatedUserName = false;
					ViiKii.User.Form.altUserName('UnAvailable username!');
				}
			}
		});
	},
	checkEmail : function() {
		var email = $('email').value;
		if (!email.isEmail()) {
			ViiKii.User.Form._validatedEmail = false;
			ViiKii.User.Form.altEmail('Unavailable e-mail');
			return;
		}
		if (email.indexOf('@seznam.cz') != -1) {
			ViiKii.User.Form._validatedEmail = false;
			ViiKii.User.Form.altEmail('We do not support @seznam.cz. Please use other e-mail address.');
			return;
		}
		
		new Ajax.Request('/users_available/email/' + email, {
			asynchronous : true,
			evalScripts : true,
			parameters : null,
			onComplete: function(transport, response) {
				if (response.available) {
					ViiKii.User.Form.altEmail('Available e-mail!');
					ViiKii.User.Form._validatedEmail = true;
				} else {
					ViiKii.User.Form.altEmail('Already registered!');
					ViiKii.User.Form._validatedEmail = false;
				}
			}
		});
	},
	checkPassword : function() {
		var password = $('password').value;
		if (password.length < 4 || password.length > 20) {
			ViiKii.User.Form._validatedPassword = false;
			ViiKii.User.Form.altPassword('4 - 20 avilable!');
			return;
		}

		ViiKii.User.Form._alt.hidden();
		ViiKii.User.Form._validatedPassword = true;
	},
	verifyPassword : function() {
		var password = $('password').value;
		var verifyPassword = $('verifyPassword').value;

		if (!password.equals(verifyPassword)) {
			ViiKii.User.Form._validatedVerifyPassword = false;
			ViiKii.User.Form.altVerifyPassword('not the same as password!');
			return;
		}
		ViiKii.User.Form._alt.hidden();
		this._validatedVerifyPassword = true;
	},
	checkSignCode : function() {
		this.altSignCode('please try again');
		this.refreshSignCode();
	},
	refreshSignCode : function() {
		$('captcha').src = '/captcha?' + Math.round(Math.random(0) * 1000) + 1;
	},
	checkPreviousLanguage : function(index) {

		if (index == 0) {
			return true;
		}

		var position = [];
		var msg = [ 'Native language first!', 'Second language first!',
				'Third language first!', 'Fourth language first!',
				'Fith language first!' ];
		var element = [ 'first-language', 'second-language', 'third-language',
				'third-language', 'fithd-language' ];

		for ( var i = 0; i < index; i++) {
			if (Object.isUndefined(this._selectedLanguageIds[i])
					|| this._selectedLanguageIds[i].isEmpty()) {
				position = Position.positionedOffset($(element[i]));
				ViiKii.User.Form._alt.alt(position[0] + 140, position[1] - 26,
						msg[i]);
				window.scrollTo(0, 0);
				return false;
			}
		}

		return true;
	},
	openLanguageBox : function(idx) {
		this._curLanguageBoxIdx = idx;
		if (this.checkPreviousLanguage(idx)) {
			var position = Position
					.positionedOffset($(this.languageLayerIds[idx]));
			ViiKii.Languages.SelectBox.open(position[0], position[1] + 20,
					ViiKii.Languages.SelectBox.getUserChooseState());
		}
	},
	openFirstLanguage : function() {
		this.openLanguageBox(0);
	},
	openSecondLanguage : function() {
		this.openLanguageBox(1);
	},
	openThirdLanguage : function() {
		this.openLanguageBox(2);
	},
	openFourthLanguage : function() {
		this.openLanguageBox(3);
	},
	openFithdLanguage : function() {
		this.openLanguageBox(4);
	},
	setLanguage : function(id, language) {
		$(this.languageLayerIds[this._curLanguageBoxIdx]).innerHTML = language;
		this._selectedLanguageIds[this._curLanguageBoxIdx] = id;
	},
	signUp : function() {

		var frm = $('userForm');
		if (!this._validatedUserName) {
			frm['data[User][name]'].focus();
			this.checkUserName();
			return false;
		}
		ViiKii.User.Form._userName = frm['data[User][name]'].value;

		if (Object.isUndefined(this._selectedLanguageIds[0])) {
			this.checkPreviousLanguage(1);
			return false;
		}

		if (Object.isUndefined(this._selectedLanguageIds[1])) {
			this.checkPreviousLanguage(2);
			return false;
		}

		var interested = '';
		for ( var i = 0; i < this._selectedLanguageIds.length; i++) {
			interested += this._selectedLanguageIds[i] + ',';
		}
		interested = interested.substring(0, interested.length - 1);
		frm['data[User][interested]'].value = interested;

		if (!this._validatedEmail) {
			frm['data[User][email]'].focus();
			this.checkEmail();
			return false;
		}

		if (!this._validatedPassword) {
			frm['data[User][password]'].focus();
			this.checkPassword();
			return false;
		}

		this.verifyPassword();
		if (!this._validatedVerifyPassword) {
			frm['data[User][verify]'].focus();
			this.verifyPassword();
			return false;
		}

		var response = new Ajax.Request(
				'/users/join',
				{
					asynchronous : false,
					evalScripts : false,
					parameters : Form.serialize(frm),
					onFailure : this.onErrorSignUp,
					onSuccess : function(transport) {
						var err = transport.responseText;
						if (err.equals('1')) {
							document.location = '/users/noteSignUp/' + ViiKii.User.Form._userName;
						} else if (err.equals('-1')) {
							frm['data[User][code]'].focus();
							ViiKii.User.Form.checkSignCode();
						} else if (err.equals('-2')) {
							frm['data[User][name]'].focus();
							ViiKii.User.Form.checkUserName();
						} else if (err.equals('-3')) {
							frm['data[User][email]'].focus();
							ViiKii.User.Form.checkEmail();
						} else if (err.equals('-4')) {
							alert('send mail error');
							// reflash?
						} else if (err.equals('-5')) {
							alert('set language error');
							// reflash?
						} else {
							alert('unknown error');
							// reflash?
						}
					}
				});
	},
	onErrorSignUp : function(transport) {
		alert('error');
	}
};

ViiKii.UserForm = {
	_error : '',
	_alt : null,
	_currentLanguageChoiceBox : null,
	_getError : function() {
		return this._error;
	},
	_tooltip : function(element, msg) {
		if (null == this._alt) {
			this._alt = ViiKii.UI.AltPool.create();
		}
		var position = Position.positionedOffset($(element));
		this._alt.alt(position[0] + 100, position[1] - 26, msg);
	},
	_closeTooltip : function() {
		alert('_closeTooltip');
		if (null != this.alt) {
			alert('test');
			this._alt.hide();
		}
	},
	_isValidName : function(name) {
		if (name.trim().isEmpty()) {
			this._error = 'only letters(a-z), numbers(0-9)';
			return false;
		} else if (20 < name.length || name.length < 4) {
			this._error = '4-20 available';
			return false;
		} else if (!name.isAlnum()) {
			this._error = 'only letters(a-z), numbers(0-9)';
			return false;
		} else {
			return true;
		}
	},
	_isChoosePreviousLanguage : function(index) {

	},
	setLanguage : function(languageId, languageName) {
		if (this._currentLanguageChoiceBox) {
			this._currentLanguageChoiceBox.update(languageName);
		}
	},
	openLanguageBox : function(obj) {
		this._currentLanguageChoiceBox = obj;
		if (this._isChoosePreviousLanguage(this._currentLanguageChoiceBox
				.getAttribute('index'))) {
			var pos = Position.positionedOffset(obj);
			ViiKii.Languages.SelectBox.open(pos[0], pos[1] + 18,
					ViiKii.Languages.SelectBox.getUserChooseState());
		}
	},
	signUp : function(form) {
		this._closeTooltip();
		if (!this._isValidName($F(form.name))) {
			this._tooltip(form.name, this._getError());
			form.name.select();
			return false;
		} else if (false /* check languages */) {
			//TODO
}
}
};

ViiKii.User.Configure = {
	_alt : null,

	open : function(userName, type) {
		switch (type) {
		case 'notification':
			ViiKii.User.Configure.Notification.open(userName);
			break;
		case 'information':
			ViiKii.User.Configure.Info.open(userName);
			break;
		default:
			break;
		}
	},

	applySelectedTabStyle : function(tab) {
		var notificationTab = $('mys_config_notification_tab');
		notificationTab.style.border = "";
		notificationTab.style.borderBottom = "solid 1px #cccccc";

		var informationTab = $('mys_config_information_tab');
		informationTab.style.border = "";
		informationTab.style.borderBottom = "solid 1px #cccccc";

		tab.style.borderLeft = "solid 1px #cccccc";
		tab.style.borderTop = "solid 1px #cccccc";
		tab.style.borderRight = "solid 1px #cccccc";
		tab.style.borderBottom = "solid 0px #cccccc";
	},

	Info : {
		_userName : '',

		open : function(userName) {
			this._userName = userName;
			ViiKii.User.Configure
					.applySelectedTabStyle($('mys_config_information_tab'));
			this._alt = ViiKii.UI.AltPool.create();
			this._update();
		},

		_update : function() {
			var response = new Ajax.Updater('mys_config_layer',
					'/users/info/' + this._userName, {
						asynchronous : false,
						evalScripts : true,
						parameters : null,
						onFailure : function(transport) {
							alert(transport.responesText);
						}
					});
		},

		reload : function() {
			this._update();
		},

		save : function() {
			this._alt.close();
			var form = $('information_form');
			var email = form['data[User][email]'].value;
			if (!email.isEmail()) {
				this.alter(form['data[User][email]'], 'UnAvailable email!');
				return;
			}
			if (email.indexOf('@seznam.cz') != -1) {
				this
						.alter(form['data[User][email]'],
								'We do not support @seznam.cz. Please use other e-mail address.');
				return;
			}

			var password = form['data[User][password]'].value;
			var newPassword = form['data[User][newPassword]'].value;
			var verification = form['data[User][verifyPassword]'].value;
			if (!password.isEmpty() || !newPassword.isEmpty()) {
				if (newPassword.length < 4 || newPassword.length > 20) {
					this.alter(form['data[User][newPassword]'],
							'4 - 20 avilable!');
					return false;
				}

				if (newPassword.isAlpha() || newPassword.isNum()) {
					this.alter(form['data[User][newPassword]'],
							'Mix number and letter!');
					return;
				}

				if (!newPassword.equals(verification)) {
					this.alter(form['data[User][verifyPassword]'],
							'not the same as password!');
					return;
				}
			}

			new Ajax.Request('/users/saveInfo', {asynchronous: false, method: 'post', parameters : Form.serialize(form),
				onComplete: function(transport, response) {
					if (response.status == "success") {
						alert("saved information");
						if ("N" == response.verified_email) {
							document.location = "/users/form_email_confirm";
						}
					} else {
						switch (response.error) {
						case 'INVALID_PASSWORD':
							alert('Not the same Password as input Password');
							var form = $('information_form');
							form['data[User][password]'].select();
							break;
						case 'INVALID_IDENTITY':
							document.location = '/';
							break;
						case 'E_ALREADY_USED_EMAIL':
							alert('Email is already used by other user.');
							var form = $('information_form');
							form['data[User][email]'].select();
							break;
						case 'DB_ERROR':
							alert('Fail to save information');
							break;
						}
					}
				}
			});
		},
		cancel : function() {
			this._alt.close();
			$('information_form').reset();
		},

		alter : function(element, msg) {
			var position = Position.positionedOffset(element);
			this._alt.alt(position[0] + 100, position[1] - 20, msg);
		},

		_toggle : function(type) {
			var form = $('information_form');
			if (form['data[Profile][' + type + ']'].value == 1) {
				form['data[Profile][' + type + ']'].value = 0;
			} else {
				form['data[Profile][' + type + ']'].value = 1;
			}

			if (form['data[Profile][' + type + ']'].value == 1) {
				$('profile_' + type).src = '/common/private_open.gif';
			} else {
				$('profile_' + type).src = '/common/private.gif';
			}
		},

		toggleName : function() {
			this._toggle('is_name');
		},

		toggleNationality : function() {
			this._toggle('is_nationality');
		},

		toggleEmail : function() {
			this._toggle('is_email');
		}
	},

	Notification : {
		_userName : '',
		_options : null,
		_availables : [ 'R', 'D', 'N' ],

		open : function(userName) {
			this._userName = userName;
			ViiKii.User.Configure
					.applySelectedTabStyle($('mys_config_notification_tab'));
			this._update();
		},

		_update : function() {
			var response = new Ajax.Updater('mys_config_layer',
					'/users/notification/' + this._userName,

					{
						asynchronous : false,
						evalScripts : true,
						parameters : null,
						onFailure : function(transport) {
							alert(transport.responesText);
						}
					});
		},

		reload : function() {
			this._update();
		},

		option : function(type, value) {
			for ( var i = 0; i < this._availables.length; i++) {
				if ($(type + '_' + this._availables[i])) {
					$(type + '_' + this._availables[i]).src = '/common/bullet_off.gif';
				}
			}
			$(type + '_' + value).src = '/common/bullet_on.gif';
			$(type).value = value;
		},

		save : function(userName) {
			var responseXml = new Ajax.RequestXML(
					'/users/saveNotification/' + userName, {
						asynchronous : false,
						method : 'post',
						parameters : Form.serialize($('notification_form')),
						onFailure : function(transport) {
							alert(transport.responesText);
						}
					});
			this.onSaved(responseXml.responseValue);
		},

		onSaved : function(xml) {
			var response = xml.response;
			if (response.status == 'success') {
				alert('saved email notification');
				this.reload();
			} else {
				switch (response.error) {
				case 'INVALID_IDENTITY':
					document.location = '/';
					break;
				case 'DB_ERROR':
					alert('Fail to save notification');
					break;
				}
			}
		}
	}
//Notification
};
ViiKii.Video = {
	_videoId :null,
	_videoLanguageId :null,
	_options :null,

	initialize : function(videoId, languageId, options) {
		this._videoId = videoId;
		this._videoLanguageId = languageId;
		this._options = options;
	},

	getId : function() {
		return this._videoId;
	},

	setId : function(videoId) {
		this._videoId = videoId;
	},

	createSegmentFrm : function(start, end, language, content) {
		var frm = $('segmentFrm');
		frm['data[Segment][video_id]'].value = this._videoId;
		frm['data[Segment][start]'].value = start;
		frm['data[Segment][end]'].value = end;
		frm['data[Subtitle][video_id]'].value = this._videoId;
		frm['data[Subtitle][language_id]'].value = language;
		frm['data[Subtitle][subtitle]'].value = content;
		return frm;
	},

	isAvailable : function(videoId) {
		var ajax = new Ajax.Request('/videos/available_video/' + videoId, {
			asynchronous :false
		});
		return ajax.transport.responseText.equals('1');
	},

	onError : function(transport) {
	},

	popUpSubtitle : function(segmentId, languageId, sort) {
		var videoId = this._videoId;
		setTimeout( function() {
			ViiKii.Subtitle.HistoryPopup.open(videoId, segmentId, languageId,
					sort);
		}, 100);
	},

	onCompletePopUpSubtitle : function(transport) {

		var layerName = 'SubtitlePopUpLayer';

		if ($(layerName)) {
			$(layerName).innerHTML = transport.responseText.stripScripts();
			ViiKii.round.round($(layerName));
			$(layerName).style.display = 'block';
		} else {
			var e = document.createElement('div');
			e.id = layerName;
			var styles = {
				position :'absolute',
				left :'260px',
				top :'200px',
				width :'676px',
				height :'545px',
				backgroundColor :'#FFF'
			};
			Element.setStyle(e, styles);
			e.innerHTML = transport.responseText.stripScripts();
			document.getElementsByTagName('body')[0].appendChild(e);
			ViiKii.round.init(layerName, {
				corners :'all',
				borderSize :1
			});
		}
		setTimeout( function() {
			transport.responseText.evalScripts();
		}, 10);
	},

	openNoticeSegment : function() {
		var layerName = 'videoSegmentMessage';
		var msg = ''
				+ '<div>'
				+ '<div style="text-align:right;margin:2px 2px 0 10px;"><img src="/common/close.gif" style="cursor:pointer;" onClick="ViiKii.Video.closeNoticeSegment();"/></div>'
				+ '<div style="text-align:left;margin:0 0 0 10px;width:400px;">'
				+ 'Your video has been added successfully, but other users cannot<br>'
				+ 'see this video yet. To make this video public, you must first segment<br>'
				+ 'this video so other users can translate your video sentence by '
				+ 'sentence.<br><br>'
				+ 'Please keep in mind that word order varies from language to<br>'
				+ 'language. We strongly recommend you to cut each segment by the<br>'
				+ 'sentence. Otherwise, you might have difficulty in getting subtitles in<br>'
				+ 'languages which use a different word order.<br><br>'
				+ 'When you finish segmenting, please press [Make Public]<br>'
				+ 'button. Only after you complete segmenting and press the button,<br>'
				+ 'will this video be made public.<br><br>'
				+ 'For more information, see <a href="http://viikiihelp.wikispaces.com/TutorialHome" target="_blank">"cut a segment"</a> in Help.'
				+ '</div>' + '</div>';

		var position = ViiKii.Video.Player.getPosition();
		position[0] += 200;
		position[1] += 40;
		var e = document.createElement('div');
		e.id = layerName;
		var styles = {
			position :'absolute',
			left :position[0] + 'px',
			top :position[1] + 'px',
			width :'420px',
			height :'270px',
			backgroundColor :'#FFF'
		};
		Element.setStyle(e, styles);
		e.innerHTML = msg;
		document.getElementsByTagName('body')[0].appendChild(e);
		ViiKii.UI.Round.init(layerName, {
			corners :'all',
			borderSize :1
		});
	},

	closeNoticeSegment : function() {
		var layerName = 'videoSegmentMessage';
		if ($(layerName)) {
			document.getElementsByTagName('body')[0].removeChild($(layerName));
		}
	},

	updateCompleteSegment : function(videoId, flag) {
		var url = '/videos/completeSegment/' + videoId + '/' + flag;
		var response = new Ajax.Request(url, {
			asynchronous :true,
			evalScripts :true,
			parameters :null,
			onSuccess :this.onUpdateCompleteSegment,
			onFailure :this.onErrorUpdateCompleteSegment
		});
	},

	onUpdateCompleteSegment : function(transport) {
		document.location = '/subtitles';
	},

	onErrorUpdateCompleteSegment : function() {
		alert('error, update complete segment!');
	},

	rating : function(point) {
		var url = '/videos/rating/' + this._videoId + '/' + point;
		var response = new Ajax.RequestXML(url, {
			asynchronous :false,
			method :'post',
			parameters :null
		});
		this.onRating(response.responseValue);
	},

	onRating : function(result) {
		var rating = result.rating;
		switch (rating.result) {
		case 'DELETED_VIDEO':
			alert("Sorry!\nThis video was deleted while you are watching it.");
			document.location = '/';
			break;
		case 'SUCCESS':
			ViiKii.Video.Player.javaSetRating(rating.rate);
			break;
		default:
			break;
		}
	},

/*
 * ACK,NAK. 2008-11-18. kyungseok.oh toggleSubtitleComplete :
 * function(segmentStartTime, languageId) { var url =
 * '/subtitles/toggleComplete/' + this._videoId + '/' + segmentStartTime + '/' +
 * languageId; var responseXml = new Ajax.RequestXML(url, { asynchronous :false,
 * method :'post', parameters :null });
 * this.onToggleSubtitleComplete(responseXml.responseValue); },
 * 
 * onToggleSubtitleComplete : function(result) { var toggle = result.toggle;
 * switch (toggle.result) { case 'DELETED_VIDEO': alert("Sorry!\nThis video was
 * deleted while you are watching it."); document.location = '/'; break;
 * default: break; } },
 */
	request : function() {
		if (!ViiKii.Video.isAvailable(this._videoId)) {
			setTimeout(
					function() {
						alert("Sorry!\nThis video was deleted while you are watching it.");
						document.location = '/';
					}, 0);
			return "VIDEO_DELETED";
		}

		var url = '/videos/request/' + this._videoId;
		var responseXml = new Ajax.RequestXML(url, {
			asynchronous :false,
			method :'get'
		});
		return "SUCCESS";
	},
	requestSubtitle: function() {
		if(this.request() == 'SUCCESS') {
			var message = '';
			message += 'Your request for subtitle/caption has been successfully received.\n';
			message += 'This video will be displayed in the highest position among the \"Subtitle Wanted\" list.\n';
			message += 'This will allow our contributors to easily find and work on this video.'
			alert(message);
		}
	},

	attach : function(subject) {
		subject.attach(this);
	},

	dettach : function(subject) {
		subject.detach(this);
	},

	update : function() {
		var url = '/videos/title/' + this._videoId;
		var res = new Ajax.Updater('watch-video-title', url, {
			asynchronous :true,
			evalScripts :false,
			parameters :null,
			onFailure : function(transport) {
				alert(transport.responseText);
			}
		});
	},

	updateData : function(tmp) {
		var res = new Ajax.Request('/videos/update/' + this._videoId, {
			asynchronous :false,
			evalScripts :false,
			parameters :null,
			onComplete : function(res) {
				alert(res.responseText);
			},
			onFailure : function(res) {
				alert(res.responseText);
			}
		});
	},

	noticeDeleted : function() {
		alert("Sorry!\nThis video was deleted while you are watching it.");
		document.location = '/';
	},

	noticeNetworkError : function() {
		alert("Sorry! Network failure!\nThis page will be refreshed.");
		document.location.reload();
	},

	changeInterstedLanguage : function(languageId) {
		var userLanguages = ViiKii.Languages.getInterestedLanguageCodes();
		var activeUserLanguages = ViiKii.Languages
				.getActiveInterestedLanguageCodes();
		if (userLanguages.indexOf(languageId) != -1
				&& activeUserLanguages.indexOf(languageId) == -1) {
			ViiKii.Languages.toggleByPlayer(languageId);
		} else {
			var languageName = ViiKii.Languages.SelectBox
					.convertToName(languageId);
			var msg = "In order to view subtitles in ["
					+ languageName
					+ "], "
					+ "include ["
					+ languageName
					+ "] in your language setting by clicking on\n"
					+ "\"Select Languages\" located at the top of this page. \n"
					+ "ViiKii users can choose up to five different languages to view subtitles in.";
			setTimeout( function() {
				alert(msg);
			}, 0);
		}
	},

	listing : function(pageNo) {
			// video_list
		var url = "/videos/listing/" + pageNo;
		var response = new Ajax.Updater('manage_content', url, {
			asynchronous :true,
			evalScripts :true,
			parameters :null,
			onFailure : function(res) {
				alert(res.responseText);
			}
		});
	},
	
	gotoYoutubeProblem: function() {
		document.location = "/videos/youtube_problem/"+$('video_id').value;
	},
	
	denyWatch: function() {
		alert("Sorry, you don't have right to watch this video.");
		history.go(-1);
	}
};// ViiKii.Video

ViiKii.Video.Player = {
	_id :'ViiKiiVideoPlayer',
	_version :'0.1',
	_name :'ViiKii.Player',
	_videoId :0,
	_width :1024,
	_height :515,
	_panelId :'player-panel',
	_flashSwfPath :'/viewer/viikiiplayer.swf',

	_inputLayerName :"ViiKii.Video.Player.InputLayer",
	_innerLayerName :"ViiKii.Video.Player.InnerLayer",
	_inputTextAreaName :"ViiKii.Video.Player.TextArea",
	_isCtrl :false,
	_isEnterEnable :false,
	_maxChars :20,
	_prevText :"",
	_inputCheckTimer :null,

	unload : function() {
		if ($('player-panel') && $(this._id)) {
			$('player-panel').removeChild($(this._id));
		}
	},

	loaded : function() {
		return $('player-panel') && $(this._id);
	},

	subtitleReload : function() {
		$(ViiKii.Video.Player._id).subtitleReload();
	},

	stopLoading : function() {
		if ($(ViiKii.Video.Player._id).stopLoading) {
			$(ViiKii.Video.Player._id).stopLoading();
		}
	},

	showInput : function(text, bgColor, fontSize, fontColor, popupLeft,
			popupTop, popupWidth, popupHeight, maxChars, isEnterEnable) {
		ViiKii.Video.Player._prevText = text;
		ViiKii.Video.Player._isCtrl = false;
		ViiKii.Video.Player._isEnterEnable = isEnterEnable;
		ViiKii.Video.Player._maxChars = maxChars;

		var layerName = ViiKii.Video.Player._inputLayerName;
		var textAreaName = ViiKii.Video.Player._inputTextAreaName;
		var innerLayerName = ViiKii.Video.Player._innerLayerName;
		popupHeight--;

		var layerStyles = {
			left :popupLeft + 'px',
			top :popupTop + 'px',
			width :popupWidth + 'px',
			height :popupHeight + 'px',
			backgroundColor :'transparent',
			position :'absolute'
		};
		var innerLayerStyles = {
			width :popupWidth + 'px',
			height :popupHeight + 'px',
			opacity :0
		};
		var textAreaStyles = {
			width :popupWidth + 'px',
			height :popupHeight + 'px',
			backgroundColor :'transparent',
			fontSize :fontSize,
			color :fontColor,
			cursor :'text'
		};
		$(layerName).style.display = 'block';
		Element.setStyle($(layerName), layerStyles);
		Element.setStyle($(textAreaName), textAreaStyles);
		Element.setStyle($(innerLayerName), innerLayerStyles);

		$(textAreaName).value = text;
		$(textAreaName).focus();

		ViiKii.Video.Player._inputCheckTimer = new PeriodicalExecuter(ViiKii.Video.Player.checkText, 0.3);
	},
	changeInputPosition: function(popupLeft, popupTop) {
		if($(ViiKii.Video.Player._inputLayerName) && $(ViiKii.Video.Player._inputLayerName).style.display == 'block') {
			$(ViiKii.Video.Player._inputLayerName).style.left = popupLeft+'px';
			$(ViiKii.Video.Player._inputLayerName).style.top = popupTop+'px';
			// alert('changeInputPosition: '+popupLeft+', '+popupTop);
		}
	},
	onKeyDown : function(event) {
		$(ViiKii.Video.Player._id).javaKeyPressed();
		var keyCode = ViiKii.Video.Player.getKeyCode(event);
		if (keyCode == 17) {
			ViiKii.Video.Player._isCtrl = true;
		}
		if (keyCode == 38 && ViiKii.Video.Player._isCtrl) {
			ViiKii.Video.Player.dipatchKeyEvent("CTRL_UP");
		} else if (keyCode == 40 && ViiKii.Video.Player._isCtrl) {
			ViiKii.Video.Player.dipatchKeyEvent("CTRL_DOWN");
		} else if (keyCode == 13) {
			ViiKii.Video.Player.dipatchKeyEvent("ENTER");
			if (!ViiKii.Video.Player._isEnterEnable) {
				ViiKii.Video.Player.preventKeyCode(event);
			}
		} else if (keyCode == 27) {
			ViiKii.Video.Player.dipatchKeyEvent("ESC");
		}
		ViiKii.Video.Player.checkText();
	},
	getCursor : function(ctrl) {
		if (document.selection) {
			ctrl.focus();
			var Sel = document.selection.createRange();
			Sel.moveStart('character', -ctrl.value.length);
			return Sel.text.length;
		} else if (ctrl.selectionStart || ctrl.selectionStart == '0') {
			return ctrl.selectionStart;
		}
		return 0;
	},
	setCursor : function(ctrl, pos) {
		if (ctrl.setSelectionRange) {
			ctrl.focus();
			ctrl.setSelectionRange(pos, pos);
		} else if (ctrl.createTextRange) {
			var range = ctrl.createTextRange();
			range.collapse(true);
			range.moveEnd('character', pos);
			range.moveStart('character', pos);
			range.select();
		}
	},
	checkText : function() {
		var textAreaName = ViiKii.Video.Player._inputTextAreaName;
		if (ViiKii.Video.Player.getBytes($(textAreaName).value) > ViiKii.Video.Player._maxChars) {
			var cursorPos = ViiKii.Video.Player.getCursor($(textAreaName));
			$('fake').focus();
			$(textAreaName).value = ViiKii.Video.Player.getBytesText(
					$(textAreaName).value, ViiKii.Video.Player._maxChars);
			ViiKii.Video.Player.setCursor($(textAreaName), cursorPos);
		}
		if (!ViiKii.Video.Player._isEnterEnable
				&& ($(textAreaName).value).indexOf("\n") != -1) {
			$(textAreaName).value = $(textAreaName).value.replace("\r", "")
					.replace("\n", "");
		}
	},
	dipatchKeyEvent : function(eventType) {
		$(ViiKii.Video.Player._id).javaDipatchKeyEvent(eventType);
	},
	onKeyUp : function(event) {
		var keyCode = ViiKii.Video.Player.getKeyCode(event);
		if (keyCode == 17) {
			ViiKii.Video.Player._isCtrl = false;
		}
		ViiKii.Video.Player.checkText();
	},
	onChange : function(event) {
		ViiKii.Video.Player.checkText();
	},
	getBytes : function(message) {
		var bytes = 0;
		for (i = 0; i < message.length; i++) {
			var ch = message.charAt(i);
			if (escape(ch).length > 4) {
				bytes += 2;
			} else if (ch != '\r') {
				bytes++;
			}
		}
		return bytes;
	},
	getBytesText : function(message, maxBytes) {
		for ( var i = Math.floor(maxBytes / 2); i < message.length; i++) {
			if (ViiKii.Video.Player.getBytes(message.substring(0, i)
					+ message.substring(i, i + 1)) >= ViiKii.Video.Player._maxChars) {
				// alert(message.substring(0, i)+":"+message.substring(i,
				// i+1)+":"+ViiKii.Video.Player.getBytes(message.substring(0,
				// i)+message.substring(i, i+1)));
				return message.substring(0, i);
			}
		}
		return message;
	},
	getKeyCode : function(event) {
		if (window.event) {
			return window.event.keyCode;
		}
		if (event) {
			return event.which;
		}
	},
	preventKeyCode : function(event) {
		if (window.event) {
			event.returnValue = false;
		} else {
			event.preventDefault();
		}
	},
	hideInput : function() {
		$(ViiKii.Video.Player._inputLayerName).style.display = 'none';
		if (ViiKii.Video.Player._inputCheckTimer) {
			ViiKii.Video.Player._inputCheckTimer.stop();
		}
		$(ViiKii.Video.Player._id).focus();
	},
	setInput : function(text) {
		$(ViiKii.Video.Player._inputTextAreaName).value = text;
	},
	getInput : function() {
		ViiKii.Video.Player.checkText();
		return $(ViiKii.Video.Player._inputTextAreaName).value;
	},
	init : function(videoId, selectedTab) {
		this._videoId = videoId;
		this.attachPlayer(this._panelId, videoId, this._flashSwfPath, selectedTab);
	},
	
	attachPlayer: function(panelId, videoId, swf, selectedTab, sourceId) {
		if(typeof sourceId == "undefined") {
			sourceId = '';
		}
		var toggleOnInterested = ViiKii.Languages.getActiveInterestedLanguageCodes();
		var userName = (ViiKii.Util.getDomainCookie('username') == null) ? '' : ViiKii.Util.getDomainCookie('username');

		var flashTag = '';
		if (Prototype.Browser.IE) {
			flashTag = '<object id="'
					+ this._id
					+ '" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" '
					+ 'codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=9,0,0,0" '
					+ 'width="' + this._width + '" height="' + this._height
					+ '" align="middle">'
					+ '<param name="allowScriptAccess" value="always" />'
					+ '<param name="allowFullScreen" value="true" />'
					+ '<param name="movie" value="' + swf
					+ '&video_id=' + videoId + '&user_name=' + userName + '&source_id=' + sourceId
					+ '&selected_tab=' + selectedTab + '&interested_languages='
					+ toggleOnInterested.join(",") + '"/>'
					+ '<param name="quality" value="high" />'
					+ '<param name="wmode" value="transparent" />'
					+ '<param name="bgcolor" value="#000000" />' + '</object>';
		} else {
			flashTag = '<embed id="'
					+ this._id
					+ '" src="'
					+ swf
					+ '&video_id='
					+ videoId
					+ '&user_name='
					+ userName
					+ '&selected_tab='
					+ selectedTab
					+ '&source_id='
					+ sourceId
					+ '&interested_languages='
					+ toggleOnInterested.join(",")
					+ '" quality="high" pluginspage="http://www.macromedia.com/go/getflashplayer" type="application/x-shockwave-flash" '
					+ 'width="'
					+ this._width
					+ '" height="'
					+ this._height
					+ '" allowFullScreen="true" allowScriptAccess="always" scale="noscale" wmode="transparent"></embed>';
		}
		$(panelId).innerHTML = flashTag;
	},

	update : function() {
		var toggleOnInterested = ViiKii.Languages
				.getActiveInterestedLanguageCodes();
		var userName = (ViiKii.Util.getDomainCookie('username') == null) ? ''
				: ViiKii.Util.getDomainCookie('username');
		$(this._id).changeInterestedLanguages(toggleOnInterested.join(","));
	},

	attach : function(subject) {
		subject.attach(this);
	},

	myViiKiiPopupOpen : function() {
		if (Object.isNull($(this._id)) || Object.isUndefined($(this._id))) {
			return;
		}
		$(this._id).myViiKiiPopupOpen();
	},

	myViiKiiPopupClose : function() {
		if (Object.isNull($(this._id)) || Object.isUndefined($(this._id))) {
			return;
		}
		$(this._id).myViiKiiPopupClose();
	},

	popUpClose : function() {
		if (Object.isNull($(this._id)) || Object.isUndefined($(this._id))) {
			alert('error: not exist viikii flash player id');
			return;
		}
		$(this._id).popUpClose();
	},

	revisionPopupCancel : function() {
		$(this._id).revisionPopupCancel();
	},

	revisionPopupModify : function(revisionFlag, revisionValue, revisionUserID,
			revisionCount) {
		$(this._id).revisionPopupModify(revisionFlag, revisionValue,
				revisionUserID, revisionCount);
	},

	revisionPopupSave : function(revisionValue) {
		$(this._id).revisionPopupSave(revisionValue);
	},

	setVideoPosition : function(position) {
		$(this._id).setVideoPosition(position);
	},

	javaAddDiscussion : function(discussionId, language, text) {
		$(this._id).javaAddDiscussion(discussionId, language, text);
	},

	javaDeleteDiscussion : function(textId, type) {
		$(this._id).javaDeleteDiscussion(textId, type);
	},
	getPosition : function() {
		return Position.positionedOffset($(this._id));
	},
	javaSetRating : function(rate) {
		$(this._id).javaSetRating(rate);
	},
	popupInappro: function() {
		// wrapper
		ViiKii.Inappro.popup('V', this._videoId, null);
	}
};// ViiKii.Video.Player

ViiKii.Video.PublishedList = {
	update: function(order, rate, date, count, page) {
		var url = '/ci/index.php/videos/published_list/' + order + '/' + rate + '/' + date + '/' + count + '/' + page;
		new Ajax.Updater('video_published_list_layer', url, {evalScripts: true});
	}
};

ViiKii.Video.WantedList = {
	update : function(order, page) {
		var url = "/ci/index.php/videos/wanted_list/" + order + "/" + page;
		new Ajax.Updater('video_wanted_list_layer', url, {evalScripts: true});
	}
};

ViiKii.Video.ManageForm = {
	flashGotoPage : function(videoId) {
		if (!Object.isUndefined(videoId)) {
			ViiKii.Video.setId(videoId);
		}

		if (Object.isUndefined(ViiKii.Video)
				|| Object.isNull(ViiKii.Video.getId())) {
			return;
		}

		setTimeout( function() {
			this.gotoManageVideo(ViiKii.Video.getId());
		}.bind(this), 0);
	},
	gotoManageVideo : function(videoId) {
		if (!ViiKii.Video.isAvailable(videoId)) {
			alert("Sorry!\nThis video was deleted while you are watching it.");
			document.location = '/';
			return;
		}
		document.location = '/manage_videos/init/' + ViiKii.Video.getId();
	},

	cancelEditNexts : function(videoId) {
		this.refreshNext(videoId);
	},

	editNexts : function(videoId) {
		var param = 'data[video_id]=' + videoId;
		param += '&data[nexts]=' + encodeURIComponent($('ManageVideoWhatNext').value);

		var xml = new Ajax.RequestXML('/manage_videos/edit_next/', {
			asynchronous :false,
			method :'post',
			parameters :param
		});
		this.onSuccessEditNext(xml, videoId);
	},
	onSuccessEditNext : function(xml, videoId) {
		// alert(xml.transport.responseText);
		var response = xml.responseValue.response;
		if (response.result == 'SUCCESS') {
			this.refreshNext(videoId);
			return;
		}
		switch (response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'INVALID_VIDEO':
			alert("Sorry!\nThis video was deleted while you are watching it.");
			document.location = '/';
			break;
		case 'NOT_OWNER':
			alert("You are not the owner of this video");
			document.location = '/';
			break;
		}
	},
	refreshNext : function(videoId) {
		var ajax = new Ajax.Request('/manage_videos/next_urls/' + videoId, {
			asynchronous :false,
			method :'get'
		});
		$('ManageVideoWhatNext').value = ajax.transport.responseText;
	}
};

ViiKii.VideoForm = {
	_fields: [],
	_clickedFieldCount: 0,
	tooltip: null,
	_lastPartIndex: 0,
	_lastSlaveIndex: 0,
	_lastTitle: '',
	_lastSeason: '',
	_lastEpisode: '',
	_lastParts: [],
	_isEditCell: false,
	_showTooltip: function(target, message, offsetX, offsetY) {
		if (typeof target == "undefined" || target == null) {
			return;
		}
		offsetX = (typeof offsetX == "undefined") ? 0 : offsetX;
		offsetY = (typeof offsetY == "undefined") ? 0 : offsetY;
		
		if (this.tooltip == null) {
			this.tooltip = ViiKii.UI.AltPool.create();
		}
		position = Position.positionedOffset(target);
		this.tooltip.alt(position[0] + offsetX, position[1] + offsetY, message);
	},
	_closeAllTooltip: function() {
		if (null != this.tooltip) {
			this.tooltip.close();
		}
	},
	onChangeGenre: function(frm, genreId, hasField) {
		this._closeAllTooltip();
		frm.genre.value = genreId;
		if (hasField == 'Y') {
			this.showFieldBox();
		} else {
			this.hiddenFieldBox();
		}
		return;
	},
	showFieldBox: function() {
		$('field_box_row_top_margin').show();
		$('field_box_row').show();
	},
	hiddenFieldBox: function() {
		this._fields.each( function(field) {
			$('img_field_chkbox_' + field).src = '/common/checkbox_wh.gif';
		});
		this._fields = [];
		$('field_box_row_top_margin').hide();
		$('field_box_row').hide();
	},
	clickField: function(fieldId) {
		max = 5;
		if (this._isSelectedFieldId(fieldId)) {
			this._detachField(fieldId);
		} else {
			if (max <= this._fields.length) {
				this._showTooltip($('field_box_div'), 'you can select up to 5 fields', 120, -24);
				return;
			}
			this._appendField(fieldId);
		}
	},
	_isSelectedFieldId: function(id) {
		return -1 != this._fields.indexOf(id); 
	},
	_appendField: function(fieldId) {
		this._fields.push(fieldId);
		$('img_field_chkbox_' + fieldId).src = '/common/checkbox_ch.gif';
	},
	_detachField: function(fieldId) {
		this._fields.splice(this._fields.indexOf(fieldId), 1);
		$('img_field_chkbox_' + fieldId).src = '/common/checkbox_wh.gif';
	},
	openSelectLanguageBox: function() {
		position = Position.positionedOffset($('language_select_box'));
		ViiKii.Languages.SelectBox.open(position[0], position[1] + 20, ViiKii.Languages.SelectBox.getVideoChooseState());
	},
	setLanguage: function(languageId, locale) {
		// called when language select-box choose language
		this._closeAllTooltip();
		$('language_select_box').update(locale);
		$('language').value = languageId;
	},
	isValidURL: function(url) {
		var pattern = /(http|rtmp):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
		if (pattern.test(url) && (url.find('youtube') || url.find('viikiifvs.cdnetworks.net') || url.find('yahoo') || url.find('myspace') || url.find('google') || url.find('rtmp'))) {
			return true;
		}
		return false;
	},
	add: function(frm) {
		this._closeAllTooltip();
		if (null == frm || "undefined" == typeof frm) {
			alert("form is undefined.");
			return false;
		}
		if ($F(frm.genre).empty()) {
			this._showTooltip($('genre_select_box'), "Please select genre.", 100, -26);
			return false;
		}
		
		if (this._fields.length > 0) {
			frm.field_id.value = this._fields.join(',');
		}
		
		if ($F(frm.language).empty()) {
			this._showTooltip($('language_select_box'), "Please select language.", 140, -26);
			return false;
		}
		
		var title_count = 0;
		var ajax = new Ajax.Request("/videos/count_temp_title", {asynchronous: false, evalScripts: false,
			onComplete: function(transport, response) {
				title_count = response.count;
			}
		});
		if (title_count < 1) {
			alert('input title');
		}
		
		if ( ! $F(frm.season).trim().empty() && 
				(! $F(frm.season).isNum() || 100 < $F(frm.season) || $F(frm.season) < 1)) {
			this._showTooltip(frm.season, "1~100", 20, -26);
			return false;
		}
		
		if ( ! $F(frm.episode).trim().empty() && 
				(! $F(frm.episode).isNum() || 999 < $F(frm.episode) || $F(frm.episode) < 1)) {
			this._showTooltip(frm.episode, "1~999", 20, -26);
			return false;
		}
		
		if ( ! this._confirmPartVideos(frm)) {
			return false;
		}
		if ( ! this._confirmSlaveVideos(frm)) {
			return false;
		}
		
		if ($F(frm.released).trim() == "eg. 1997/08/03") {
			frm.released.value = "";
		}
		
		var ajax = new Ajax.Request("/add_videos/add", {asynchronous: false, evalScripts: false,
			parameters: Form.serialize(frm),
			onComplete: function(transport, response) {
				if ("success" == response.result) {
					if (0 != response.id) {
						document.location = '/videos/watch/' + response.id + '/1';
						return;
					}
				} else {
					switch (response.error) {
					case "E_NOT_LOGIN":
						alert("Fail, to add video. You login first.");
						document.location = '/';
						break;
					case "E_THUMB_URL":
						alert("Fail, to add video, Not found thumb image.");
						break;
					}
				}
			}
		});
	},
	_confirmPartVideos: function(frm) {
		count = this._getPartVideosCount(frm);
		duplicatedAndEmptyUrlVideoCount = 0;
		
		for (i = 0; i < count; i++) {
			index = this._getPartVideoIndex(frm, i);
			if ( ! this._isValidPartValue($F(frm['videos['+index+'][part1]']))) {
				this._showTooltip(frm['videos['+index+'][part1]'], "1~100", 20, -26);
				return false;
			} else if ( ! this._isValidPartValue($F(frm['videos['+index+'][part2]']))) {
				this._showTooltip(frm['videos['+index+'][part2]'], "1~100", 20, -26);
				return false;
			}
			
			url = $F(frm['videos['+index+'][url]']).trim();
			switch ($F(frm['videos['+index+'][duplicated]'])) {
			case 'Y'://duplicated video
				if (url.empty()) {
					duplicatedAndEmptyUrlVideoCount++;
				} else if ( ! url.empty() && ! this.isValidURL(url)) {
					this._showTooltip(frm['videos['+index+'][url]'], "you have entered incorrect URL", 20, -26);
					return false;
				}
				break;
			case 'N'://not duplicated video
				if (url.empty()) {
					this._showTooltip(frm['videos['+index+'][url]'], "input the URL", 20, -26);
					return false;
				} else if ( ! this.isValidURL(url)) {
					this._showTooltip(frm['videos['+index+'][url]'], "you have entered incorrect URL", 20, -26);
					return false;
				}
				break;
			case 'C'://checking video duplicated
			default://else case
				return false;
			}
		}
		
		if (count == duplicatedAndEmptyUrlVideoCount) {
			alert('all duplicated and not input url anyone');
			return false;	// 전부다 duplicated 되었으며, 입력된 URL 이 하나도 없는 경우.
		}
		
		return true;
	},
	_confirmSlaveVideos: function(frm) {
		count = this._getSlaveVideosCount(frm);
		for (i = 0; i < count; i++) {
			index = this._getSlaveVideoIndex(frm, i);
			start = $F(frm['slaves['+index+'][start_tm]']).trim();
			end = $F(frm['slaves['+index+'][end_tm]']).trim();
			if (start.empty()) {
				this._showTooltip(frm['slaves['+index+'][start_tm]'], 'input the START time.', 20, -26);
				return false;
			} else if (end.empty()) {
				this._showTooltip(frm['slaves['+index+'][end_tm]'], 'input the END time.', 20, -26);
				return false;
			} else {			
				if ( ! this.isValidURL($F(frm['slaves['+index+'][url]']).trim())) {
					this._showTooltip(frm['slaves['+index+'][url]'], 'you have entered incorrect URL', 20, -26);
					return false; 
				}
			}
		}
		return true;
	},
	_isValidPartValue: function(value) {
		min = 1;
		max = 100;
		if (value.isNum() && (min <= value && value <= max)) {
			return true;
		}
		return false;
	},
	change: function(frm) {
		this._closeAllTooltip();
		
		if (this._fields.length > 0) {
			frm.field_id.value = this._fields.join(',');
		}
		
		if ( ! $F(frm.season).trim().empty() && 
				(! $F(frm.season).isNum() || 100 < $F(frm.season) || $F(frm.season) < 1)) {
			this._showTooltip(frm.season, "1~100", 20, -26);
			return false;
		}
		
		if ( ! $F(frm.episode).trim().empty() && 
				(! $F(frm.episode).isNum() || 999 < $F(frm.episode) || $F(frm.episode) < 1)) {
			this._showTooltip(frm.episode, "1~999", 20, -26);
			return false;
		}
		
		if ( ! this._confirmPartVideos(frm)) {
			return false;
		}
		if ( ! this._confirmSlaveVideos(frm)) {
			return false;
		}
		
		if ( ! $F(frm.channel_url).trim().empty() && $F(frm.channel_url).trim() != "Enter the Channel URL Here") {
			var isValidUrl = false;
			channel = $F(frm.channel_url).trim();
			if (channel.lastIndexOf('/') != -1) {
				channel = channel.substring(channel.lastIndexOf('/') + 1);
			}
			
			var params = $H({'url':channel}).toQueryString();
			new Ajax.Request('/channels/check_valid_url', {
				asynchronous: false,
				parameters: params,
				onComplete: function(transport, response) {
					if (response.result == 'success') {
						isValidUrl = true;
					} else {
						isValidUrl = false;
						alert(response.error);
					}
				}
			});
			
			if ( ! isValidUrl) {
				frm.channel_url.focus();
				return false;
			}
		}
		
		new Ajax.Request('/update_videos/update', {asynchronous: false, evalScripts: false, 
			parameters: Form.serialize(frm),
			onComplete: function(transport, res) {
				if ('success' == res.result) {
					alert("saved");
					document.location.reload();
				} else {
					alert("Fail, to save video information");
				}
			}
		});
	},
	focusChannel: function(input) {
		if ($F(input).trim() == "Enter the Channel URL Here") {
			input.value = '';
		}
	},
	change_for_moderator: function(frm) {
		this._closeAllTooltip();
		
		if (this._fields.length > 0) {
			frm.field_id.value = this._fields.join(',');
		}
		
		if ( ! $F(frm.season).trim().empty() && 
				(! $F(frm.season).isNum() || 100 < $F(frm.season) || $F(frm.season) < 1)) {
			this._showTooltip(frm.season, "1~100", 20, -26);
			return false;
		}
		
		if ( ! $F(frm.episode).trim().empty() && 
				(! $F(frm.episode).isNum() || 999 < $F(frm.episode) || $F(frm.episode) < 1)) {
			this._showTooltip(frm.episode, "1~999", 20, -26);
			return false;
		}
		
		new Ajax.Request('/update_videos/update_for_moderator', {asynchronous: false, evalScripts: false, 
			parameters: Form.serialize(frm),
			onComplete: function(transport, res) {
				if ('success' == res.result) {
					alert("saved");
					document.location.reload();
				} else {
					alert("Fail, to save video information");
				}
			}
		});
	},
	appendPart: function(frm) {
		if (this._isExistSlaveVideos(frm)) {
			return false;
		}
		div = document.createElement("div");
		$('video_parts').appendChild(div);
		div.innerHTML = this._getVideoPartTag(this._lastPartIndex + 1);
		this._lastPartIndex++;
		this._initPartVideosPart(frm);
		this._updateAllPartVideoDuplicateStatus(frm, 'C');//checking.
		this._checkPartVideosDuplicate(frm);
	},
	_isExistSlaveVideos: function(frm) {
		return 0 < this._getSlaveVideosCount(frm);
	},
	_initPartVideosPart: function(frm) {
		this._lastParts = [];
		count = this._getPartVideosCount(frm);
		for (i = 0; i < count; i++) {
			this._lastParts[i] = (i+1) + '/' + count;
			index = this._getPartVideoIndex(frm, i);
			frm['videos[' + index + '][part1]'].value = i + 1;
			frm['videos[' + index + '][part2]'].value = count;
		}
	},
	_getPartVideosCount: function(frm) {
		if (null == frm || "undefined" == typeof frm) {
			return 0;
		}
		return ("undefined" == typeof frm['parts[]'].length) ? 1 : frm['parts[]'].length; 
	},
	_updateAllPartVideoDuplicateStatus: function(frm, status) {
		for (i = 0; i < this._getPartVideosCount(frm); i++) {
			this.updatePartVideoDuplicateStatus(frm, this._getPartVideoIndex(frm, i), status);
		}
	},
	_checkPartVideosDuplicate: function(frm) {
		if (! frm.id.value.trim().empty()) { //modify
			season = this._getSeason(frm);
			episode = this._getEpisode(frm);
			for (i = 0; i < this._getPartVideosCount(frm); i++) {
				index = this._getPartVideoIndex(frm, i);
				this.updatePartVideoDuplicateStatus(frm, index, 'C');//C-checking
				this._checkPartVideoDuplicate(frm, index);
			}
		} else {
			season = this._getSeason(frm);
			episode = this._getEpisode(frm);
			for (i = 0; i < this._getPartVideosCount(frm); i++) {
				index = this._getPartVideoIndex(frm, i);
				this.updatePartVideoDuplicateStatus(frm, index, 'C');//C-checking
				this._checkPartVideoDuplicate(frm, index);
			}
		}
	},
	appendSlave: function(frm) {
		if (this._isExistAnotherPartVideos(frm)) {
			return false;
		}
		div = document.createElement("div");
		$('video_slaves').appendChild(div);
		div.innerHTML = this._getSlaveVideoTemplate(this._lastSlaveIndex);
		this._initSlaveVideosPart(frm);
		this._lastSlaveIndex++;
	},
	loadSlave: function(frm, id, url, start, end) {
		this.appendSlave(frm);
		index = this._lastSlaveIndex - 1;
		frm["slaves["+index+"][id]"].value = id;
		frm["slaves["+index+"][url]"].value = url;
		frm["slaves["+index+"][start_tm]"].value = start;
		frm["slaves["+index+"][end_tm]"].value = end;
	},
	_isExistAnotherPartVideos: function(frm) {
		return 1 < this._getPartVideosCount(frm);
	},
	_getSlaveVideoTemplate: function(index) {
		return $('slave_video_tempalte').innerHTML.replace(/#index#/g, index);
	},
	detachSlave: function(frm, index) {
		$('slave_video_' + index).remove();
		this._initSlaveVideosPart(frm);
	},
	_getSlaveVideoIndex: function(frm, number) {
		if ("undefined" == typeof frm['slave_indexs[]'][number]) {
			return frm['slave_indexs[]'].value;
		} else {
			return frm['slave_indexs[]'][number].value;
		}
	},
	_initSlaveVideosPart: function(frm) {
		count = this._getSlaveVideosCount(frm);
		for (i = 0; i < count; i++) {
			index = this._getSlaveVideoIndex(frm, i);
			frm['slaves[' + index + '][part1]'].value = i + 1;
			frm['slaves[' + index + '][part2]'].value = count;
		}
	},
	_getSlaveVideosCount: function(frm) {
		if ("undefined" == typeof frm['slave_indexs[]']) {
			return 0;
		}
		return ("undefined" == typeof frm['slave_indexs[]'].length) ? 1 : frm['slave_indexs[]'].length; 
	},
	_getVideoPartTag: function(index) {
		return $('part_video_template').innerHTML.replace(/#index#/g, index);
	},
	_getPartVideoIndex: function(frm, part) {
		if ("undefined" == typeof frm['parts[]'][part]) {
			return frm['parts[]'].value;
		} else {
			return frm['parts[]'][part].value;
		}
	},
	updatePartVideoDuplicateStatus: function(frm, index, status) {
		switch (status) {
		case 'D':// duplicated
			img = 'http://vkcommon.viikii.net/duplicate_bg_pink_duplicate.gif';
			msg = 'Duplicate';
			is_duplicate_checked = 'Y';
			duplicated = 'Y';
			break;
		case 'A':// available
			img = 'http://vkcommon.viikii.net/duplicate_bg_pink_available.gif';
			msg = 'Available';
			is_duplicate_checked = 'Y';
			duplicated = 'N';
			break;
		case 'C':// checking duplicate
			img = 'http://vkcommon.viikii.net/loading_bg_pink_01.gif';
			msg = 'Checking duplicate';
			is_duplicate_checked = 'N';
			duplicated = '';
			break;
		case 'N':// none
		default:
			img = '';
			msg = '';
			is_duplicate_checked = 'N';
			duplicated = ''
			break;
		}
		
		$('videos_' + index + '_status').style.background = "url('" + img + "') no-repeat 5px 2px";
		$('videos_' + index + '_status').update(msg);
		
		frm['videos['+index+'][is_duplicate_checked]'].value = is_duplicate_checked;
		frm['videos['+index+'][duplicated]'].value = duplicated;
	},
	detachPart: function(frm, index) {
		$('part_video_' + index).remove();
		this._initPartVideosPart(frm);
		if ($F(frm.title).trim().empty()) {
			this._updateAllPartVideoDuplicateStatus(frm, 'N');//none
		} else {
			this._updateAllPartVideoDuplicateStatus(frm, 'C');//checking.
			this._checkPartVideosDuplicate(frm);
		}
	},
	_checkPartVideoDuplicate: function(frm, index) {
		season = this._getSeason(frm);
		episode = this._getEpisode(frm);
		part1 = this._getPartVideoPart1(frm, index);
		part2 = this._getPartVideoPart2(frm, index);
		
		if (! frm.id.value.trim().empty()) {
			params = $H({'index': index, 'video_id': $F(frm.id), 'season': season, 'episode': episode, 
				'part1': part1, 'part2': part2}).toQueryString();
		} else {
			params = $H({'index': index, 'season': season, 'episode': episode, 
				'part1': part1, 'part2': part2}).toQueryString();
		}
		new Ajax.Request("/ci/index.php/duplicated_videos/check", {asynchronous: false, evalScripts: false,
			parameters: params,
			onComplete: function(transport, response) {
				ViiKii.VideoForm.updatePartVideoDuplicateStatus($('frm'), response.index, response.status);
			}
		});
	},
	_getSeason: function(frm) {
		return $F(frm.season).empty() ? 0 : $F(frm.season); 
	},
	_getEpisode: function(frm) {
		return $F(frm.episode).empty() ? 0 : $F(frm.episode);
	},
	_getPartVideoIndex: function(frm, key) {
		return "undefined" == typeof frm['parts[]'][key] ? $F(frm['parts[]']) : $F(frm['parts[]'][key]);
	},
	_getPartVideoPart1: function(frm, index) {
		return ($F(frm['videos[' + index + '][part1]']).empty()) ? 0 : $F(frm['videos[' + index + '][part1]']);
	},
	_getPartVideoPart2: function(frm, index) {
		return ($F(frm['videos[' + index + '][part2]']).empty()) ? 0 : $F(frm['videos[' + index + '][part2]']);
	},
	_isFirstInput: function(value) {
		return null == value;
	},
	isChangedInput: function(last, current) {
		return last != current;
	},
	checkChangedTitle: function(frm) {//
		this._updateAllPartVideoDuplicateStatus(frm, 'C');//C-checking
		this._checkPartVideosDuplicate(frm);
	},
	_isChangedTitle: function(lastTitle, currentTitle) {
		return this._isChangedInputValue(lastTitle, currentTitle);
	},
	_isChangedInputValue: function(last, current) {
		return last != current;
	},
	_isChangedSeason: function(lastSeason, currentSeason) {
		return this._isChangedInputValue(lastSeason, currentSeason);
	},
	checkChangedSeason: function(frm) {
		if (this._isChangedSeason(this._lastSeason, $F(frm.season).trim())) {
			this._lastSeason = $F(frm.season).trim();
			this._updateAllPartVideoDuplicateStatus(frm, 'C');//C-checking
			this._checkPartVideosDuplicate(frm);
		}
	},
	_isChangedEpisode: function(lastEpisode, currentEpisode) {
		return this._isChangedInputValue(lastEpisode, currentEpisode);
	},
	checkChangedEpisode: function(frm) {
		if (this._isChangedEpisode(this._lastEpisode, $F(frm.episode).trim())) {
			this._lastEpisode = $F(frm.episode).trim();
			this._updateAllPartVideoDuplicateStatus(frm, 'C');//C-checking
			this._checkPartVideosDuplicate(frm);
		}
	},
	_isChangedPart: function(lastPart, currentPart) {
		return this._isChangedInputValue(lastPart, currentPart);
	},
	checkChangedPart: function(frm, index) {
		part = $F(frm['videos[' + index + '][part1]']) + '/' + $F(frm['videos[' + index + '][part2]']);
		if (this._isChangedPart(this._lastParts[index], part)) {
			this._lastParts[index] = part;
			this.updatePartVideoDuplicateStatus(frm, index, 'C');//C-checking
			this._checkPartVideoDuplicate(frm, index);
		}
	},
	clickCell: function(event) {
		var source = Event.element(event);
		var sourceId = source.id.split("_");
		switch (sourceId[0]) {
		case 'cell':
			this.editCell(source.id);
			break;
		case 'save':
			this.saveCell();
			break;
		case 'cancel':
			this.cancelCell();
			break;
		}
	},
	editCell: function(cellId) {
		if (this._isEditCell) {
			return;
		}
		this.editableCell.onKeyEnterDown = "ViiKii.VideoForm.saveCell()";
		this.editableCell.onKeyESCDown = "ViiKii.VideoForm.cancelCell()";
		this.editableCell.editCell(cellId);
		this._isEditCell = true;
	},
	saveCell: function() {
		if (this._isEditCell) {
			var text = this.editableCell.getTextAreaText();
			text = text.trim();
			text = text.split("<BR>").join("");
			text = text.split("<br>").join("");
			
			if (text.empty()) {
				this.cancelCell();
			} else if (text.getBytes() > 255) {
				alert('up to 255 characters');
				this.cancelSave();
				return;
			}
			
			this._isEditCell = false;
			var cellId = this.editableCell.getCellId();
			var cell = cellId.split("_");
			params = $H({'type':cell[1], 'language':cell[2], 'sequence':cell[3], 'content':text}).toQueryString();
			new Ajax.Request('/videos/save_cell', {
				evalScripts: false,
				parameters: params,
				onComplete: function(transport, response) {
					if (response.result == "success") {
						ViiKii.VideoForm.updateCell();
						ViiKii.VideoForm.checkChangedTitle($('frm'));
					} else {
						alert(response.error);
					}
				}
			});
		}
	},
	cancelCell: function() {
		this.editableCell.cancelEdit();
		this._isEditCell = false;
	},
	updateCell: function() {
		new Ajax.Updater('t_table', '/videos/metas', {
			evalScripts: false,
			parameters: null
		});
	},
	editableCell: new ViiKii.UI.EditableCell()
};// End of ViiKii.VideoForm

ViiKii.Video.Searching = {
	goMore : function() {
		this.paging(1);
	},
	paging : function(pageNo) {
		var params = $H( {
			'pageNo' :pageNo,
			'query' :$F('query')
		}).toQueryString();
		document.location = '/search/videos?' + params;
	}
};
ViiKii.Video.Details = {
	videoId: 0,
	showTab: function(show) {
		if(show) {
			Element.show('ViiKii.Video.Details.layer');
		} else {
			Element.hide('ViiKii.Video.Details.layer');
		}
	},
	update: function() {
		new Ajax.Updater(
			'ViiKii.Video.Details.layer',
			'/video_infos/detail/'+this.videoId
		);
	},
	onClickUrl: function(text) {
		this.selectAll(text);
	},
	selectAll: function(ctrl) {
		if (ctrl.setSelectionRange) {
			ctrl.focus();
			ctrl.setSelectionRange(0, 99999);
		} else if (ctrl.createTextRange) {
			var range = ctrl.createTextRange();
			range.collapse(true);
			range.moveStart('character', 0);
			range.moveEnd('character', 99999);
			range.select();
		}
	}
};
ViiKii.Video.Details.RelatedVideos = {
	videoId: 0,
	isMore: false,
	toggleMore: function() {
		this.isMore = !this.isMore;
		this.updateMore();
	},
	updateMore: function() {
		$('ViiKii.Video.Details.RelatedVideos.button').innerHTML = (this.isMore?'less':'more');
		$('ViiKii.Video.Details.RelatedVideos.moreList.layer').toggle();
	}
};
ViiKii.Video.Details.IncludingChannels = {
	videoId: 0,
	isMore: false,
	toggleMore: function() {
		this.isMore = !this.isMore;
		this.updateMore();
	},
	updateMore: function() {
		$('ViiKii.Video.Details.IncludingChannels.button').innerHTML = (this.isMore?'less':'more');
		new Ajax.Updater(
			'ViiKii.Video.Details.IncludingChannels.layer',
			'/video_infos/including_channels/'+this.videoId+'/'+(this.isMore?'T':'F'),
			{
				evalScripts: true,
				method: 'get'
			}
		);
	}
};
ViiKii.Video.Stream = {
	getStream: function(url) {
		// alert(url);
		var ajax = new Ajax.Request(
			url,
			{
				asynchronous: false
			}
		);
		this.onGetStream(ajax);
	},
	onGetStream: function(ajax) {
		// alert("hi");
		// alert(ajax.transport.responseText);
	}
};
ViiKii.Video.Sync = {
	gotoAddUrl: function() {
		document.location = '/video_urls/add_source/'+$('video_id').value;
	},
	addUrl: function(videoId) {
		// alert("video: "+videoId+" "+$('video_url').value);
		if(!ViiKii.VideoForm.isValidURL($('video_url').value)) {
			alert('Insert valid video URL first!');
			return;
		}
		var params=$H(
			{url:$('video_url').value}
		).toQueryString();
		new Ajax.Request(
			'/video_urls/add_url/'+videoId,
			{
				parameters: params,
				onComplete: this.onAddUrl.bind(this)
			}
		);
	},
	onAddUrl: function(transport, response) {
		if(response.result == 'SUCCESS') {
			document.location = '/video_urls/sync_source/'+response.url_id;
			return;
		}
		switch(response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'INVALID_STREAM':
			alert('Invalid stream. Please insert another video URL.');
			break;
		case 'INVALID_VIDEO':
			alert('The video is deleted.');
			document.location = '/';
			break;
		case 'DB_ERROR':
			alert('Fail to add url. Please try again!');
			break;
		}
	},
	save: function(sourceId, time) {
		new Ajax.Request(
			'/video_urls/save_sync/'+sourceId+'/'+time,
			{
				onComplete: this.onSave.bind(this)
			}
		)
	},
	onSave: function(transport, response) {
		if(response.result == 'SUCCESS') {
			document.location = '/videos/watch/'+response.video_id;
			return;
		}
		switch(response.error) {
		case 'NOT_LOG_IN':
			ViiKii.Login.popUp();
			break;
		case 'INVALID_SOURCE':
			alert('The video source is invalid.');
			document.location = '/videos';
			break;
		case 'INVALID_VIDEO':
			alert('The video is deleted.');
			document.location = '/videos';
			break;
		case 'DB_ERROR':
			alert('Fail to sync video. Please try again!');
			break;
		}
	}
};

ViiKii.Video.Divide = {
	_currentIndex: 0,
	_length: 0,
	_partVideos: [],
	init: function(videoId) {
		var params = $H({'video_id': videoId}).toQueryString();
		new Ajax.Request('/videos_divide/init', {
			asynchronous :false,
			evalScripts: false,
			parameters: params,
			onComplete: function(transport, response) {
				if ('success' == response.result) {
					document.location = '/videos_divide/step_one/' + response.videoId;
				} else {
					alert(response.error);
				}
			}
		});
	},
	appendSlaveForm: function(frm) {
		div = document.createElement("div");
		div.innerHTML = $('part_template').innerHTML;
		$('part_list').appendChild(div);
		this._arrangeParts(frm);
	},
	detachSlaveForm: function(frm, div) {
		div.up().remove();
		this._arrangeParts(frm);
	},
	_arrangeParts: function(frm) {
		count = this._getPartCount(frm);
		if (1 == count) {
			frm['part1[]'].value = 1;
			frm['part2[]'].value = 1;
		} else {
			for (i = 0; i < count; i++) {
				frm['part1[]'][i].value = (i+1);
				frm['part2[]'][i].value = count;
			}
		}
	},
	_getPartCount: function(frm) {
		if ("undefined" == typeof frm['url[]']) {
			return 0;
		} else if ("undefined" == typeof frm['url[]'].length) {
			return 1;
		} else {
			return frm['url[]'].length;
		}
	},
	clear: function(frm) {
		new Ajax.Request("/videos_divide/clear/" + frm.videoId.value, {
			asynchronous :false,
			evalScripts: false,
			parameters: null,
			onComplete: function(trasnport, response) {
				if ('success' == response.result) {
					document.location = '/videos_divide/step_one/' + response.videoId;
				} else {
					alert(response.error);
				}
			}
		});
	},
	clearTarget: function(frm) {
		new Ajax.Request("/videos_divide/clear_target/" + frm.videoId.value, {
			asynchronous :false,
			evalScripts: false,
			parameters: null,
			onComplete: function(trasnport, response) {
				if ('success' == response.result) {
					document.location = '/videos_divide/step_one/' + response.videoId;
				} else {
					alert(response.error);
				}
			}
		});
	},
	nextStep: function(frm) {
		count = this._getPartCount(frm);
		if (count < 2) {
			alert('part video is more 2');
			return false;
		}
		
		for (i = 0; i < count; i++) {
			if ( ! ViiKii.VideoForm.isValidURL(frm['url[]'][i].value)) {
				alert("input valid video URL");
				frm['url[]'][i].focus();
				return;
			}
		}
		
		new Ajax.Request('/videos_divide/next_step/' + frm.videoId.value, {
			asynchronous :false,
			evalScripts: false,
			parameters: Form.serialize(frm),
			onComplete: function(trasnport, response) {
				if ('success' == response.result) {
					document.location = '/videos_divide/step_two/1';
				} else {
					alert(response.error);
				}
			}
		});
	},
	formed: function(v) {
		formed = "" + v;
		if (formed.length < 2) {
			return "0" + formed;
		}
		return formed;
	},
	time2msec: function(h, m, s, ms) {
		return h * 3600000 + m * 60000 + s * 1000 + ms * 10;
	},
	msec2timed: function(msec) {
		h = parseInt(msec / 3600000);
		remn = msec % 3600000;
		m = parseInt(remn / 60000);
		remn = parseInt(remn % 60000);
		s = parseInt(remn / 1000);
		remn = parseInt(remn % 1000);
		ms = parseInt(remn/10);
		return {'h':h, 'm':m, 's':s, 'ms':ms};
	},
	getStartMsec: function() {
		return this.time2msec($('sh').value, $('sm').value, $('ss').value, $('sms').value);
	},
	getEndMsec: function() {
		return this.time2msec($('eh').value, $('em').value, $('es').value, $('ems').value);
	},
	getLengthMsec: function() {
		return this.getEndMsec() - this.getStartMsec();
	},
	prevPartLoad: function() {
		if (this._currentIndex > 0) {
			this._currentIndex--;
			this.updatePartIndexLayer();
			this.updateTimeInputBox();
			this.loadPlayerPartVideo();
		}
	},
	nextPartLoad: function() {
		if (this._currentIndex < this._partVideos.length - 1) {
			this._currentIndex++;
			if (this._partVideos[this._currentIndex]['start'] == 0 && this._partVideos[this._currentIndex]['length'] == 0) {
				this._partVideos[this._currentIndex]['start'] = this._partVideos[this._currentIndex - 1]['start'] + this._partVideos[this._currentIndex - 1]['length'];
			}
			this.updatePartIndexLayer();
			this.updateTimeInputBox();
			this.loadPlayerPartVideo();
		}
	},
	updatePartIndexLayer: function() {
		$('part_index_layer').update(this._currentIndex + 1);
	},
	loadPlayerPartVideo: function() {
		alert('to do something for player - load part video');
	},
	setPartLength: function(msec) {
		this._partVideos[this._currentIndex]['length'] = msec;
	},
	setPartPos: function(pos) {
		this._partVideos[this._currentIndex]['start'] = msec;
	},
	updateTimeInputBox: function() {
		var start = this._partVideos[this._currentIndex]['start'];
		var length = this._partVideos[this._currentIndex]['length'];
		timed = this.msec2timed(Math.abs(start));
		$('sh').value = (start < 0) ? "-"+timed['h']: timed['h'];
		$('sm').value = this.formed(timed['m']);
		$('ss').value = this.formed(timed['s']);
		$('sms').value = this.formed(timed['ms']);
		
		timed = this.msec2timed(Math.abs(start + length));
		$('eh').value = timed['h'];
		$('em').value = this.formed(timed['m']);
		$('es').value = this.formed(timed['s']);
		$('ems').value = this.formed(timed['ms']);
	},
	changedStartTime: function() {
		msec = this.time2msec($('sh').value, $('sm').value, $('ss').value, $('sms').value);
		this.setPartPos(msec);
		this.updateTimeInputBox();
	},
	save: function() {
		for (i = 0; i < this._partVideos.length; i++) {
			if (this._partVideos[i]['length'] == 0) {
				alert("part " + (i+1) + " length is zero.");
				return false;
			}
		}
		
		params = "";
		for (i = 0; i < this._partVideos.length; i++) {
			params += "parts[" + this._partVideos[i]['id'] + "][start]=" + this._partVideos[i]['start'] + 
					"&parts[" + this._partVideos[i]['id'] + "][length]=" + this._partVideos[i]['length'] + "&";
		}
		
		new Ajax.Request("/videos_divide/divide/", {
			asynchronous :false,
			evalScripts: false,
			parameters: params,
			onComplete: function(trasnport, response) {
				if ("success" == response.result) {
					document.location = response.url;
				} else {
					alert(response.error);
				}
			}
		});
	},
	divide: function() {
		new Ajax.Request("/videos_divide/divide/", {
			asynchronous :false,
			evalScripts: false,
			parameters: params,
			onComplete: function(trasnport, response) {
				if ("success" == response.result) {
					document.location = response.url;
				} else {
					alert(response.error);
				}
			}
		});
	},
	appendPart: function(id, url, start, length) {
		this._partVideos.push({'id':id, 'url':url, 'start':start, 'length':length});
	}
};//ViiKii.Video.Divide

ViiKii.Video.MergeFrm = {
	_currentIndex: 0,
	_length: 0,
	_partVideos: [],
	appendPart: function(videoId, url, start, length) {
		this._partVideos.push({'videoId':videoId, 'url':url, 'start':start, 'length':length});
	},
	nextStep: function(frm) {
		if ( frm.url.value.trim().empty()) {
			alert("input the URL");
			frm.url.focus();
			return;
		} else if ( ! ViiKii.VideoForm.isValidURL(frm.url.value.trim())) {
			alert("input valid video URL");
			frm.url.focus();
			return;
		}
		
		new Ajax.Request("/videos_merge/go_next", {
			asynchronous :false,
			evalScripts: false,
			parameters: Form.serialize(frm),
			onComplete: function(transport, response) {
				if ('success' == response.result) {
					document.location = '/videos_merge/step_two/1';
				} else {
					alert(response.error);
				}
			}
		});
	},
	formed: function(v) {
		formed = "" + v;
		if (formed.length < 2) {
			return "0" + formed;
		}
		return formed;
	},
	time2msec: function(h, m, s, ms) {
		return h * 3600000 + m * 60000 + s * 1000 + ms * 10;
	},
	msec2timed: function(msec) {
		h = parseInt(msec / 3600000);
		remn = msec % 3600000;
		m = parseInt(remn / 60000);
		remn = parseInt(remn % 60000);
		s = parseInt(remn / 1000);
		remn = parseInt(remn % 1000);
		ms = parseInt(remn/10);
		return {'h':h, 'm':m, 's':s, 'ms':ms};
	},
	getStartMsec: function() {
		return this.time2msec($('sh').value, $('sm').value, $('ss').value, $('sms').value);
	},
	getEndMsec: function() {
		return this.time2msec($('eh').value, $('em').value, $('es').value, $('ems').value);
	},
	getLengthMsec: function() {
		return this.getEndMsec() - this.getStartMsec();
	},
	prevPartLoad: function() {
		if (this._currentIndex > 0) {
			this._currentIndex--;
			this.updatePartIndexLayer();
			this.updateTimeInputBox();
			this.loadPlayerPartVideo();
		}
	},
	nextPartLoad: function() {
		if (this._currentIndex < this._partVideos.length - 1) {
			this._currentIndex++;
			if (this._partVideos[this._currentIndex]['start'] == 0 && this._partVideos[this._currentIndex]['length'] == 0) {
				this._partVideos[this._currentIndex]['start'] = this._partVideos[this._currentIndex - 1]['start'] + this._partVideos[this._currentIndex - 1]['length'];
			}
			this.updatePartIndexLayer();
			this.updateTimeInputBox();
			this.loadPlayerPartVideo();
		}
	},
	updatePartIndexLayer: function() {
		$('part_index_layer').update(this._currentIndex + 1);
	},
	setPartLength: function(msec) {
		this._partVideos[this._currentIndex]['length'] = msec;
	},
	setPartPos: function(msec) {
		this._partVideos[this._currentIndex]['start'] = msec;
	},
	loadPlayerPartVideo: function() {
		alert('to do something for player - load part video');
	},
	updateTimeInputBox: function() {
		var start = this._partVideos[this._currentIndex]['start'];
		var length = this._partVideos[this._currentIndex]['length'];
		
		timed = this.msec2timed(Math.abs(start));
		$('sh').value = (start < 0) ? "-"+timed['h']: timed['h'];
		$('sm').value = this.formed(timed['m']);
		$('ss').value = this.formed(timed['s']);
		$('sms').value = this.formed(timed['ms']);
		
		timed = this.msec2timed(Math.abs(start + length));
		$('eh').value = timed['h'];
		$('em').value = this.formed(timed['m']);
		$('es').value = this.formed(timed['s']);
		$('ems').value = this.formed(timed['ms']);
	},
	changedStartTime: function() {
		msec = this.time2msec($('sh').value, $('sm').value, $('ss').value, $('sms').value);
		this.setPartPos(msec);
		this.updateTimeInputBox();
	},
	save: function() {
		for (i = 0; i < this._partVideos.length; i++) {
			if (this._partVideos[i]['length'] == 0) {
				alert("part " + (i+1) + " length is zero.");
				return false;
			}
		}
		
		params = "";
		for (i = 0; i < this._partVideos.length; i++) {
			params += "parts[" + this._partVideos[i]['videoId'] + "][start]=" + this._partVideos[i]['start'] + 
					"&parts[" + this._partVideos[i]['videoId'] + "][length]=" + this._partVideos[i]['length'] + "&";
		}
		
		new Ajax.Request('/videos_merge/merge', {
			asynchronous :false,
			parameters: params,
			evalScripts: false,
			onComplete: function(transport, response) {
				if ('success' == response.result) {
					document.location = "/videos/watch/" + response.videoId;
				} else {
					alert(response.error);
				}
			}
		});
	}
};//ViiKii.Video.MergeFrm

ViiKii.Video.Upload = {
	upload: function() {
		if(!$('file').value) {
			alert('Select available file first!');
			return;
		}
		$('s3form').submit();
	},
	loadPage: function(curPage) {
		new Ajax.Updater(
			'aws_videos',
			'/aws_video/aws_videos/'+curPage,
			{ evalScripts: true }
		);
	},
	refresh: function() {
		this.loadPage($('aws_videos_cur_page').value);
	},
	changeVideo: function(rowId) {
		var videoId = $$('#aw_video_'+rowId+' .video_id')[0];
		var filename = $$('#aw_video_'+rowId+' .filename')[0];
		var params = $H({'filename': filename.value}).toQueryString();
//		alert(videoId.value);
		new Ajax.Request(
			'/aws_video/change_video/'+rowId+'/'+videoId.value,
			{
				evalScripts: true,
				parameters: params,
				onComplete: this.onChangeVideo.bind(this)
			}
		);
	},
	onChangeVideo: function(transport, response) {
		if(response.result == 'SUCCESS') {
			alert('Changed successfully!');
			this.refresh();
			return;
		}
		switch(response.error) {
		case 'NOT_ADMIN':
			alert('You are not an administrator.');
			return;
		case 'DB_ERROR':
			alert('Fail to change. Please try again.');
			return;
		case 'INVALID_VIDEO':
			alert('Invalid Video ID');
			return;
		case 'INVALID_AWS_VIDEO':
			alert('Invalid Uploaded Video ID');
			return;
		}
	}
};
ViiKii.Video.Plugin = {
	onCompletes: {},
	check: function(youtubeId, onComplete) {
		$('viikiidetect').initDetect();
		ViiKii.Video.Plugin.onCompletes[youtubeId] = onComplete;
		$('viikiidetect').detectPlugIn(youtubeId);
	},
	returnStream: function(youtubeId, streamUrl) {
		if (typeof ViiKii.Video.Plugin.onCompletes[youtubeId] != "function") {
			return;
		}
//		alert('return stream '+youtubeId+' '+streamUrl);
		ViiKii.Video.Plugin.onCompletes[youtubeId].apply(this, [youtubeId, streamUrl]);
	}
};var not_whitespace = new RegExp(/[^\s]/);//This can be given inside the funciton - I made it a global variable to make the scipt a little bit faster.
var parent_count;

ViiKii.XML = {
	xml2array: function(xmlDoc, parent_count) {
		var arr;
		var parent = "";
		parent_count = parent_count || new Object;
	
		var attribute_inside = 0; /*:CONFIG: Value - 1 or 0
		*	If 1, Value and Attribute will be shown inside the tag - like this...
		*	For the XML string...
		*	<guid isPermaLink="true">http://www.bin-co.com/</guid>
		*	The resulting array will be...
		*	array['guid']['value'] = "http://www.bin-co.com/";
		*	array['guid']['attribute_isPermaLink'] = "true";
		*	
		*	If 0, the value will be inside the tag but the attribute will be outside - like this...	
		*	For the same XML String the resulting array will be...
		*	array['guid'] = "http://www.bin-co.com/";
		*	array['attribute_guid_isPermaLink'] = "true";
		*/
	
		if(xmlDoc.nodeName && xmlDoc.nodeName.charAt(0) != "#") {
			if(xmlDoc.childNodes.length > 1) { //If its a parent
				arr = new Object;
				parent = xmlDoc.nodeName;
			}
		}
		var value = xmlDoc.nodeValue;
		if(xmlDoc.parentNode && xmlDoc.parentNode.nodeName && value) {
			if(not_whitespace.test(value)) {//If its a child
				arr = new Object;
				arr[xmlDoc.parentNode.nodeName] = value;
			}
		}
	
		if(xmlDoc.childNodes.length) {
			if(xmlDoc.childNodes.length == 1) { //Just one item in this tag.
				arr = xml2array(xmlDoc.childNodes[0],parent_count); //:RECURSION:
			} else { //If there is more than one childNodes, go thru them one by one and get their results.
				var index = 0;
	
				for(var i=0; i<xmlDoc.childNodes.length; i++) {//Go thru all the child nodes.
					var temp = xml2array(xmlDoc.childNodes[i],parent_count); //:RECURSION:
					if(temp) {
						var assoc = false;
						var arr_count = 0;
						for(key in temp) {
							if(isNaN(key)) assoc = true;
							arr_count++;
							if(arr_count>2) break;//We just need to know wether it is a single value array or not
						}
	
						if(assoc && arr_count == 1) {
							if(arr[key]) { 	//If another element exists with the same tag name before,
											//		put it in a numeric array.
								//Find out how many time this parent made its appearance
								if(!parent_count || !parent_count[key]) {
									parent_count[key] = 0;
	
									var temp_arr = arr[key];
									arr[key] = new Object;
									arr[key][0] = temp_arr;
								}
								parent_count[key]++;
								arr[key][parent_count[key]] = temp[key]; //Members of of a numeric array
							} else {
								parent_count[key] = 0;
								arr[key] = temp[key];
								if(xmlDoc.childNodes[i].attributes.length) {
									for(var j=0; j<xmlDoc.childNodes[i].attributes.length; j++) {
										var nname = xmlDoc.childNodes[i].attributes[j].nodeName;
										if(nname) {
											/* Value and Attribute inside the tag */
											if(attribute_inside) {
												var temp_arr = arr[key];
												arr[key] = new Object;
												arr[key]['value'] = temp_arr;
												arr[key]['attribute_'+nname] = xmlDoc.childNodes[i].attributes[j].nodeValue;
											} else {
											/* Value in the tag and Attribute otside the tag(in parent) */
												arr['attribute_' + key + '_' + nname] = xmlDoc.childNodes[i].attributes[j].nodeValue;
											}
										}
									} //End of 'for(var j=0; j<xmlDoc. ...'
								} //End of 'if(xmlDoc.childNodes[i] ...'
							}
						} else {
							arr[index] = temp;
							index++;
						}
					} //End of 'if(temp) {'
				} //End of 'for(var i=0; i<xmlDoc. ...'
			}
		}
	
		if(parent && arr) {
			var temp = arr;
			arr = new Object;
			
			arr[parent] = temp;
		}
		return arr;		
	}
};
