/*
    wn (What's New)
    version 1.0 Copyright (C) 2006 Tagata Akira

    This program 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.

    This program 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 this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
    02110-1301 USA

*/

_wn.prototype = new _fss('wn','What\'s New for every visitor','1.0d','2006 Tagata Akira','http://tagata.org/software/');

/* ---------------------------------------------------------------- */
_wn.prototype._wnPathname = function (href) {

	if (this.wnHost === undefined) {
//		this.wnHost = '//' + window.location.hostname;
		this.wnHost = '//' + document.domain;
		this._log('_wnPathname(): this.wnHost:'+this.wnHost,0);
	}
	var index = href.indexOf(this.wnHost);
	var p = null;
	if (index != -1) {
		index += this.wnHost.length;
		var pathnameIndex = href.indexOf('/',index);
		if (pathnameIndex != -1) {
			var tailIndex;
//			var queryIndex = href.lastIndexOf('?',pathnameIndex);
			var queryIndex = href.indexOf('?',pathnameIndex);
			if (queryIndex != -1) {
				tailIndex = queryIndex;
			}
			else {
//				var fragmentIndex = href.lastIndexOf('#',pathnameIndex);
				var fragmentIndex = href.indexOf('#',pathnameIndex);
				if (fragmentIndex != -1) {
					tailIndex = fragmentIndex;
				}
				else {
					tailIndex = href.length;
				}
			}
			this._log('_wnPathname(): pathnameIndex:'+pathnameIndex+', queryIndex:'+queryIndex+', tailIndex:'+tailIndex,1);
			p = href.substring(pathnameIndex,tailIndex);
		}
	}

	this._log('_wnPathname(): exit href:'+href+', p:'+p,0);

	return p;
}
/* ---------------------------------------------------------------- */
_wn.prototype._wnGetPathnames = function (element) {

	this._log('_wnGetPathnames(): entered',0);

	var ret = new Array();
	if (element) {
		var p;
		var links = element.getElementsByTagName('a');
		this._log('_wnGetPathnames(): links.length:'+links.length,0);
		for (var i = 0; i < links.length; i++) {
			var href = links[i].href;
			if (href && (p = this._wnPathname(href))) {
				var j = ret.length;
				ret[j] = {};
				ret[j].p = p;		// pathname
				ret[j].e = links[i];	// element
				ret[j].t = -1;		// timestamp
			}
		}
	}
	return ret;
}
/* ---------------------------------------------------------------- */
_wn.prototype.prependZero = function (str) {
	str += '';
	if (str.length < 2) {
		str = '0'+str;
	}
	if (str.length < 2) {
		str = '0'+str;
	}
	return str;
}
/* ---------------------------------------------------------------- */
_wn.prototype.toLocalString = function (dateObj) {
	var ymd = dateObj.getFullYear()+'-'+
		this.prependZero(dateObj.getMonth()+1)+'-'+
		this.prependZero(dateObj.getDate());
	var hms = this.prependZero(dateObj.getHours())+':'+
		this.prependZero(dateObj.getMinutes())+':'+
		this.prependZero(dateObj.getSeconds());
	var secTz = dateObj.getTimezoneOffset();
	var signTz = (secTz>0)? '+': '-';
	secTz = Math.abs(secTz);
	var tz = signTz+
		this.prependZero(Math.floor(secTz/60))+':'+
		this.prependZero(Math.floor(secTz%60));

	return ymd+' '+hms+' '+tz;
}
/* ---------------------------------------------------------------- */
_wn.prototype.elementXY = function (element) {
	var curleft = 0, curtop = 0;
	if (element.offsetParent) {
		while (element.offsetParent) {
			curtop += element.offsetTop
			curleft += element.offsetLeft
			element = element.offsetParent;
		}
	}
	else {
		if (element.x)
			curleft += element.x;
		if (element.y)
			curtop += element.y;
	}
	return { x: curleft, y: curtop } ;
}
/* ---------------------------------------------------------------- */
_wn.prototype.setOpacity = function (value) {
	this.style.opacity = value/10;
	this.style.filter = 'alpha(opacity=' + value*10 + ')';
}
/* ---------------------------------------------------------------- */
_wn.prototype._wnSetNewMarkElt = function (isNew, linkElement, dateString, nmo) {

	if (isNew) {
		if (nmo._nmLinkClass) {
			linkElement.className = nmo._nmLinkClass;
		}
		else if (nmo._nmLinkBackgroundColor) {
			linkElement.style.backgroundColor = nmo._nmLinkBackgroundColor;
		}
	}
	var label = nmo._nmLinkLabel || '';
	linkElement.title = label + dateString;
}
/* ---------------------------------------------------------------- */

