/*
 * Copyright (c) 1995-2012 by 4system Polska Sp. z o.o.
 * All Rights Reserved. v4
 */
if (typeof(moduleDone) != "undefined") moduleDone("tools.js");

var E_NOTIMPL = -1;
var S_OK = 1;
var S_FALSE = 0;

var oPlayer = null;
var oLMS = null;
var oUELO = null;
var oSW = null;
var oPage = null;
var oStruct = null;
var oSuspendData = null;
var oLang = null;
var framesTable = new Array();

/* Search */
function checkFrame(f)
{
	for (var i in framesTable) {
		if (framesTable[i] === f) return true;
	};
	return false;
};

function storeFrame(f)
{
	framesTable[framesTable.length] = f;
};

function findObject(win, m)
{
	// try {
		// if (!(win instanceof Window)) return null;
	// } catch(e) {
		// return null;
	// };

	try {
		if (win.extContent) return null;
		if (win[m] != null) return win[m];
	} catch(e) {};

	if (checkFrame(win)) return null;
	storeFrame(win);

	if (win != null) {
		var i = 0;
		while (typeof(win.frames[i]) !== "undefined") {
			var o = findObject(win.frames[i], m);
			if (o != null) { //pg2-completion
				if (m == "pageWBT" && oPlayer != null) { //if (m == "page" && oPlayer != null) { //pg2-prov_moodle_new_test
					if (o.p_globalIndex == oPlayer.gix) return o;
				} else return o;
			};
			i++;
		};
	};

	return null;
};

function findObjectUp(w, m)
{
	var obj = w;
	while (obj != null && !checkFrame(obj)) {
		try {
			var o = findObject(obj, m);
			if (o != null) return o;
		} catch(e) {};
		obj = obj.parent;
	};

	if (w != null && !checkFrame(w.opener)) {
		return findObjectUp(w.opener, m);
	};

	return null;
};

function getObject(m)
{
	return findObjectUp(window, m);
};

function getPlayer()
{
	framesTable = new Array();

	//WARNING- DO NOT CHANGE ANYTHING WITHOUT CAREFUL ANALYSIS

	/*if (oPlayer == null)  oPlayer = getObject("player");
	return oPlayer; */

	if (typeof(is) == "undefined") { //pg2-distinquish of webbrowser (at first, it will not be available)
		oPlayer = getObject("player");
	} else
	if (is.ie || is.moz) { //pg2-it doesn't work in Chrome, etc
		if (oPlayer != null) {
			try {
				oPlayer.isAvailablePlayerObject(); //pg2-even if  " oPlayer != null ", it might be relased, so try to invoke its method
			} catch(e) {
				oPlayer = getObject("player");
			};
		} else oPlayer = getObject("player");
	} else {
		oPlayer = getObject("player");
	};
	return oPlayer;
};

function getLMS()
{
	framesTable = new Array();

	//WARNING- DO NOT CHANGE ANYTHING WITHOUT CAREFUL ANALYSIS

	/*if (oLMS == null) oLMS = getObject("lms"); //pg2-sometimes lms was somewhere relased, but wasn't null - calling its method invoked exceptions
	return oLMS; */

	if (typeof(is) == "undefined") { //pg2-distinquish of webbrowser (at first, it will not be available)
		oLMS = getObject("lms");
	} else
	if (is.ie || is.moz) { //pg2-it doesn't work in Chrome, etc
		if (oLMS != null) {
			try {
				oLMS.getSID(); //pg2-even if  " oLMS != null", it might be relased, so try to invoke its method
			} catch(e) {
				oLMS = getObject("lms");
			};
		} else oLMS = getObject("lms");
	} else {
		oLMS = getObject("lms");
	};
	return oLMS;
};

function getUELO()
{
	framesTable = new Array();
	if (oUELO == null) oUELO = getObject("uelo");
	return oUELO;
};

function getSW()
{
	framesTable = new Array();
	if (oSW == null) oSW = getObject("sw");
	return oSW;
};

function getPage()
{
	framesTable = new Array();

	//WARNING- DO NOT CHANGE ANYTHING WITHOUT CAREFUL ANALYSIS

	//pg2-removed, 'cause sometimes player somewhere was relased, object wasn't null - calling its method caused exceptions
	/*if (oPlayer == null) oPlayer = getPlayer(); //pg2-completion
	if (oPlayer != null) { //pg2-do not return previous object, 'cause current object could be a reference to another page (example: current oPlayer.gix=3, oPage.p_globalIndex = 2 -previously loaded, not the one required
		if (oPage != null) {
			if (oPage.p_globalIndex != oPlayer.gix) oPage = getObject("page"); //pg2-if gixs match, do not uncecessary seek through all frames
		} else {
			oPage = getObject("page");
		};
		oPage = getObject("page");
	};
	return oPage;*/

	if (oPlayer == null) oPlayer = getPlayer();
	if (oPlayer != null) {
		if (typeof(is) == "undefined") {  //pg2-distinquish of webbrowser (at first, it will not be available)
			if (oPage != null) {
				try { //pg2-if this will fail, page isn't available, try to get new instance of the object
					if (oPage.p_globalIndex != oPlayer.gix) oPage = getObject("pageWBT"); //getObject("page"); //pg2-prov_moodle_new_test
				} catch(e) {
					oPage = getObject("pageWBT"); //oPage = getObject("page"); //pg2-prov_moodle_new_test
				};
			} else
			oPage = getObject("pageWBT"); //oPage = getObject("page"); //pg2-prov_moodle_new_test
		} else
		if (is.ie || is.moz) { //pg2-it doesn't work in Chrome, etc
			if (oPage != null) {
				try {
					oPage.getName(); //pg2-even if  "oPage != null ", it might be relased, so try to invoke its method
					if (oPage.p_globalIndex != oPlayer.gix) oPage = getObject("pageWBT"); //oPage = getObject("page"); //pg2-if gixs match, do not uncecessary seek through all frames //pg2-prov_moodle_new_test
				} catch(e) {
					oPage = getObject("pageWBT"); //oPage = getObject("page"); //pg2-prov_moodle_new_test
				};
			} else oPage = getObject("pageWBT"); //oPage = getObject("page"); //pg2-prov_moodle_new_test
		} else {
			oPage = getObject("pageWBT"); //oPage = getObject("page"); //pg2-prov_moodle_new_test
		};
	};
	return oPage;
};

