(function(){
/*
#	hash function
*/
String.prototype.hashCode = function() {
	var hash = 0, i, chr;
	if (this.length === 0) return hash;
	for (i = 0; i < this.length; i++) {
		chr   = this.charCodeAt(i);
		hash  = ((hash << 5) - hash) + chr;
		hash |= 0; // Convert to 32bit integer
	}
	return hash;
};
/*
#	configuration
*/
var externalCheck = {
	checkServerUrl: window.location.origin + '/externalCheck/checkServer.php',
	checkHashFile: window.location.origin + '/externalCheck/hashFile.txt',
	nodeSelector: 'iframe,script,img,link,video,source',
	checkTypeExtended: false,
	timeToWait: 5000
};

/*
# check for elements and for local hashes
*/
var elementsToCheck = document.querySelectorAll(externalCheck.nodeSelector),
	srces = [],
	srcesOnce = [],
	hostname = window.location.hostname,
	hashStorage = sessionStorage.getItem('hashStorage'),
	hashes = [],
	hashesOnce = [];
var numberOfElements = elementsToCheck.length;
var intervalId;

if (hashStorage == null){
	sendCheck('get', function(){
		startInterval(externalCheck.timeToWait);
		checkTheElements();
	});
} else {
	if ( numberOfElements > 0) {
		checkTheElements();
	}
	startInterval(externalCheck.timeToWait);
}

/*
# interval stuff
*/
var counter=0;
var firstLoop=true;

function startInterval(wait) {
	intervalId = setInterval(function(){
		checkTheElements();
		counter++;
		if (counter == 6 ){
			clearInterval(intervalId);
			if (firstLoop) {
				firstLoop = false;
				startInterval(parseInt(externalCheck.timeToWait * 2));
			}

		}
		if (counter > 16) {

			clearInterval(intervalId);
		}
	},wait);
}

/*
# check for external elements on page
*/
function checkTheElements () {
	if(hashStorage === null) return;
	elementsToCheck = [];
	elementsToCheck = document.querySelectorAll(externalCheck.nodeSelector);
	hashStorage = sessionStorage.getItem('hashStorage');
	var reg = new RegExp("(^[^?]+)");
	srces = [];
	for (i=0; i < elementsToCheck.length; i++) {
		var link = '';
		var testTags = ['src','href','poster'];
		for (var ii = 0; ii < testTags.length; ii++) {
			if(typeof elementsToCheck[i][testTags[ii]] === 'string' && elementsToCheck[i][testTags[ii]] !== ''){
				link = elementsToCheck[i][testTags[ii]];
				break;
			}
		}
		if (link !== '' && (link.indexOf(hostname) === -1 || link.indexOf(hostname) > 10)) {
			var hash = reg.exec(link)[0].hashCode();
			if (hashStorage.indexOf(hash) === -1){
				srces.push({
					url: window.location.href,
					src: reg.exec(link)[0],
					tagName: elementsToCheck[i].nodeName,
					srcHash: hash
				})
			}
		}
	}
	sort_unique(srces);
}


/*
# send found elements to log them
*/
function sendCheck (mode,srcesOnce, callback) {
	var xhttp = new XMLHttpRequest();
	xhttp.onreadystatechange = function() {
		if (this.readyState == 4 && this.status == 200) {
			switch (mode){
				case 'get':
					sessionStorage.setItem('hashStorage', this.responseText);
				break;
				case 'send':
					var storage = sessionStorage.getItem('hashStorage');
					sessionStorage.setItem('hashStorage', storage+' '+this.responseText);
					var hashes = sessionStorage.getItem('hashStorage').replace(/  /g,' ').replace(/\r?\n|\r/g,'').split(' ');
					if (hashes.length > 0){
						sort_hashes(hashes);
					}
			}
		}
		if (callback && typeof(callback) === "function") callback()
	};

	switch (mode){
		case 'get':
			xhttp.open("GET", externalCheck.checkHashFile, true);
			xhttp.send();
			break;
		case 'send':
			xhttp.open("POST", externalCheck.checkServerUrl, true);
			xhttp.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
			xhttp.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
			xhttp.send(JSON.stringify(srcesOnce));
			break;
		default:
			break;
	}
}

/*
# sort unique function for log objects
*/
function sort_unique (srces){
	srces.sort(function(a, b) {
		return a.srcHash - b.srcHash;
	});
	srcesOnce = [];
	for (i=0; i < srces.length; i++) {
		if ( i > 0) {
			if ( srces[i].srcHash != srces[i-1].srcHash ) {
				srcesOnce.push(srces[i]);
			}
		} else {
			srcesOnce.push(srces[i]);
		}
	}
	if (srcesOnce.length > 0) {
		sendCheck('send', srcesOnce);
	}
}

/*
# sort hashes and save them to sessionStorage
*/
function sort_hashes (hashes){
	hashes.sort(function(a, b) {
		return a - b;
	});
	hashes.sort();
	hashesOnce = [];
	for (i=0; i < hashes.length; i++) {
		if (hashes[i].length > 0){
			if ( i > 0) {
				if ( hashes[i] != hashes[i-1] ) {
					hashesOnce.push(hashes[i]);
				}
			} else {
				hashesOnce.push(hashes[i]);
			}
		}
	}
	sessionStorage.setItem('hashStorage', hashesOnce.join(' '));
}
})();