_nm.prototype._nmOffsetX = '5';
_nm.prototype._nmOffsetY = '5';
_nm.prototype._nmText = 'New';

_nm.prototype._nmClass = null;

_nm.prototype._nmBackgroundColor = '#ff0000';
_nm.prototype._nmColor = '#ffffff';
_nm.prototype._nmLabel = 'newer than the last visit: ';
_nm.prototype._nmPadding = '0 3px';
_nm.prototype._nmFontSize = 'smaller';
_nm.prototype._nmOpacity = 9;

_nm.prototype._nmLinkClass = null;
_nm.prototype._nmLinkBackgroundColor = '#ffcccc';
_nm.prototype._nmLinkLabel = 'Last modified: ';

function _nm(offsetX,offsetY,label,className,
		backgroundColor,color,text,padding,fontSize,opacity,
		linkClass,linkBackgroundColor,linkLabel) {

	if (offsetX)
		this._nmOffsetX = offsetX;
	if (offsetY)
		this._nmOffsetY = offsetY;
	if (text)
		this._nmText = text;

	if (className)
		this._nmClass = className;

	if (backgroundColor)
		this._nmBackgroundColor = backgroundColor;
	if (color)
		this._nmColor = color;
	if (label)
		this._nmLabel = label;
	if (padding)
		this._nmPadding = padding;
	if (fontSize)
		this._nmFontSize = fontSize;
	if (opacity)
		this._nmOpacity = opacity;

	if (linkClass)
		this._nmLinkClass = linkClass;
	if (linkBackgroundColor)
		this._nmLinkBackgroundColor = linkBackgroundColor;
	if (linkLabel)
		this._nmLinkLabel = linkLabel;
}
/* ---------------------------------------------------------------- */
_wn.prototype._wnSetNewMarkPosition = function (elt,linkElt,nmo) {
	var offsetX =
		(nmo._nmOffsetX === undefined)? 0: nmo._nmOffsetX;
	var offsetY =
		(nmo._nmOffsetY === undefined)? 0: nmo._nmOffsetY;

	var exy = this.elementXY(linkElt);
	var newMarkX = exy.x + linkElt.offsetWidth + Number(offsetX);
	var newMarkY = exy.y + Number(offsetY);

	elt.style.position = 'absolute';
	elt.style.top = newMarkY + 'px';
	elt.style.left = newMarkX + 'px';

	this._log('_wnSetNewMarkPosition(): newMarkX:'+newMarkX+', newMarkY:'+newMarkY,0);
}
/* ---------------------------------------------------------------- */
_wn.prototype._wnCreateNewMarkElement = function (linkElement,dateLastVisited,nmo) {

	var newMark = document.createElement('div');

	if (nmo._nmText !== undefined) {
		newMark.appendChild(document.createTextNode(nmo._nmText));
	}
	var newMarkLabel =
		(nmo._nmLabel === undefined)? '': nmo._nmLabel;
	newMark.title = newMarkLabel + dateLastVisited;

	if (nmo._nmClass) {
		newMark.className = nmo._nmClass;
	}
	else {
		if (nmo._nmBackgroundColor !== undefined){
			newMark.style.backgroundColor =
				 nmo._nmBackgroundColor;
		}
		if (nmo._nmColor !== undefined) {
			newMark.style.color = nmo._nmColor;
		}
		if (nmo._nmFontSize !== undefined) {
			newMark.style.fontSize = nmo._nmFontSize;
		}
		if (nmo._nmPadding !== undefined) {
			newMark.style.padding = nmo._nmPadding;
		}
		if (nmo._nmOpacity !== undefined) {
			this.setOpacity.call(newMark,nmo._nmOpacity);
		}
	}
	this._wnModifyNewMarkElement(newMark,linkElement);
	return newMark;
}
/* ---------------------------------------------------------------- */
_wn.prototype._wnResetPosition = function () {
	this._log('_wnResetPosition(): entered length:'+this.wnPn.length,0);
	for (var i = 0; i < this.wnPn.length; i++) {
		if (this.wnPn.newMarked)
			this._wnSetNewMarkPosition(this.wnPn[i].nme,this.wnPn[i].e,this.wnPn[i].nmo);
	}
}
/* ---------------------------------------------------------------- */
_wn.prototype._wnSetNewMark = function (pathname,now) {
	if (pathname.t < 0) return;

	var dateMtime = this.toLocalString(new Date(pathname.t*1000));

	if (this._wnSetNewMarkObject && this._wnCheckNewMarkObject
		&& this._wnCheckNewMarkObject(pathname.e)) {
		var nmo = this._wnSetNewMarkObject(pathname.e);
	}
	else {
		var nmo = new _nm;
	}

//	var isNew = now < pathname.t + this._wnLastVisitDefault;
	var isNew = this.lastVisited < pathname.t;
	if (isNew) {
		var dateLastVisited =
			this.toLocalString(new Date(this.lastVisited * 1000));
		var newMarkElt = this._wnCreateNewMarkElement(pathname.e,dateLastVisited,nmo);

		pathname.nmo = nmo;
		pathname.nme = newMarkElt;
		pathname.newMarked = true;
		this._wnSetNewMarkPosition(pathname.nme,pathname.e,pathname.nmo);
		document.body.appendChild(newMarkElt);
	}
	if (this._wnSetNewMarkElt !== undefined) {
		this._wnSetNewMarkElt(isNew,pathname.e,dateMtime,nmo);
	}
}
/* ---------------------------------------------------------------- */
_wn.prototype._wnPath2Mtime = function (path) {
	ret = -1;
	if (this.wnParentHostMtimes[path] !== undefined) {
		ret = Number(this.wnParentHostMtimes[path]);
	}
	this._log('_wnPath2Mtime(): exit path:'+path+', ret:'+ret,0);
	return ret;
}
/* ---------------------------------------------------------------- */
_wn.prototype._wnSetNewMarks = function () {
// called from _wn.php
	this._log('_wnSetNewMarks(): entered',0);

	this._log('_wnSetNewMarks(): this._wnIframeId:'+this._wnIframeId+', frames[this._wnIframeId].wnHostMtimes:'+frames[this._wnIframeId].wnHostMtimes,1);
	if (frames[this._wnIframeId].wnHostMtimes) {
		var hostNow = Number(frames[this._wnIframeId].wnHostNow);

		// Cookie
		if (this._wnNoCookie) {
			this.lastVisited = hostNow - this._wnLastVisitDefault;
			this.averageRecent = this._wnLastVisitDefault;
		}
		else {
			var lastVisitDefault = this._wnCookie(hostNow);
//			if (lastVisitDefault >= 0) {
//				this._wnLastVisitDefault = lastVisitDefault;
//			}
//			this._log('_wnSetNewMarks(): hostNow:'+hostNow+', lastVisitDefault:'+lastVisitDefault,1);
			this._log('_wnSetNewMarks(): hostNow:'+hostNow,1);
		}

		this.wnDateCollected = this.toLocalString(new Date(hostNow * 1000));
		this.wnParentHostMtimes =
			new frames[this._wnIframeId].wnHostMtimes();
		this._log('_wnSetNewMarks(): this.wnDateCollected:'+this.wnDateCollected,1);
		for (var i = 0; i < this.wnPn.length; i++) {
			this.wnPn[i].t = this._wnPath2Mtime(this.wnPn[i].p);
			this._wnSetNewMark(this.wnPn[i],hostNow);
		}
	}
	this._wnCompletion();
}
/* ---------------------------------------------------------------- */
_wn.prototype._wnCookie = function (now) {

	this._log('_wnCookie(): entered'+' now:'+now,0);

	var cookieObj = this.stringToObject(this.readCookie(this._cookieName));
	var cookieHist;
	var lastVisit;
	var prevVisit;

	var ptab = ['ver', 'fst', 'rfr', 'era', 'exp', 'hst', 'lst', 'prv'];
	for (var i = 0; i < ptab.length; i++) {
		if (!(ptab[i] in cookieObj)) {
			this._log('_wnCookie(): '+ptab[i]+' is not defined in cookieObj',0);
			break;
		}
	}
	if (i < ptab.length) { // error
		// the first visit assumed
		lastVisit = undefined;
		prevVisit = undefined;
	}
	else {
		cookieHist = cookieObj.hst;
		lastVisit = cookieObj.lst;
		prevVisit = cookieObj.prv;
	}


	if (prevVisit !== undefined && lastVisit !== undefined) {
		// refresh
//		if (this.refresh && this.refresh < now
//			&& prevVisit && prevVisit < this.refresh) {
		if (this.refresh < now && cookieObj.rfr < this.refresh
			|| cookieObj.ver != _wn.prototype._fssVer()) {
			// the first visit assumed
			this._log('_wnCookie(): refresh assumed'+', cookieObj.rfr:'+cookieObj.rfr+', this.refresh:'+this.refresh+', cookieObj.ver:'+cookieObj.ver+', _wn.prototype._fssVer():'+_wn.prototype._fssVer(),0);
			lastVisit = undefined;
			prevVisit = undefined;
		}
	}

	var sum = 0;
	var average;
	var first;

	if (prevVisit !== undefined && lastVisit !== undefined) {
		first = cookieObj.fst;
		if ((now - first - prevVisit) < this._wnRevisitEstimated) {
			for (var i = 0; i < cookieHist.len; i++) {
				sum += Number(cookieHist[i]);
			}
			average = Math.round(sum / cookieHist.len);
		}
		else { // revisit
			for (var i = 0; i < cookieHist.len - 1; i++) {
				sum += (cookieHist[i] = Number(cookieHist[i+1]));
			}
			sum += (cookieHist[i] = prevVisit - lastVisit);
			average = Math.round(sum / cookieHist.len);

			this.eraseCookie(this._cookieName);
			this.createCookie(this._cookieName,
				this.objectToString({
					ver: cookieObj.ver,
					fst: first,
					rfr: cookieObj.rfr,
					era: cookieObj.era,
					exp: cookieObj.exp,
					lst: lastVisit = prevVisit,
					prv: prevVisit = now - first,
					hst: cookieHist
				}),
				cookieObj.exp);
		}
	}
	else { // the first visit or cookie n/a
		var era = now - this._cookieExpired * 86400;
		var expired = this._cookieExpired;
		if (this.era && this.era < now) {
			era = this.era;
		}
		else if (this.obsolete) {
			era = now - this.obsolete;
			expired = this._wnObsolete;
		}

		cookieHist = { len: this.numHist };
		for (var i = 0; i < cookieHist.len; i++) {
			cookieHist[i] = this._wnLastVisitDefault;
		}

		average = this._wnLastVisitDefault;

		var eraFirstOrigin = era - now;
		this.eraseCookie(this._cookieName);
		this.createCookie(this._cookieName,
			this.objectToString({
				ver: _wn.prototype._fssVer(),
				fst: now,
				rfr: this.refresh,
				era: era,
				exp: expired,
				lst: lastVisit = eraFirstOrigin,
				prv: prevVisit = 0, // fst origin
				hst: cookieHist
			}),
			expired);
		if (this.readCookie(this._cookieName) === null) {
			lastVisit = eraFirstOrigin;
		}
		first = now;
	}
	this.lastVisited = Number(first) + Number(lastVisit);
	this.averageRecent = average;

	this._log('_wnCookie(): '+'this.averageRecent:'+this.averageRecent+', this.lastVisited:'+this.lastVisited+', lastVisit:'+lastVisit+', prevVisit:'+prevVisit,0);

	return average; // ???
}
/* ---------------------------------------------------------------- */

