/*  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',	'an',	'ar',	'ag',	
		'hy',	'ra',	'as',	'at',	'av',	'ay',	'az',	'bm',	'ba',	'be',	
		'eu',	'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',	
		'mt',	'mg',	'ms',	'ml',	'mk',	'gv',	'mi',	'mr',	'mh',	'mp',	
		'zm',	'mo',	'mn',	'nh',	'no',	'ne',	'na',	'or',	'oc',	'nn',	
		'om',	'pi',	'ps',	'fa',	'pt',	'pl',	'pa',	'qu',	'ro',	'rm',	
		'ru',	'rw',	'sm',	'sg',	'gd',	'sc',	'sa',	'sr',	'tn',	'sh',	
		'sn',	'sb',	'si',	'sd',	'se',	'sk',	'sl',	'so',	'es',	'st',	
		'tl',	'sw',	'ss',	'sv',	'su',	'tg',	'ta',	'tt',	'te',	'th',	
		'bo',	'ti',	'tp',	'tq',	'to',	'ts',	'tr',	'tk',	'tw',	'uk',	
		'ur',	'ug',	'uz',	'vi',	'vo',	'wa',	'cy',	'xh',	'wo',	'fy',	
		'yi',	'yo',	'za',	'zu'
	],
	_language : [
	   'Abkhazian',	'Afar',	'Afrikaans',	'Akan',	'Albanian',	
		'Alemannic',	'Amharic',	'Aragonese',	'Arabic',	'Anglo-Saxon',	
		'Armenian',	'Aromanian',	'Assamese',	'Asturian',	'Avar',	
		'Aymara',	'Azeri',	'Bambara',	'Bashkir',	'Belarusian',	
		'Basque',	'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',	
		'Maltese',	'Malagasy',	'Malay',	'Malayalam',	'Macedonian',	
		'Manx',	'Maori',	'Marathi',	'Marshallese',	'Micronesian-Pni',	
		'Min Nan',	'Moldovan',	'Mongoloian',	'Nahuatl',	'Norwegian (BokmÃ¥l)',	
		'Nepali',	'Nauruan',	'Oriya',	'Occitan',	'Norwegian (Nynorsk)',	
		'Oromo',	'Pali',	'Pashto',	'Persian',	'Portuguese',	
		'Polish',	'Punjabi',	'Quechua',	'Romanian',	'Raeto Romance',	
		'Russian',	'Rwandi',	'Samoan',	'Sango',	'Scottish Gaelic',	
		'Sardinian',	'Sanskrit',	'Serbian',	'Setswana',	'Serbo-Croatian',	
		'Shona',	'Sicilian',	'Sinhalese',	'Sindhi',	'Simple English',	
		'Slovak',	'Slovenian',	'Somali',	'Spanish',	'Southern Sotho',	
		'Tagalog',	'Swahili',	'Swati',	'Swedish',	'Sundanese',	
		'Tajik',	'Tamil',	'Tatar',	'Telugu',	'Thai',	
		'Tibetan',	'Tigrinya',	'Tok Pisin',	'Tokipona',	'Tongan',	
		'Tsonga',	'Turkish',	'Turkmen',	'Twi',	'Ukrainian',	
		'Urdu',	'Uyghur',	'Uzbek',	'Vietnamese',	'VolapÃ¼k',	
		'Walloon',	'Welsh',	'Xhosan',	'Wolof',	'West Frisian',	
		'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 : '500px',
			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() {
	if(this.getFolders().length == 0) {
		alert("Select available folder first.");
		return;
	}
	var videoUrl = $('suggest_video_url').value;
	videoUrl = videoUrl.trim();
	if (videoUrl == '') {
		alert('Insert available Video URL first.');
		return;
	}

	var params = $H( {
		channel_id :$('channel_id').value,
		folder: this.getFolders()[0],
		recommendation :videoUrl
	}).toQueryString();

	new Ajax.Request(
		'/channels/add_recommendation/',
		{	
			parameters :params,
			onComplete: this.onOk.bind(this)
		}
	);
};
ViiKii.Channel.VideoList.SuggestPopup.onOk = function(transport, response) {
	if (response.result == 'SUCCESS') {
		this.close();
		ViiKii.Channel.VideoList.showList(1, $('channel_id').value);
		ViiKii.Channel.Folder.refresh($('channel_id').value);
		return;
	}
	switch (response.error) {
	case 'NOT_LOG_IN':
		this.close();
		ViiKii.Login.popUp();
		break;
	case 'EMPTY_DATA':
	case 'EMPTY_RECOMMENDATION':
		alert('Insert available video url first.');
		break;
	case 'INVALID_RECOMMENDATION':
		alert('The 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 suggest. Please try again");
		return;
	case 'NOT_PERMISSION':
		alert("You don't have permission");
		this.close();
		return;
	}
};
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() {
		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.Channels = {
	refresh: function() {
		this.loadChannels($('channel_list_cur_page').value, $('channel_list_sort_most').value, $('channel_list_sort_date').value);
	},
	loadPage: function(curPage, sortMost, sortDate) {
		this.loadChannels(curPage, $('channel_list_sort_most').value, $('channel_list_sort_date').value);
	},
	loadChannels: function(curPage, sortMost, sortDate) {
		new Ajax.Updater(
			'ViiKii.Channel.ChannelList.Channels.layer',
			'/channel_list/channel_list/'+$('channel_list_genre').value+'/'+$('channel_list_country').value+'/'+curPage+'/'+sortMost+'/'+sortDate,
			{ evalScripts:true }
		);
	},
	sortMost: function(sortMost) {
		this.loadChannels(1, sortMost, $('channel_list_sort_date').value);
	},
	sortDate: function(sortDate) {
		this.loadChannels(1, $('channel_list_sort_most').value, sortDate);
	}
};
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 = {
	del: function(channelId) {
		if(!confirm('Do you really want to delete this channel?')) {
			return;
		}
		new Ajax.Request(
			'/manage_channels/delete/'+channelId,
			{
				evalScripts: true,
				onComplete: this.onDel.bind(this)
			}
		);
	},
	onDel: function(transport, response) {
		if(response.result == 'SUCCESS') {
			alert('Successfully deleted!');
			document.location = '/';
			return;
		}
		switch(response.error) {
		case 'DB_ERROR':
			alert('Fail to delete. Please try again.');
			break;
		case 'NOT_ADMIN':
			alert('You are not an administrator.');
			break;	
		}
	}
};
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') == 'CHANNEL') {
			ViiKii.Channel.Topic.refresh.bind(ViiKii.Channel.Topic);
			ViiKii.Channel.Topic.refresh();
		}
	},
	onDeletedForum: function() {
		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;
	}
	var topicUrl = $('suggest_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/'+$('forum_id').value+'/'+this.getFolders()[0],
		{
			parameters :params,
			onComplete: this.onOk.bind(this)
		}
	);
};
ViiKii.Forum.TopicList.SuggestPopup.onOk = 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 'CHANNEL':
			this.removeFromChannel(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;
		}
	},
	removeFromChannel: 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.onRemoveFromChannel(ajax, isCopier);
	},
	onRemoveFromChannel: function(ajax, isCopier) {
		//alert(ajax.transport.responseText);
		var response = ajax.responseValue.response;
		if(response.result == 'SUCCESS') {
			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.');
			}
			ViiKii.Channel.VideoList.openDefault();
			ViiKii.Forum.Folder.refresh();
			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);
			}
			if (channel.lastIndexOf('#') != -1) {
				channel = channel.substring(0, channel.lastIndexOf('#'));
			}
			
			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() {
		$('swf').loadDestVideo("m_"+this._partVideos[this._currentIndex]['videoId'], this._partVideos[this._currentIndex]['start']);
	},
	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() {
		$('swf').loadDestVideo("m_"+this._partVideos[this._currentIndex]['videoId'], this._partVideos[this._currentIndex]['start']);
	},
	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;		
	}
};
