/*
Copyright 2003 David Finch. All rights reserved.

Released under the Revised BSD License.
*/


var entropy=[];
var entropysize=0;

var totalEnt=0;

//gotta initialize it to something.
var hashes=[
	"ntZkADR3i4q7X9Mafud+EolnI/A",
	"W/fR752fgXEeLFsltSi3zEoDuUY",
	"vIJg7ah9azuFIV9+4p56SAIzLIY",
	"afcMZ26oDw5D6pdveVCYAnJjblY"
];





var chash=0;


function initEnt() {
	//which browser they're using
	//may also tell us operating system and installed extras
	addEnt(navigator.userAgent);
	
	//window dimensions
	if(document.all) {
		addEnt(document.body.clientWidth);
		addEnt(document.body.clientHeight);
		addEnt(document.body.scrollWidth);
		addEnt(document.body.scrollHeight);
	} else {
		addEnt(window.innerWidth);
		addEnt(window.innerHeight);
		addEnt(window.width);
		addEnt(window.height);
	}
	
	//get a bit from the browser's PRNG
	addEnt(Math.random());
	addEnt(Math.random());

	//screen dimensions
	addEnt(screen.width);
	addEnt(screen.height);
	
	//current url
	addEnt(document.location.href);

	//time.
	timeEnt();
	timeEnt();

	totalEnt=32;
}
function nextHash() {
	hashes[chash]=b64_sha1(hashes.join("")+entropy.join("|"))
	chash=(chash+1)&3;
	entropy=[];
	entropysize=0;
}
function addEnt(str) {
	str=""+str;
	entropysize+=str.length+1;
	entropy[entropy.length]=str;

	//occasionally rehash for performance reasons
	//better than a few long hashes at the end.
	if(entropysize>=108) nextHash();
	
}

//use this if you need the added text to affect all 640 bits of the internal state.
function addLargeText(str) {
	str=""+str;
	addEnt(str);
	nextHash();
	addEnt(str);
	nextHash();
	addEnt(str);
	nextHash();
	addEnt(str);
	totalEnt+=str.length*0.5; //assume as little as 1/2 bit per character
}
function addText(str) {
	str=""+str;
	addEnt(str);
	totalEnt+=str.length*0.5; //assume as little as 1/2 bit per character
}
function getEnt() {
	nextHash();
	return hashes.join("");
}
function getEstimate() {
	return Math.floor(totalEnt<640?totalEnt:640);
}
function timeEnt() {
	var i=0;
	var d=1*new Date();
	while(1*new Date()==d) i++; //measure iterations until next tick
	addEnt(d);
	addEnt(i);

	totalEnt+=4;
}
function mouseEnt(e) {
	addEnt("m");
	if(e){
		addEnt(e.x || e.pageX);
		addEnt(e.y || e.pageY);
	} else {
		addEnt(event.clientX);
		addEnt(event.clientY);
	}
	timeEnt();

	totalEnt+=2;
}
function keyEnt(e) {
	e=e||window.event;
	addEnt(e.type);
	addEnt(e.which || e.keyCode);
	timeEnt();

	totalEnt+=0.7; //small because each key results in 2 events, and may possibly be recounted in addText()
}