function getStruct()
{
	framesTable = new Array();
	if (oStruct == null) oStruct = getObject("struct");
	return oStruct;
};

function getSuspendData()
{
	framesTable = new Array();
	if (oSuspendData == null) oSuspendData = getObject("suspendData");
	return oSuspendData;
};

function getLang()
{
	framesTable = new Array();
	if (oLang == null) oLang = getObject("messages"); //getObject("lang"); //pg2-inactivity time -there is no longer 'lang' object (it was changed to 'messages')
	return oLang;
};

function findWBTServerTop(win) {
	try {
		if (typeof(win.isWBTServer) != "undefined" && win.isWBTServer != null) return win;
	} catch(e) {};
	if (win.length > 0) {
		for(var i = 0; i < win.length; i++) {
			var theWBTServerTop = findWBTServerTop(win.frames[i]);
			if (theWBTServerTop != null) return theWBTServerTop;
		};
	};
	return null;
};

function getWBTServerTop()
{
	var theWBTServerTop = findWBTServerTop(parent);
	if (theWBTServerTop == null) theWBTServerTop = findWBTServerTop(top);
	if (theWBTServerTop == null) {
		if (typeof(opener) != "undefined") {
			if (opener != null) theWBTServerTop = findWBTServerTop(opener.top);
		};
	};
	return theWBTServerTop;
};

function findFrame(name, frame)
{
	var oldFrameName = null;
	if (name == "navigation") {
		oldFrameName = "header";
	};

	if (typeof(frame) == "undefined") {
		frame = frames;
	};
	for (var i = 0; i < frame.length; i++) {
		if (frame[i].name == name || (oldFrameName && frame[i].name == oldFrameName)) {
			return frame[i];
		} else {
			var result = findFrame(name, frame[i]);
			if (result) return(result);
		};
	};
	return(null);
};

function findHTMLObjInFrame(name, frame) 
{
	if (typeof(frame) == "undefined") {
		frame = frames;
	};
	var htmlObj = frame.document.getElementById(name);
	if (htmlObj) return htmlObj;
	for (var i = 0; i < frame.length; i++) {
		var result = this.findHTMLObjInFrame(name, frame[i]);
		if (result) return result;
	};
	return null;
};
/* Array */
function fnArrayPop()
{
	var response = this[this.length - 1];
	this.length--;
	return response;
};

if (typeof(Array.prototype.pop) == "undefined") {
	Array.prototype.pop = fnArrayPop;
};

function fnArrayPush()
{
	for (var A_p=0; A_p<arguments.length; A_p++) {
		this[this.length] = arguments[A_p];
	};
	return this.length;
};

if (typeof Array.prototype.push == "undefined") {
	Array.prototype.push = fnArrayPush;
};

function fnArraySplice(index, delTotal)
{
	var temp = new Array();
	var response = new Array();

	var A_s = 0;
	for (A_s = 0; A_s < index; A_s++) {
		temp[temp.length] = this[A_s];
	};
	for (A_s = 2; A_s < arguments.length; A_s++) {
		temp[temp.length] = arguments[A_s];
	};
	for (A_s = index + delTotal; A_s < this.length; A_s++) {
		temp[temp.length] = this[A_s];
	};
	for (A_s = 0; A_s < delTotal; A_s++) {
		response[A_s] = this[index + A_s];
	};
	this.length = 0;
	for (A_s = 0; A_s < temp.length; A_s++) {
		this[this.length] = temp[A_s];
	};
	return response;
};

if (typeof Array.prototype.splice == "undefined") {
	Array.prototype.splice = fnArraySplice;
};

function inArray(value, searchArray)
{
	for (var i = 0; i < searchArray.length; i++) {
		if (value == searchArray[i]) return true;
	};
	return false;
};