_wn.prototype._cookieName = _wn.prototype._fssName();
_wn.prototype._cookieExpired = 90;

_wn.prototype._wnEra = null;
_wn.prototype._wnObsolete = null;
_wn.prototype._wnRefresh = null;
_wn.prototype._wnNumHist = 10;

_wn.prototype._wnPageToBeInserted = '_wn.html';
_wn.prototype._wnServerScript = '_wn.php';
_wn.prototype._wnIframeId = 'wnIframeInternalId';

_wn.prototype._wnCompletion = function () {};
_wn.prototype._wnModifyNewMarkElement = function () {};

_wn.prototype._wnNoCookie = false;
_wn.prototype._wnRevisitEstimated = 7200; // 2 hours in sec.
_wn.prototype._wnLastVisitDefault = 86400; // default for noCookie

_wn.prototype._wnElementIds = null;
_wn.prototype._wnElements = null;

/* ---------------------------------------------------------------- */
function _wn(elementIds,		// elements array
		iframeId,		// internal iframe id
		checkNewMarkObject,	// method
		setNewMarkObject,	// method
		modifyNewMarkElement,	// method
		noCookie,		// [false]
		revisitEstimated,	// secs no update cookie
		lastVisitDefault,	// secs when noCookie
		setNewMark,		// method
		setNewMarkElt,		// method
		completion) {		// method

	this._log('_wn(): entered',0);

	if (!(document.getElementById &&
			document.getElementsByTagName &&
			document.createElement))
		return null; // fail



	this.era = 0;
	if (this._wnEra) { // in the form of Date.parse()
		this.era = Math.round(Date.parse(this._wnEra)/1000);
	}

	this.obsolete = 0;
	if (this._wnObsolete > 0) { // in days
		this.obsolete = Number(this._wnObsolete) * 86400;
	}

	this.refresh = 0;
	if (this._wnRefresh) { // in the form of Date.parse()
		this.refresh = Math.round(Date.parse(this._wnRefresh)/1000);
	}

	this.numHist = 1;
	if (this._wnNumHist) {
		this.numHist = (this._wnNumHist>0)? this._wnNumHist: this.numHist;
	}

	this._log('_wn(): parms'+', this.era:'+this.era+', this.obsolete:'+this.obsolete+', this.refresh:'+this.refresh+', this.numHist:'+this.numHist,0);

	// options

	this._wnElements = new Array;
	if (elementIds) {
		this._wnElementIds = elementIds;
		for (var i = 0; i < elementIds.length; i++) {
			this._log('_wn(): elementIds[i]: '+elementIds[i],1);
			var elt = document.getElementById(elementIds[i]);
			if (elt)
				this._wnElements[this._wnElements.length] = elt;
		}
	}
	else {
		this._wnElements[0] = document.body;
	}

	this._log('_wn(): this._wnElements.length: '+this._wnElements.length,0);

	if (iframeId)
		this._wnIframeId = iframeId;

	if (this._wnElements.length && this._wnIframeId && !this._isLocal) {

		if (noCookie)
			this._wnNoCookie = noCookie

		if (revisitEstimated)
			this._wnRevisitEstimated = revisitEstimated;

		// _wnLastVisitDefault will be overwritten by Cookie
		if (lastVisitDefault)
			this._wnLastVisitDefault = lastVisitDefault;

		// methods

		if (setNewMark)
			this._wnSetNewMark = setNewMark;
		if (setNewMarkElt)
			this._wnSetNewMarkElt = setNewMarkElt;

		this._wnCheckNewMarkObject = checkNewMarkObject;
		this._wnSetNewMarkObject = setNewMarkObject;

		if (modifyNewMarkElement)
			this._wnModifyNewMarkElement = modifyNewMarkElement;


		if (completion)
			this._wnCompletion = completion;



		this.wnPn = new Array();
		for (var i = 0; i < this._wnElements.length; i++) {
			this.wnPn = this.wnPn.concat(this._wnGetPathnames(this._wnElements[i]));
		}


		this._log('_wn(): this._wnRevisitEstimated:'+this._wnRevisitEstimated+', this._wnLastVisitDefault:'+this._wnLastVisitDefault+', this.wnPn.length:'+this.wnPn.length,0);



		// start

		var ifr = this.elementIdentified(this._wnIframeId,'iframe');
		ifr.$_wnO = this;
		ifr.name = this._wnIframeId;
//		ifr.src = this._wnPageToBeInserted;
		ifr.style.visibility = 'hidden';
		ifr.frameborder = 0;
		ifr.style.width = 0;
		ifr.style.height = 0;

		if (ifr._fssGenerated && !ifr._fssGeneratedEver)
			document.body.appendChild(ifr);

		var urlToSubmit = this._prependInstallDirectory(this._wnPageToBeInserted);
		frames[this._wnIframeId].document.location.replace(urlToSubmit);

		this._log('_wn(): this._wnIframeId:'+this._wnIframeId+', urlToSubmit:'+urlToSubmit,0);

		if (typeof _wnIframe == 'undefined') {
			_wnIframe = new Object;
		}
		_wnIframe[ifr.id] = ifr;
	}
	_wn.prototype._fssInsertUrl();
}
/* ---------------------------------------------------------------- */

