//  August Chat System
//  Copyright (c) 2000-2009 by August
//  www:  http://www.august4u.ru/
//  file: august.js


GECKO   = "Components" in window
SAFARI3 = "devicePixelRatio" in window
IE      = "ActiveXObject" in window ? /MSIE (\d\.\d)/i.test (navigator.userAgent) ? parseInt (RegExp.$1 * 10) : 10 : 0
OPERA   = "opera" in window ? /Opera[\/ ](\d\.\d)/i.test (navigator.userAgent) ? parseInt (RegExp.$1 * 10) : 10 : 0
WEBKIT2 = "Plugin" in window

STYLE_INP = "class=inp onFocus=id=className onBlur=id=''"
STYLE_BTN = "class=btn onMouseOver=id=className onMouseOut=id='' onMouseDown=id=className+'p' onMouseUp=id=className"


function $ ( win, el ) {
	return win.document.getElementById (el)
}

function $$ ( e ) {
	return IE ? e.srcElement : (e.target.tagName ? e.target : e.target.parentNode)
}

function isset ( el ) {
	return typeof el != "undefined"
}

Number.prototype.hex = function () {
	return (this >> 4).toString (16) + (this & 0x0f).toString (16)
}

Number.prototype.ip = function () {
	return this ? ((this >> 24) & 0xff) + "." + ((this >> 16) & 0xff) + "." + ((this >> 8) & 0xff) + "." + (this & 0xff) : ""
}

String.prototype.trim = function () {
	return this.replace (/^\s+|\s+$/, "")
}

String.prototype.striptags = function () {
	return this.replace (/<\/?[!a-zA-Z][^>]*>/g, "")
}