/* String */
function quotedString(value)
{
	var new_value = value;
	new_value = new_value.replace(/"/g, "&quot;");
	new_value = new_value.replace(/'/g, "&#146;");
	return new_value;
};

function unquotedString(value)
{
	var new_value = value;
	new_value = new_value.replace(/&quot;/g, '"');
	new_value = new_value.replace(/#&034/g, '"');
	new_value = new_value.replace(/&#146;/g, "'");
	return new_value;
}; 
 
function trim(str)
{
   if (typeof(str) != "undefined") {
		return str.replace(/^\s*|\s*$/g, "");
	} else {
		return "";
	};
};

function binIntoDec(bin)
{
	return parseInt(bin, 10);
};

function decIntoBin(dec)
{
	if (isNaN(dec)) return "";
	if (dec == -1 || dec == '-1') return ''; //pg2- in case of -1, here would be an "neverending loop"
	var bin = "";
	while (dec != 0) {
		bin += dec % 2;
		dec = Math.floor(dec / 2);
	};
	return bin;
};

function formatString(value, keywords)
{
	var result = value;
	for (var i = 1; i < arguments.length; i++) {
		if (result.indexOf("%s") > -1) {
			result = result.replace("%s", arguments[i]);
		} else break;
	};
	return result;
};

/* NN4 Tools */
function getFormNS4(name, obj)
{
	for (var i = 0; i < obj.forms.length; i++) {
		if (obj.forms[i].name == name) return obj.forms[i];
	};
	for (var i = 0; i < obj.layers.length; i++) {
		var res = getFormNS4(name, obj.layers[i].document);
		if (res) return res;
	};
	return null;
};

function getObjNS4(obj,name)
{
	var x = obj.layers;
	var foundLayer;
  
	for (var i = 0; i < x.length; i++) {
		if (x[i].id == name) foundLayer = x[i]; else 
		if (x[i].layers.length) var tmp = getObjNS4(x[i], name);
		if (tmp) foundLayer = tmp;
	};
	return foundLayer;
};

function getForm(name)
{
	if (is.ns4) {
		return getFormNS4(name, document);
	} else {
		return document.forms[name];
	};
};

/* Date & Time Class */
Date.prototype.getFotmatedTime = function()
{
	var hours = this.getHours();
	hours = ((hours < 10) ? "0" : "") + hours;
	var minutes = this.getMinutes();
	minutes = ((minutes < 10) ? "0" : "") + minutes;
	var seconds = this.getSeconds();
	seconds = ((seconds < 10) ? "0" : "") + seconds;
	return hours + ":" + minutes + ":" + seconds;
};

Date.prototype.subtractTimeToString = function(dateStart)
{
  if (typeof(dateStart) == "undefined" || dateStart == null) dateStart = new Date(); //pg2-exceptions in offline- page status = F or P, and check answer (via some image, etc)
  var dd = Math.abs(this.getTime() - dateStart.getTime());
  var ts = Math.floor( ( ( (dd % (60 * 60 * 1000 * 24) ) % (60 * 60 * 1000) ) % ( 60 * 1000 ) ) / 1000 * 1);
  var tm = Math.floor( (dd % (60 * 60 * 1000 * 24)) % ((60 * 60 * 1000)) / (60 * 1000));
  var th = Math.floor( (dd % (60 * 60 * 1000 * 24)) / (60 * 60 * 1000));

  var sh = ((th < 10) ? "0" : "") + th;
  var sm = ((tm < 10) ? "0" : "") + tm;
  var ss = ((ts < 10) ? "0" : "") + ts;

  return ("" + sh + ":" + sm + ":" + ss);
};

Date.prototype.getMilisecondsBetweenDates = function(dateStart, dateEnd)
{
  if (typeof(dateStart) == "undefined" || dateStart == null) dateStart = new Date(); //pg2
  if (typeof(dateEnd) == "undefined" || dateEnd == null) dateEnd = new Date(); //pg2
  var miliseconds = Math.abs(dateStart.getTime() - dateEnd.getTime());

  return miliseconds;
};

function convertStringTimeToInt(stringDate)
{
	var timeArr = stringDate.split(":");

	var h = parseInt(timeArr[0], 10)*60*60;
	var m = parseInt(timeArr[1], 10)*60;
	var s = parseInt(timeArr[2], 10);
	var ms = parseInt(timeArr[3], 10);

	return h+m+s+ms/1000;
};

function calculateTimeIntToString(timeInt, fillWithZeros)
{
	var sh = parseInt(timeInt/(60*60));
	var timeLeft = timeInt - sh*60*60;
	var sm = parseInt(timeLeft/60);
	timeLeft = timeLeft - sm*60;
	var ss = Math.floor(timeLeft); //pg2-moved here
	
	if (typeof(fillWithZeros) != 'undefined' && fillWithZeros == true) { //pg2-bi_AKA_completion
		sh += '';
		sm += '';
		ss += '';
		if (sh.length == 1) sh = '0' + sh;
		if (sm.length == 1) sm = '0' + sm;
		if (ss.length == 1) ss = '0' + ss;
	};
	
	return "" + sh + ":" + sm + ":" + ss; //Math.floor(ss); //pg2-inactivity time -seconds only
};

function calculateTimeToString(dateStart, dateEnd)
{
	if (typeof(dateStart) == "undefined" || dateStart == null) dateStart = new Date(); //pg2
	if (typeof(dateEnd) == "undefined" || dateEnd == null) dateEnd = new Date();

	var dtm = Math.abs(dateEnd.getTime() - dateStart.getTime());

	var th = Math.floor((dtm % (60 * 60 * 1000 * 24)) / (60 * 60 * 1000));
	var tm = Math.floor((dtm % (60 * 60 * 1000 * 24)) % ((60 * 60 * 1000)) / (60 * 1000));
	var ts = Math.floor((((dtm % (60 * 60 * 1000 * 24)) % (60 * 60 * 1000)) % (60 * 1000)) / 1000 * 1);

	var sh = ((th < 10) ? "0" : "") + th;
	var sm = ((tm < 10) ? "0" : "") + tm;
	var ss = ((ts < 10) ? "0" : "") + ts;

	return "" + sh + ":" + sm + ":" + ss;
};

function formatTime(format, date, dateSep)
{
	if (typeof(format) == "undefined") format = "time";
	if (typeof(date) == "undefined") date = new Date();
	if (typeof(dateSep) == "undefined") dateSep = "-";
	var timeSep = ":";

	var dy = date.getFullYear();
	var dm = date.getMonth() + 1;
	dm = ((dm < 10) ? "0" : "") + dm;
	var dd = date.getDate();
	dd = ((dd < 10) ? "0" : "") + dd;
	var th = date.getHours();
	th = ((th < 10) ? "0" : "") + th;
	var tm = date.getMinutes();
	tm = ((tm < 10) ? "0" : "") + tm;
	var ts = date.getSeconds();
	ts = ((ts < 10) ? "0" : "") + ts;

	var result = "";
	switch (format) {
		case "time": //HH:MM:SS								03:00:00
			result = th + timeSep + tm + timeSep + ts;
			break;
		case "date": //YYYY-MM-DD								2003-07-25
			result = dy + dateSep + dm + dateSep + dd;
			break;
		case "datetime": //YYYY-MM-DD HH:MM:SS					2003-07-25 03:00:00
			result = dy + dateSep + dm + dateSep + dd
				+ " " + th + timeSep + tm + timeSep + ts;
			break;
		case "timestamp": //YYYY[-MM[-DD[Thh[:mm[:ss[.s[TZD]]]]]]]		2003-07-25T03:00:00
			result = dy + dateSep + dm + dateSep + dd
				+ "T" + th + timeSep + tm + timeSep + ts;
			break;
		case "timeinterval": //PT[yY][mM][dD][T[hH][mM][s[.s]S]]		PT1Y3M2DT3H
			var ti_th = parseInt(th, 10);
			var ti_tm = parseInt(tm, 10);
			var ti_ts = parseInt(ts, 10);

			result = "PT";
			result += (ti_th > 0) ? ti_th + "H" : "";
			result += (ti_tm > 0) ? ti_tm + "M" : "";
			result += ti_ts + "S";
			break;
	};

	return result;
};

function stringToDate(s)
{
	if (typeof(s) == "undefined" || s == "") return new Date();
	var r = new RegExp("(\\d{4})-(\\d{2})-(\\d{2}) (\\d{2}):(\\d{2}):(\\d{2})");
	var a = s.match(r);

	//pg2-fixed convertion from string to date
	var resDate = new Date();
	if (a.length == 7) {
		var param2 = a[2];
		if (param2.indexOf('0') == 0) {
			param2.substring(1,2);
		}
		var param1 = parseInt(param2, 10) - 1;
		resDate = new Date(a[1], param1, a[3], a[4], a[5], a[6]);
	};

	return resDate;
};

function addVersionControl(millis) 
{
	date = new Date();
	var curDate = null;

	do {
		var curDate = new Date();
	} while(curDate - date < millis);
};

/* Cookie Class */
function Cookie()
{
	this.get = function (nameOfCookie, doc)
	{
		if (typeof(doc) == "undefined") doc = top.window.document;

		if (doc.cookie.length > 0) { 
			var begin = -1;
			var code = '';
			code += (is.ns4) ? '' : 'try {';
			code += 'begin = doc.cookie.indexOf("' + nameOfCookie + '=");';
			code += (is.ns4) ? '' : '} catch(e) {}';
			eval(code);
			if (begin != -1) { 
				begin += nameOfCookie.length + 1; 
				var end = doc.cookie.indexOf(";", begin);
				if (end == -1) end = doc.cookie.length;
				return unescape(doc.cookie.substring(begin, end));
			} ;
		};
		return null; 
	};

	this.set = function (nameOfCookie, value, expiredays, doc) 
	{
		if (typeof(doc) == "undefined") doc = top.window.document;

		if (typeof(expiredays) == "undefined") expiredays = 10;

		var ExpireDate = new Date ();
		ExpireDate.setTime(ExpireDate.getTime() + (expiredays * 24 * 3600 * 1000));
		var code = '';
		code += (is.ns4) ? '' : 'try {';
		code += 'doc.cookie = "' + nameOfCookie + '=' + escape(value) + ((expiredays == null) ? '' : '; expires=' + ExpireDate.toGMTString()) + '"';
		code += (is.ns4) ? '' : '} catch(e) {}';
		eval(code);
	};

	this.remove = function (nameOfCookie, doc)
	{
		if (typeof(doc) == "undefined") doc = document;

		if (this.get(nameOfCookie)) {
			var code = '';
			code += (is.ns4) ? '' : 'try {';
			code += 'doc.cookie = "' + nameOfCookie + '=' + '; expires=Thu, 01-Jan-70 00:00:01 GMT"';
			code += (is.ns4) ? '' : '} catch(e) {}';
			eval(code);
		};
	};
};

cookie = new Cookie();

/* URL */
function getCommandUrl(name, def)
{
	try {
		name = name.toLowerCase();
		var arr = location.search.slice(1).split('&');
		for (var i = 0; i < arr.length; i++) {
			var keyName = arr[i].slice(0, arr[i].indexOf('=')).toLowerCase();
			if (keyName == name) {
				return arr[i].slice(arr[i].indexOf('=') + 1);
			};
		};
	} catch(e) {
		if (log) log.error(e + " : getTopCommandUrl name=" + name + "");
	};
	if (typeof(def) == "undefined") return null
	else return def;
};

function getTopCommandUrl(name)
{
	return getCommandUrl(name);
};

/* Fonts */
function isDefaultFont(font)
{
	var result = true;
	if (font.family != 'Arial') {
		result = false;
	} else 
	if (font.size != 2) {
		result = false;
	} else 
	if (font.color.replace(/#/g, "") != '000000') {
		result = false;
	};
	return result;
};

function getFontSize(value, format)
{
	if (typeof(value)=='undefined' || value < 0) return 10; //pg2
	
	var fontSizesPX = new Array(0,10,13,16,18,24,32,48);
	var fontSizesPT = new Array(0, 8,10,12,14,18,24,36);
	
	//pg2-prevent from given value greater than array size - if there was given font size instead of its number, find the number
	if (parseInt(value) >= fontSizesPX.length) {
		var val = -1;
		for (var i=0; i<fontSizesPX.length; i++) {
			if (fontSizesPX[i] == parseInt(value)) {
				val = i;
				break;
			};
		};
		if (val != -1) {
			value = val;
		} else {
			for (var i=0; i<fontSizesPT.length; i++) {
				if (fontSizesPT[i] == parseInt(value)) {
					val = i;
					break;
				};
			};
			if (val != -1) value = val; else {
				//delete fontSizesPX;
				//delete fontSizesPT;
				//return 10;
				value = fontSizesPX.length-1;
			};
		};
	};
	//...
	var pxSize = fontSizesPT[parseInt(value)];
	if (format == "px") {
		pxSize = fontSizesPX[parseInt(value)];
	};
	if (typeof(pxSize) == "undefined") pxSize = value;
	
	delete fontSizesPX; //pg2
	delete fontSizesPT;
	
	return pxSize;
};

function getProjectFont(fontGlobalFormating, family, size, color)
{
	var font = {};
	font.family = family;
	font.size = size;
	font.color = color;

	if (fontGlobalFormating && project.globalFormating) {
		font.family = project.font.family;
		font.size = project.font.size;
		font.color = project.font.color;
	};

	return font;
};

function sameFonts(font1, font2)
{
	var result = true;
	if (font1.family != font2.family) {
		result = false;
	} else 
	if (font1.size != font2.size) {
		result = false;
	} else 
	if (font1.color.replace(/#/g, "") != font2.color.replace(/#/g, "")) {
		result = false;
	};
	return result;
};

function checkFont(font)
{
	var result = true;
	if (typeof(font) != "object") {
		result = false;
	} else 
	if (!font.family || font.family == '') {
		result = false;
	} else 
	if (!font.size || font.size == '' || isNaN(font.size)) {
		result = false;
	} else 
	if (!font.color || font.color.replace(/#/g, "") == '') {
		result = false;
	};
	return result;
};

function Font()
{
	this.family = "Arial";
	this.size = "2";
	this.color = "#000000";
};

/* other */
function showConfiguration(isNew, x, y, w, h)
{
	var url = "ds_configuration.html";
	if (isNew) url = "configuration.html";

	if (w == null) w = 600;
	if (h == null) h = 280;

	var opt = "";
	opt += (x != null) ? ', left=' + x : ', left=' + ((screen.availWidth - w) / 2);
	opt += (y != null) ? ', top=' + y : ', top=' + ((screen.availHeight - h) / 2);
	opt += ', width=' + w;
	opt += ', height=' + h;

	window.open(url, "", opt);

	return false;
};

function getURIParam(name)
{
	var r = "";
	name = name.toLowerCase();
	var paramsList = location.search.slice(1).split('&');
	for (var i = 0; i < paramsList.length; i++)	{
		keyName = paramsList[i].slice(0, paramsList[i].indexOf('=')).toLowerCase();
		if (keyName == name) {
			r = paramsList[i].slice(paramsList[i].indexOf('=') + 1);
			break;
		};
	};
	return r;
};

function preloadImage(obj, id)
{
	var isLoaded = false;

	if (obj.paintLocked || obj.isLoaded 
		|| typeof(obj.preloadImages) == "undefined" || obj.preloadImages == null
		|| typeof(obj.preloadImages["src" + id]) == "undefined" || obj.preloadImages["src" + id] == null) return true;

    if (obj.preloadImages["src" + id] == "" || obj.preloadImages["src" + id] == "empty"
			|| page.state == psDesigning || page.state == psPreview) {
		isLoaded = true;
    } else {
		if (obj.preloadImages["pim" + id] == null) {
			obj.preloadImages["pim" + id] = new Image();
			obj.preloadImages["pim" + id].src = obj.preloadImages["src" + id];
		};

        if (typeof(obj.preloadImages["pim" + id].complete) == "undefined") {
			isLoaded = true;
        } else {
            if (obj.preloadImages["pim" + id].complete) {
				isLoaded = true;
			} else {
				do {
					if (obj.preloadImages["pim" + id].complete) return true;
					++obj.preloadImages["wtc" + id];
				} while (obj.preloadImages["wtc" + id] < 50 && !obj.preloadImages["pim" + id].complete)
			};
		};
	};
	return isLoaded;
};

function getImageSize(imgName)
{
	var img = new Image();
	if (PageInterface.GetValue("state") == psDesigning) {
		img.src = PageInterface.GetValue("resourcesURL") + imgName;
	} else {
		img.src = PlayerInterface.GetValue("resourcesURL") + imgName;
	};
	if (isImageLoaded(img) || (!isNaN(img.width) && !isNaN(img.height))) {
		//var size = new Array(img.width, img.height);
		var size = new Array();
		size[0] = img.width;
		size[1] = img.height;
		img = null;
		return size;
	} else {
		img = null;
		return getImageSize(imgName);
	};
};

function getImageHeight(imgName)
{
	var img = new Image();
	if (PageInterface.GetValue("state") == psDesigning || !page.allowCommunication()) {
		img.src = PageInterface.GetValue("resourcesURL") + imgName;
	} else {
		img.src = PlayerInterface.GetValue("resourcesURL") + imgName;
	};
	if (isImageLoaded(img) || !isNaN(img.height)) {
		var height = img.height;
		img = null;
		return height;
	} else {
		img = null;
		return getImageHeight(imgName);
	};
}; 

function getImageWidth(imgName)
{
	var img = new Image();
	if (PageInterface.GetValue("state") == psDesigning || !page.allowCommunication()) {
		img.src = PageInterface.GetValue("resourcesURL") + imgName;
	} else {
		img.src = PlayerInterface.GetValue("resourcesURL") + imgName;
	};

	if (isImageLoaded(img) || !isNaN(img.width)) {
		var width = img.width;
		img = null;
		return width;
	} else {
		img = null;
		return getImageWidth(imgName);
	};
};

function isImageLoaded(imgObj)
{
	var isLoaded = false;
	var counter = 0;
	if (imgObj.complete) {
		isLoaded = true;
	} else {
		if (typeof(imgObj.complete) == "undefined") {
			isLoaded = true;
		};
	};
	return isLoaded;
};

function clone(obj)
{
	for (o in obj) {
        if (typeof obj[o] == 'object') {
            this[o] = new clone(obj[o]);
        } else {
            this[o] = obj[o];
		};
    };
};

function getAttributeText(obj, name)
{
	var result = "";
	for (var i=0; i<obj.attributes.length; i++) {
		if (obj.attributes[i].specified && (obj.attributes[i].nodeName.toLowerCase() == name.toLowerCase())) {
			result += ' ' + obj.attributes[i].nodeName + '="' + obj.attributes[i].nodeValue + '" ';
		};
	};

	return result;
};

function clearHTMLTags(inHTML) { 
	var regEx = '';
	var outText = '';
	regEx = /<[^>]*>/g;
	outText = inHTML.replace(regEx, "");
	regEx = /&nbsp;/g;
	outText = outText.replace(regEx, "");
	return outText;
};

function checkExportType(exportType, checkType)
{
	exportType = exportType.toLowerCase();
	switch (checkType) {
		case "single":
			return ((exportType == "wbtserver_singlesco") || (exportType == "offline") ||
			(exportType == "exe") || (exportType == "exe_cbt") || (exportType == "poll") || 
			(exportType == "exe_cbtlight") || (exportType == "scorm12_singlesco") ||
			(exportType == "scorm2004_singlesco") || (exportType == "aicc_singlesco") ||
			(exportType == "aicc_multisinglesco") || (exportType == "oracle_singlesco") ||
			(exportType == "moodle_singlesco") || (exportType == "aicc_singlesco") ||
			(exportType == "scorm2004_singlesco") || (exportType == "aicc_singlesco"));
			break;
		case "multi":
			return ((exportType == "wbtserver_multisco") || (exportType == "exam") ||
			(exportType == "encyclopedia") || (exportType == "oracle_multisco") ||
			(exportType == "scorm12_multisco") || (exportType == "scorm2004_multisco") ||
			(exportType == "aicc_multisco") || (exportType == "moodle_multisco"));
			break;
		case "singleMulti":
			return ((exportType == "wbtserver_multisinglesco") || (exportType == "scorm12_multisinglesco") ||
			(exportType == "scorm2004_multisinglesco") || (exportType == "oracle_multisinglesco") ||
			(exportType == "moodle_multisinglesco"));
			break;
		case "poll":
			return (exportType == "poll"); //pg2-new
			break;
	};
	return false;
};

function showMessage(message)
{
	if (arguments[1]) {
		prompt(message, arguments[1]);
	} else {
		alert(message);
	};
};

function displayHTMLElement(obj, value)
{
	if (obj.style)	obj.style.display = value;
};

function convertStatusToName(shortStatus)
{
	switch (shortStatus.toUpperCase()) {
		case "C" : 
				return 'completed'; 
			break;
		case "f" : 
				return 'failed'; 
			break;
		case "I" : 
				return 'incomplete'; 
			break;
		case "N" : 
				return 'not attempted'; 
			break;
		case "P" : 
				return 'passed'; 
			break;
		default : 
				return shortStatus.toUpperCase(); 
			break;
	};
};

function convertStatusToLetter(longStatus)
{
	switch (longStatus) {
		case "browsed" : 
				return 'N'; 
			break;
		case "completed" : 
				return 'C'; 
			break;
		case "failed" : 
				return 'F'; 
			break;
		case "incomplete" : 
				return 'I'; 
			break;
		case "not attempted" : 
				return 'N'; 
			break;
		case "passed" : 
				return 'P'; 
			break;
		case "unknown" : 
				return 'N'; 
			break;
		default : 
				return longStatus; 
			break;
	};
};

function setWindowTitle(title)
{
	try {
		top.window.document.title = title;
	} catch(e) {};
};

function Size(x, y, w, h)
{
    this.x = x;
    this.y = y;
    this.w = w;
    this.h = h;
};

function getElementSize(o)
{
    var s = new Size(o.offsetLeft, o.offsetTop, o.offsetWidth, o.offsetHeight);
    while (o.offsetParent && o.offsetParent.offsetLeft !== undefined)
    {
        o = o.offsetParent;
		if (o.style.position == "absolute") { break; };
        s.x += o.offsetLeft;
        s.y += o.offsetTop;
    }
    return s;
};
//---------------------------------------------------------------------------------------
function getDateStr(dt) { //year : month : day : hour : seconds : milliseconds
	var selfCreated = false;
	if (typeof(dt) == 'undefined') {
		dt = new Date();
		selfCreated = true;
	};
	//var dt = new Date();
	var year = dt.getFullYear();
	var month = dt.getMonth();
	var day = dt.getDate();
	var hours = dt.getHours();
	var minutes = dt.getMinutes();
	var seconds = dt.getSeconds();
	var mseconds = dt.getMilliseconds();
	//delete dt;
	var result = year + ':' + month + ':' + day + ':' + hours + ':' + minutes + ':' + seconds + ':' + mseconds;
	if (selfCreated) delete dt;
	
	return result;
};
//---------------------------------------------------------------------------------------
function setDateStr(dateStr) { //TEST
	if (typeof(dateStr) == 'undefined' || dateStr == '') return '';
	var list = dateStr.split(':');
	if (list.length != 7) return '';
	
	var dt = new Date();

	dt.setFullYear(list[0]);
	dt.setMonth(list[1]);
	dt.setDate(list[2]);
	dt.setHours(list[3]);
	dt.setMinutes(list[4]);
	dt.setSeconds(list[5]);
	dt.setMilliseconds(list[6]);

	var result = getDateStr(dt);
	delete dt;
	
	return result;
};
//---------------------------------------------------------------------------------------
function setDateObjFromStr(dateStr) {
	if (typeof(dateStr) == 'undefined' || dateStr == '') return null;
	var list = dateStr.split(':');
	if (list.length != 7) return null;
	
	var dt = new Date();

	dt.setFullYear(list[0]);
	dt.setMonth(list[1]);
	dt.setDate(list[2]);
	dt.setHours(list[3]);
	dt.setMinutes(list[4]);
	dt.setSeconds(list[5]);
	dt.setMilliseconds(list[6]);

	return dt;
};
//---------------------------------------------------------------------------------------
function getDateAbsMilliseconds(dt) {
	if (typeof(dt) == 'undefined') return 0;
	try {
		var result = dt.getTime();
		return result;
	} catch(e) {
		return 0;
	};
};
//---------------------------------------------------------------------------------------
function getDateObjFromMilliseconds(ms) {
	if (typeof(ms) == 'undefined' || ms == '') return null;
	var dt = new Date();
	dt.setTime(ms);
	return dt;
};
//---------------------------------------------------------------------------------------
function isTheSameDay(dateOneStr, dateTwoStr) {//"year : month : day : hour : seconds : milliseconds", "year : month : day : hour : seconds : milliseconds"
	if (typeof(dateOneStr) == 'undefined' || dateOneStr == '' || typeof(dateTwoStr) == 'undefined' || dateTwoStr == '') return false;
	
	var list1 = dateOneStr.split(':');
	var list2 = dateTwoStr.split(':');
	if (list1.length != 7 || list2.length != 7) return false;
	
	var result = true;
	for (var i=0; i<3; i++) {
		result = (list1[i] == list2[i]) && result;
	};
	
	return result;
};
//---------------------------------------------------------------------------------------
function getSecondsFromTimeStr(timeStr) { //inverse of 'calculateTimeIntToString()'
	if (typeof(timeStr) == 'undefined' || timeStr == '') return 0;
	try {
		var list = timeStr.split(':');
		if (list.length != 3) return -1;
		
		for (var i=0; i<list.length; i++) {
			var elem = list[i];
			while (elem.indexOf('0') == 0) elem = elem.substring(1, elem.length)
			if (elem == '') elem = '0';
			list[i] = elem;
		};
		
		var result = (parseInt(list[0])*3600) + (parseInt(list[1])*60) + parseInt(list[2]); //pg2- IE8 has issues with 'parseInt('01', 10)
		return result;
	} catch(e) {};
	return 0;
};
//---------------------------------------------------------------------------------------
function getComponentByPartialId(partialId) {
	if (typeof(partialId) == 'undefined' || partialId == '' || typeof(pc) == 'undefined') return null;
	for (var i in pc) {
		var obj = pc[i];
		if (obj && obj.id.indexOf(partialId) != -1) return obj;
	};
};
//---------------------------------------------------------------------------------------
function calculateTimeIntToFormattedString(timeInt) {
	var str = calculateTimeIntToString(timeInt);
	var strList = str.split(':');
	var result = '';
	var start = 0; //yy : mm : dd : gg : mm : ss : ssss
	if (strList.length == 7) start = 3;
	for (var i=start; i<strList.length; i++) {
		var strSub = strList[i];
		if (strSub.length == 1) result += '0' + strList[i]; else result += strList[i];
		if (i < strList.length-1) result += ':';
	};
	return result;
};
//=========================================================
var timerBusy = false;
function TIMER_KNF() { //pg2-knf_new
	return;
};
//=====================================================================================================
function TIMER_KNF_PLAYER2() { //pg2-knf_new
	var course_time_max_per_day = '8:0:0'; //tutaj ustawiony maks czas na dzien h:m:s -tutaj 20 sek dla testow (8:0:0 a nie 8:00:00)
	var course_time_min_4completion = '24:0:0'; //minimalny czas aby uzyskac ukonczenie/zaliczenie
	
	if (timerBusy) return;
	
	var errorStr = '';
	var player = getPlayer();
	var sd = getSuspendData();
	var me = null;
	if (typeof(sd) != 'undefined' && sd != null) me = sd.me;
	try {
		if (player && me != null) {
			timerBusy = true;
			if (player.lessonMode != 'normal') {
				player.allowSendTime = false;
				timerBusy = false;
				return;
			};
			//-----------------------------------
			var dt1 = new Date();
			var dt2 = player.lastTimeRun;
			var dt1MS = dt1.getTime();
			var dt2MS = dt2.getTime();
			
			var diff = Math.abs(dt2MS - dt1MS);
			
			var dayTimeMax = getSecondsFromTimeStr(course_time_max_per_day) * 1000; //milliseconds
			var timeMin2SendStatus = getSecondsFromTimeStr(course_time_min_4completion) * 1000; //milliseconds
			
			//-----------------------------------//pg2-override player's inactivity feature
			var secondsFromLastActivity = Math.ceil(player.lastActivityTime.getTime()/1000);
			var secondsCurrent = Math.ceil(dt1MS/1000);
			var inactiveDiff = Math.abs(secondsFromLastActivity - secondsCurrent);
			
			if (inactiveDiff > config.inactivityTime) player.IsStudentActive = false; else player.IsStudentActive = true;
			//top.window.document.title = inactiveDiff + ', ' + Math.abs(config.inactivityTime - inactiveDiff);
			
			//-----------------------------------
			var last_launch_time = 0;
			if (me.last_launch_time != "") last_launch_time = parseInt(me.last_launch_time); else last_launch_time = dt2MS;   //me.last_launch_time;
			var this_launch_time = dt1MS;
			
			var lms_send_session_time = parseInt(me.lms_send_session_time);
			var lms_send_status = parseInt(me.lms_send_status); //zezwolenie na wyslanie statusu ukonczenia/zaliczenia

			var today_time = parseInt(me.today_time);
			if (isNaN(today_time)) today_time = 0;
			var total_time = parseInt(me.total_time); //
			if (isNaN(total_time)) total_time = 0;
			
			if (player.todayTime == 0) player.todayTime = today_time; else today_time = player.todayTime;
			//if (player.totalTime == 0) lms_send_session_time = 1; //pg2-test
			if (player.totalTime == 0 && lms_send_session_time == 1) { //pg2-knf3 -lms_send_session_time
				var timeFromLMS = player.scormLMS.totalTimeLMS * 1000; //pg2-knf_new_test (all with comment mark)
				if (timeFromLMS > total_time) {
					var diffTotalTime = Math.abs(timeFromLMS - total_time);
					player.totalTime = timeFromLMS;
					player.todayTime = player.todayTime + diffTotalTime;
				} else player.totalTime = total_time;
				//if (timeFromLMS > total_time) player.totalTime = timeFromLMS - 1; else 
				//player.totalTime = total_time;
				//if (player.totalTime < 0) player.totalTime = 0;
			} else {
				if (player.totalTime > 0) total_time = player.totalTime; //pg2-knf3 -if
			};
			
			player.allowSendTime = (lms_send_session_time == 1);
			
			//-----------------------------------
			var hotspot_id = 'hotspot_locked';
			var text_id = 'text_locked';
			var timer_text_id = 'main_timer_text'; //main_timer - od konca, pozostaly czas dzisiaj
			var total_time_id = 'total_time_text'; //total_timer - czas caaaalkowity
			var inactivity_text_id = 'text_inactive';

			var hotspot_locked = getComponentByPartialId(hotspot_id);
			var text_locked = getComponentByPartialId(text_id);
			var timer_text = getComponentByPartialId(timer_text_id);
			var total_time_text = getComponentByPartialId(total_time_id);
			var inactivity_text = getComponentByPartialId(inactivity_text_id);
			
			//-----------------------------------
			if (!player.IsStudentActive) { //pg2-inactivity
				player.lastTimeRun = dt1;
				me.last_launch_time = this_launch_time + '';
				inactivity_text.imWarningPopup = true;
				inactivity_text.show();
				delete dt1;
				timerBusy = false; //pg2-new
				return;
			} else {
				if (inactivity_text) inactivity_text.hide();
			};
			
			if (isTheSameDay(getDateStr(getDateObjFromMilliseconds(last_launch_time)), getDateStr(getDateObjFromMilliseconds(this_launch_time)))) {
				if (lms_send_session_time == 1 && today_time < dayTimeMax) {
					player.totalTime += diff; //IMPORTANT - update property of the player, otherwise time shift would occure
					total_time = player.totalTime;
					me.total_time = total_time + '';
					
					player.todayTime += diff;
					today_time = player.todayTime;
					me.today_time = today_time + '';
					
					player.lastTimeRun = dt1;
					me.last_launch_time = this_launch_time + '';
					
					if (total_time >= timeMin2SendStatus) me.lms_send_status = '1';
				};
				
				if (today_time >= dayTimeMax) { // max liczba godzin dziennie
					try {
						if (player && player.scormLMS && lms_send_session_time == 1) {
							me.last_launch_time = this_launch_time + '';
							
							player.scormLMS.setTime();
							player.scormLMS.LMSCommit();
						};
					} catch(e) {};

					player.todayTime = dayTimeMax; //pg2-knf3
					me.todayTime = dayTimeMax + ''; //pg2-knf3
					
					me.lms_send_session_time = '0';
					player.allowSendTime = false;
					//me.today_time = today_time;
					if (hotspot_locked) hotspot_locked.show(); //pokaz hotspota zakrywajacego cala strone (przyciski z akcjami)
					if (text_locked) text_locked.show(); //pokaz tekst z info ze przekroczony czas i klikniecie spowoduje wyjscie z kursu
				} else {
					me.lms_send_session_time = '1';
					player.allowSendTime = true;
					//me.today_time = today_time;
					//me.last_launch_time = this_launch_time;
				};
			
			} else {
				me.today_time = '0';
				player.todayTime = '0';
				player.lastTimeRun = dt1;
				
				player.allowSendTime = true;
				me.last_launch_time = this_launch_time + '';
				me.lms_send_session_time = '1';
			};
			
			//-----------------------------------
			var displayValueInText = function(obj, value) {
				if (typeof(obj) == 'undefined' || obj == null || value == '') return;
				obj.text = value;
				obj.orgText = value;
				obj.reinit();
				obj.paint();
			};
			
			displayValueInText(total_time_text, calculateTimeIntToFormattedString(Math.floor(total_time / 1000)) ); //pg2-knf3 -floor instead of ceil
			displayValueInText(timer_text, calculateTimeIntToFormattedString(Math.ceil(Math.abs(dayTimeMax - player.todayTime) / 1000))); //pg2-knf3 -ceil instead of floor
			//top.window.document.title = calculateTimeIntToFormattedString(Math.ceil(player.totalTime / 1000)); //calculateTimeToString(player.scormLMS.startTime, dt);
			
			//-----------------------------------
			delete dt1;
		};
	} catch(e) {
		errorStr = e.message;
	};
	timerBusy = false;
};
//-----------------------------------------
function KP_exam_pages() {
	var currentSCONo = parseInt(parent.currentIDSCOidx) + 1;
	if (typeof(top.KP_pagesCount) == 'undefined' || currentSCONo == 1) {
		top.KP_pagesCount = 0;
		var treeFrame = findFrame('Menu', top);
		if (treeFrame) {
			var pagesCount = 0;
			for (var i=0; i<1000; i++) {
				var trObj = null;
				try {
					trObj = treeFrame.document.getElementById('item_' + i);
					if (trObj) pagesCount++; else break;
				} catch(e) {};
			};
			top.KP_pagesCount = pagesCount;
		};
	};
	var txt = getComponentByPartialId('txt_pagesInfo');
	if (txt) {
		var str = currentSCONo + ' z ' + top.KP_pagesCount;
		txt.contentObj.innerHTML = txt.contentObj.innerHTML.replace('%s', str);
	};
};
//-------------------------------------
function displayConnectionInfo() { //pg2-BI_iPad_connection
	try {
		if (!page) var page = getPage();
		//var obj = findFrame('content', top).
		var obj = document.getElementById('error'); //document.getElementById('error');
		
		var msgWindowLeft = '550px'; //450
		var msgWindowTop = (Math.floor(page.pageHeight/2) + 75) + 'px'; //+0
		var msgWindowWidth = '450px'; //szerokosc calego okienka
		var msgWindowHeight = '150px';
		var msgWindowFrame = '2px solid #003164';

		var msgFont = 'Arial';
		var msgFontSize = '18px';
		var msgMarginFromTop = '10px'; //25
		var msgTextAlign = 'center';
		
		var msgText = '';
		if (is.safari && is.mobile) {
			msgText = 'Wykryto problemy z połączeniem/urządzeniem. Prosimy o wylogowanie się z platformy, zamknięcie niepotrzebnych aplikacji oraz zakładek przeglądarki, a następnie ponowne zalogowanie i uruchomienie szkolenia.';
			msgFontSize = '16px';
		} else {
			msgText = 'Wykryto problemy z połączeniem/urządzeniem. Prosimy o wylogowanie się z platformy, a następnie ponowne zalogowanie i uruchomienie szkolenia.';
		};
		
		var msgCloseText = 'ZAMKNIJ';
		var msgCloseFont = 'Arial';
		var msgCloseFontSize = '16px';
		var msgCloseMarginFromBottom = '10px'; //25
		var msgCloseTextAlign = 'center';
		
		if (page && obj) { // && !is.ie) {
			var left = Math.floor(page.pageWidth/2)
			var top = Math.floor(page.pageHeight/2);

			obj.style.left = msgWindowLeft;
			obj.style.top = msgWindowTop;
			obj.style.width = msgWindowWidth;
			obj.style.height = msgWindowHeight;
			obj.style.overflow = 'hidden'; //ukryte standardowo widoczne scrolle
			obj.style.position = 'relative'; //"...can't touch this"
			obj.style.border = msgWindowFrame;

			obj.style.visibility = 'visible';
			obj.style.display = 'block';
			obj.style.zIndex = '10000';

			var str = '<p style="margin-top:' + msgMarginFromTop + '; text-align:' + msgTextAlign + '; font-family:' + msgFont + '; font-size:' + msgFontSize + ';">';
			str += msgText;
			str += '</p>';

			str += '<span onclick="document.getElementById(\'error\').style.display=\'none\';" style="bottom:' + msgCloseMarginFromBottom +
					'; width:100%; position:absolute; text-align:' + msgCloseTextAlign + '; font-size:' + msgCloseFontSize + '; font-family:' +
					msgCloseFont + ';">' + msgCloseText + '</span>';
			obj.innerHTML = str;
		}
	} catch(e) {};
};

function displayCheckingConnectionIcon(showBox) { //pg2-BI_iPad_connection
	try {
		var obj = document.getElementById('error'); //document.getElementById('error');
		if (showBox) {
			obj.style.zIndex = '10000';
			return;
		};
		if (!page) var page = getPage();
		//var obj = findFrame('content', top).

		var msgWindowLeft = '740px'; //450
		var msgWindowTop = (Math.floor(page.pageHeight/2) + 125) + 'px'; //+0
		var msgWindowWidth = '130px'; //'130px'; //szerokosc calego okienka
		var msgWindowHeight = '130px';
		var msgWindowFrame = '0px solid #FFAAFF';
		
		var iconName = 'waitanimation.gif';
			
		if (page && obj) { // && !is.ie) {
			var left = Math.floor(page.pageWidth/2)
			var top = Math.floor(page.pageHeight/2);

			obj.style.left = msgWindowLeft;
			obj.style.top = msgWindowTop;
			obj.style.width = msgWindowWidth;
			obj.style.height = msgWindowHeight;
			obj.style.overflow = 'hidden'; //ukryte standardowo widoczne scrolle
			obj.style.position = 'relative'; //"...can't touch this"
			obj.style.border = msgWindowFrame;

			obj.style.visibility = 'visible'; //'hidden'; //'visible';
			obj.style.display = 'block';
			obj.style.zIndex = '-100';

			var str = '<img style="left:0px; top:0px; width:120px; height:120px;" src="' + resourcesURL + iconName + '">';
			obj.innerHTML = str;
		}
	} catch(e) {};
};