window.onresize = function () {
	if (!(typeof _wnIframe == 'undefined')) {
		for (var id in _wnIframe) {
			_wnIframe[id].$_wnO._wnResetPosition();
		}
	}
}

/* ---------------------------------------------------------------- */
_wn.prototype.__objectIdChar = '/';
/* ---------------------------------------------------------------- */
_wn.prototype.objectToString = function (obj) {
	this._log('objectToString(): entered',0);
	var ret = '';
	for (var p in obj) {
		var str;
		if (typeof obj[p] == 'object') {
			str = this.__objectIdChar+this.objectToString(obj[p]);
		}
		else {
			str = obj[p]; 
		}
		ret += p+'='+str+';';
	}
	this._log('objectToString(): ret before encode:'+ret,1);
	return encodeURIComponent(ret);
}
/* ---------------------------------------------------------------- */
_wn.prototype.stringToObject = function (str) {
	this._log('stringToObject(): entered',0);
	var ret = {};
	if (str) {
		this._log('stringToObject(): str:'+str,1);
		var x = decodeURIComponent(str).split(';');
		var indexEq;
//		alert('x:'+x+', x.length:'+x.length);
		for (var i = 0; i < x.length; i++) {
			if ((indexEq = x[i].indexOf('=')) == -1) continue;
			var p = x[i].substring(0,indexEq);
			var v = x[i].substring(indexEq+1);
			if (v.length && v.charAt(0) == this.__objectIdChar) {
				v = this.stringToObject(v.substring(1))
			}
			this._log('stringToObject(): i:'+i+', p:'+p+', v:'+v,1);
			ret[p] = v;
//			ret[x[i].substring(0,indexEq)] = x[i].substring(indexEq+1);
		}
	}
	return ret;
}
/* ---------------------------------------------------------------- */