String.prototype.htmlentities = function () {
	return this.replace (/['"&<>]/g, function ( $0 ) { return "&#" + $0.charCodeAt (0) + ";" })
}

String.prototype.addslashes = function () {
	return this.replace (/(['"\\])/g, "\\$1")
}

String.prototype.safeRE = function () {
	return this.replace (/([\][}{)(?$*+.|])/g, "\\$1")
}

String.prototype.sreplace = function ( f, r ) {
	return this.split (f).join (r)
}

String.prototype.mreplace = function ( f, r ) {
	var s = this
	for (var i = 0; i < f.length; i++) {
		if (f [i])
			s = s.replace (f [i], r [i])
	}
	return s
}

String.prototype.encode = function () {
	var s = this
	var ch = "%?#:;,()[]&='/\\\""
	for (var i = 0; i < ch.length; i++)
		s = s.sreplace (ch.charAt (i), "%" + ch.charAt (i).charCodeAt ().hex ())
	for (var i = 0; i < 32; i++)
		s = s.sreplace (String.fromCharCode (i), "%" + i.hex ())
	return s
}

String.prototype.text = function () {
	return this.replace (/<img.*? text=(['"`])(.+?)\1.*>/g, "").striptags ()
}

String.prototype.re = {
	t: /%([A-Z0-9_]+)(?:\((.*?)\))?%/g,
	c: /%\?(.+?)(%:%(.+?))?\?%/g,
	p: /^(.*?)\{\{\{(.+)(?:\|\|\|(.+))?\}\}\}(.*)$/
}

String.prototype.tpl = function ( re, o ) {
	function t ( $0, $1, $2 ) {
		if (!re [$1])
			return $0
		var r = re [$1] ($2 ? $2.split ("\\\\") : $2, $2)
		c.t++
		if (r)
			c.r++
		return r ? r.toString ().sreplace ("%", "&#37;") : r
	}
	function c ( $0, $1, $2, $3 ) {
		c.t = 0
		c.r = 0
		var r = ret ($1)
		return c.r ? r : c.t ? $2 ? $3 : "" : $0
	}
	function ret ( s ) {
		if (!o)
			return s.replace (s.re.t, t)
		for (var n in re)
			s = s.replace (new RegExp ("%(" + n + ")(?:\\\((.*?)\\\))?%", "g"), t)
		return s
	}
	return ret (this.replace (/[\r\n]+/g, " ").replace (this.re.c, c))
}

String.prototype.pattern = function ( re, n ) {
	var n = n || 0
	if (!re [n])
		return this
	var t = this.replace (/[\r\n]+/g, " ").match (this.re.p)
	if (!t)
		return this
	var r = ""
	for (var i = 0; i < re [n].$size (); i++) {
		re [n].$set (i)
		r += t [2].pattern (re, n + 1).tpl (re [n])
	}
	return r.length ? t [1] + r + t [4] : t [3] ? t [1] + t [3] + t [4] : r
}

String.prototype.color = function ( Clrs ) {
	function l ( s ) {
		do {
			var l = s.length
			s = s.replace (/[^]+/g, "")
		} while (l != s.length)
		return s.mreplace ([/<[^>]+>?/g, / +/g, /&([a-zA-Z]{2,}\d*|#\d+|#x[\da-fA-F]{2});/g], ["", "", "."]).length
	}
	function c ( r, g, b, s ) {
		return "<font color=#" + r.hex () + g.hex () + b.hex () + ">" + s + "</font>"
	}
	function g ( c1, c2, l, s ) {
		var c1 = parseInt (c1.substr (1), 16)
		var c2 = parseInt (c2.substr (1), 16)
		var r1 = c1 >> 16, g1 = (c1 >> 8) & 0xff, b1 = c1 & 0xff
		var r2 = c2 >> 16, g2 = (c2 >> 8) & 0xff, b2 = c2 & 0xff
		var res = ""
		var d = l - s
		r2 -= r1
		g2 -= g1
		b2 -= b1
		for (var i = 0; iS < Str.length;) {
			var ch = Str.charAt (iS)
			if (ch == '<') {
				for (var t = 0; iS < Str.length; iS++) {
					res += Str.charAt (iS)
					if (Str.charAt (iS) == '')
						t++
					else if (Str.charAt (iS) == '')
						t--
					else if (Str.charAt (iS) == '>' && !t)
						break
				}
				iS++
			} else if (ch == ' ') {
				res += d ? c (r1 + i * r2 / d, g1 + i * g2 / d, b1 + i * b2 / d, ch) : c (r1, g1, b1, ch)
				iS++
			} else if (i != l) {
				if (ch == '&' && /^(&([a-zA-Z]{2,}\d*|#\d+|#x[\da-fA-F]{2});)/.test (Str.substr (iS)))
					ch = RegExp.$1
				res += d ? c (r1 + i * r2 / d, g1 + i * g2 / d, b1 + i * b2 / d, ch) : c (r1, g1, b1, ch)
				iS += ch.length
				i++
			} else
				break
		}
		return res
	}

	var Str = this
	var Len = l (Str)
	if (!Len)
		return Str
	var cs = Clrs.split ("-")
	var c0 = cs [0]
	var n = cs.length - 1
	if (!n)
		return "<font color='" + c0 + "'>" + Str + "</font>"
	var d = 0
	var res = ""
	var iS = 0
	for (var i = 1; i < n; i++) {
		var d0 = Math.floor (i * Len / n)
		if (d0 == d || !cs [i])
			continue
		res += g (c0, cs [i], d0 - d, 0)
		c0 = cs [i]
		d = d0
	}
	return res + g (c0, cs [i], Len - d, 1)
}

function august_addEvent ( el, event, handler ) {
	if (el.addEventListener)
		el.addEventListener (event, handler, false)
	else if (window.attachEvent)
		el.attachEvent ("on" + event, handler._ev_handler = function ( e ) { return handler.call (el, e) })
	else
		el ["on" + event] = handler
}

function august_removeEvent ( el, event, handler ) {
	if (el.removeEventListener) {
		el.removeEventListener (event, handler, false)
	} else if (window.detachEvent) {
	 	el.detachEvent ("on" + event, handler._ev_handler)
		handler._ev_handler = null
	}
}

function august_stopEvent ( e ) {
	if (e.stopPropagation)
		e.stopPropagation ()
	if (e.preventDefault)
		e.preventDefault ()
	e.cancelBubble = true
	e.returnValue = false
	return false
}

function august_start ( win, init ) {
	function run () {
		if (init.run)
			return
		init.run = true
		init ()
	}
	if (init.init)
		return
	init.init = true
	if (IE)
		return run ()
	if (win.document.addEventListener)
		win.document.addEventListener ("DOMContentLoaded", run, false)
	win.onload = run
}

function august_noselect ( el ) {
	if (IE)
		el.onselectstart = el.ondragstart = function () { return false }
	else if (isset (el.style.UserSelect))
		el.style.UserSelect = "none"
	else if (isset (el.style.MozUserSelect))
		el.style.MozUserSelect = "none"
	else if (isset (el.style.WebkitUserSelect))
		el.style.WebkitUserSelect = "none"
}

function august_wo ( URL, Name, w, h, f, l, t ) {
	var w = Math.min (w || document.body.clientWidth, screen.availWidth - 20)
	var h = Math.min (h || document.body.clientHeight, screen.availHeight - 80)
	var o = open
	var p = [
		"scrollbars=" + (f & 1),
		"resizable=" + (f & 2 ? 1 : 0),
		"menubar=" + (f & 4 ? 1 : 0),
		"toolbar=" + (f & 8 ? 1 : 0),
		"location=" + (f & 16 ? 1 : 0),
		"status=" + (f & 32 ? 1 : 0),
		"width=" + w,
		"height=" + h
	]
	if (f & 64) {
		p.push ("left=" + (screen.availWidth - w - 10 >> 1))
		p.push ("top=" + (screen.availHeight - h - 80 >> 1))
	} else if (l && t) {
		p.push ("left=" + l)
		p.push ("top=" + t)
	}
	var p = p.join (",")
	return /^http:/i.test (URL) ? o (URL, "_blank", p) : o (URL || (window.opera ? "" : "about:blank"), Name, p)
}

function august_pattern ( s, re ) {
	return s.pattern (re)
}

function august_gradient ( s, c ) {
	return s.color (c)
}

function august_extend ( Child, Parent ) {
	var f = function () {}
	f.prototype = Parent.prototype
	Child.prototype = new f ()
	Child.prototype.constructor = Child
	Child.superclass = Parent.prototype
}

function august_now () {
	return +new Date
}

AUGUST_HTML = {
	img:		function ( $0, $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11 ) { function a ( n, v ) { return (v || v === 0) ? " " + n + "='" + v + "'" : "" }; return "<img" + a ("src", $1) + a ("width", $2) + a ("height", $3) + a ("border", $4) + a ("style", $5 ? "vertical-align: " + ($5 == "absmiddle" ? "middle" : $5) + ";" + $9 : $9) + a ("hspace", $6) + a ("vspace", $7) + a ("title", $8) + a ("name", $0 ? "" : $10) + ($0 ? "" : ($11 || "")) + ">" },
	color:		function ( $0, $1, $2, $3, $4 ) { var m = AUGUST_HTML.$opt & 64 || !$1 ? $4 : $4.color ($1); return $3 == "0" ? $2 ? "<font style='font-family: " + $2 + "' >" + m + "</font >" : m : "<font " + ($2 ? "style='font-family: " + $2 + "'" : "") + " class=m" + $3 + " >" + m + "</font >" },
	graph:		function ( $0, $1, $2, $3, $4, $5, $6 ) { return AUGUST_HTML.$opt & 32 ? $6 : AUGUST_HTML.img ("", "/people/nick/" + $1 + "." + $2, $3, $4, 0, "", "", "", $6, $5 != 0 ? IE && IE < 60 ? "position: relative; top: " + $5 + "px" : "vertical-align: -" + $5 + "px" : "", ">" + $6 + "<") + "<!---->" },
	smile:		function ( $0, $1, $2, $3, $4, $5, $6 ) { return AUGUST_HTML.$opt & 16 ? $6 : AUGUST_HTML.img ("", "/smiles/" + $1 + "." + $2, $3, $5, 0, $4 == "O" || $4 == "X" ? "absmiddle" : "", "", "", $6, "", ">" + $6 + "<", $4 == "o" || $4 == "O" ? " x=o onClick='root.smClick.call (Chat, this)' onMouseOver='root.smOver.call (Chat, this)'" : "") },
	flag:		function ( $0, $1, $2, $3 ) { var s = $2 == ";"; return AUGUST_HTML.img ("", s ? "/images/small-flags/" + $1 + ".gif" : "/images/flags/" + $1 + ".gif", s ? 18 : 29, s ? 12 : 20, 0, "absmiddle", "", "", $3) },
	media:		function ( $0, $1, $2 ) { if (!($2 && /\bsrc *= *(?:['"`] *)?(?:http|ftp):/i.test ($0))) return "&lt;" + $0.substr (1); var i = AUGUST_HTML.MediaSuppress [$1.toLowerCase ()]; if ((AUGUST_HTML.$opt >> 16) & i.m) return $0; return "<span><img src=" + i.p + " width=" + i.w + " height=" + i.h + " border=0 onClick='this.parentNode.innerHTML = \"&shy;" + $0.addslashes ().htmlentities () + "\"'></span>" },
	time:		function ( $0, $1 ) { function dd ( d ) { return "<span class=tm2>" + (d < 10 ? "0" + d : d) + "</span>" } var Time = (parseInt ($1) + 86400 + ((AUGUST_HTML.$opt & 524288) ? -(new Date ()).getTimezoneOffset () * 60 : cfg.TimeCorrect + Chat.TimeZone)) % 86400; var TIME = dd (parseInt (Time / 3600)) + ":" + dd (parseInt (Time / 60) % 60) + ":" + dd (Time % 60); return "<span class=tm>" + (cfg.TimeStyle.length ? cfg.TimeStyle.replace ("TIME", TIME) : TIME) + "</span>" },
	url:		function ( $0, $1 ) { return cfg.Clickable ? "<a href='r?" + $1 + "' target=_blank>" + $1 + "</a>" : $1 },
	email:		function ( $0, $1 ) { return cfg.Clickable ? "<a href='mailto:" + $1 + "'>" + $1 + "</a>" : $1 },
	system:		function ( $0, $1, $2 ) { return "<div class=s" + $1 + ">" + $2 + "</div s>" },
	system2:	function ( $0, $1, $2 ) { return "<span class=s" + $1 + ">" + $2 + "</span s>" },
	mess:		function ( m, opt ) { this.$opt = opt; return ((((opt >> 16) & 3) == 3 || this.SYSTEM_RE.test (m)) ? m : m.replace (this.MEDIA_RE, this.media)).mreplace (this.mess_re (), this.mess_html ()) },
	nick:		function ( n, t ) { this.$opt = 0; return n.mreplace ([this.SMILE_RE, this.GRAPH_NICK_RE, this.GRADIENT_RE, this.COLOR_RE], [root.User.Set & 16 || t ? "$6" : this.smile, root.User.Set & 32 || t ? "$6" : this.graph, t ? "$4" : this.color, t ? "$4" : this.color]) },
	html:		function ( m ) { this.$opt = 0; return m.mreplace ([this.GRADIENT_RE, this.IMG_RE], [this.color, this.img]) },
	text:		function ( t ) { return t.text () },

	EMAIL_RE:	/\b([-\w\.]+@([-\w]+\.)+[a-z]{2,4})(?!.*<!>)\b/gi,
	URL_RE:		/(\b(?!<[^>]*)(https?|ftp):(\/\/|\\\\)(([-\w]+\.)+[a-z]{2,4}\.?|\d+\.\d+\.\d+\.\d+)(:\d+)?[^<>'"`- ]*(?![^<]*>)\b\/?)/gi,
	COLOR_RE:	/([^:-]*):([^:]*):(\d?)([^]*)/g,
	GRADIENT_RE:	/((?:(?:#[\da-fA-F]{6}|)-)+#[\da-fA-F]{6}):([^:]*):(\d?)([^]*)/g,
	GRAPH_NICK_RE:	/([\da-f]{8})(...)(\d+)x(\d+)%(-?\d*)([^]+)/g,
	SMILE_RE:	/(\d{7})(...)(\d+)([xoXO])(\d+)([^]+)/g,
	IMG_RE:		/([^]+)([^]*)([^]*)([^]*)([^]*)([^]*)([^]*)([^]*)([^]*)/g,
	FLAG_RE:	/([a-z]{2})([:;])([^]*)/g,
	SYSTEM_RE:	/^(\d)([^]*)$/,
	SYSTEM2_RE:	/(\d)([^]*)/g,
	NICK_RE:	/(\d\d+)([^]+)/g,
	MEDIA_RE:	/<(embed|bgsound|img|image)\b[^>]+(>?)/gi,

	mess_re:	function () { return [this.SMILE_RE, this.NICK_RE, this.GRAPH_NICK_RE, this.IMG_RE, this.EMAIL_RE, this.URL_RE, this.COLOR_RE, this.GRADIENT_RE, this.GRADIENT_RE, this.COLOR_RE, this.FLAG_RE, this.SYSTEM_RE, this.SYSTEM2_RE, /(\d+)/] },
	mess_html:	function () { return [this.smile, "<a class=n i=$1 onClick='return false' href=/>$2</a n><!>", this.graph, this.img, this.email, this.url, this.color, this.color, this.color, this.color, this.flag, this.system, this.system2, this.time] },

	MediaSuppress:	{
		embed:	{ p: "/images/mediaplayer.gif", w: 138, h: 25, m: 2 },
		bgsound:{ p: "/images/playsound.gif",   w: 107, h: 25, m: 2 },
		img:	{ p: "/images/showpicture.gif", w: 129, h: 25, m: 1 },
		image:	{ p: "/images/showpicture.gif", w: 129, h: 25, m: 1 }
	}
}
