var isReady = false;

var pi2 = 2 * Math.PI;

var i, j, radius, angle, distance, tempDistance, xp, yp, closestX, closestY, closestIndex, closestDistance, tempX, tempY, circles, posX, posY;

var boundsXMin = 20000;
var boundsXMax = 0;
var boundsYMin = 20000;
var boundsYMax = 0;
var boundsWidth, boundsHeight, scaleX, scaleY, scale;
var startX, startY;

var lastClosestIndex = -1;
var gap = 5;
var centreX;
var centreY;
var circleData = [];
var circlePositions = [];
var fails = [];
var maxfails = 1000;
var closesetPoints = [];
var clouds;

var date;
var time = 0;

var backgroundColor = '#fff';


var drawModifier;

var checkPopularInterval

function startPopular() {

    clearInterval(checkPopularInterval);
    if (!popularWall) {
        checkPopularInterval = setInterval(startPopular, 1000);
        return;
    }

    clearPopular();

   

	boundsXMin = 20000;
	boundsXMax = 0;
	boundsYMin = 20000;
	boundsYMax = 0;
	
	lastClosestIndex = -1;
	circleData = [];
	circlePositions = [];
	fails = [];
	closesetPoints = [];
	clouds = [];

	ctx = popularWall.getContext("2d");
	
	resizeWindowCircles();
	
	//alert( 'startPopular' + popularWall + popularWall.width + ' ' + popularWall.height + ' ' + popularWall.left + ' ' + popularWall.top);
	//var sizes = '';

	$.getJSON('/Ajax/GetPopular.ashx', GetFilters(), function (data) {
    //$.getJSON('/test.json.txt', GetFilters(), function (data) {
	    checkData(data);
	    circles = data.length;
	    $.each(data, function (index, item) {      

	        if (index == 0) {
	            drawModifier = 500 / (item.Count + 5) / circles;
	        }

	        clouds[index] = {
	            id: item.Event.Id,
	            category: item.Event.Categories[0].Name,
	            size: (item.Count + 5) * drawModifier,
	            color: getCategoryColour(item.Event.Categories[0].Name)
	        }

	        //sizes += ( circles + ' ' + clouds[index].id + ' ' + clouds[index].size + ' ' + clouds[index].color );
	        //sizes += ( clouds[index].size + ', ' );
	    });

	    $('canvas').css('visibility', 'visible');

	    xp = centreX;
	    yp = centreY;

	    angle = Math.random() * 360;

	    for (i = 0; i < circles; i++) {

	        fails[i] = 0;

	        // set radius to be the popularity amount
	        // set color to category

	        radius = clouds[i].size;
	        color = clouds[i].color;
			
	        angle -= 5; //angle -= 0.1;

	        if (i) {
	            var coolPos = getRandomPosition(xp, yp);
	            xp = coolPos[0];
	            yp = coolPos[1];

	        }

	        circleData[i] = { x: xp, y: yp, r: radius, col: color };
	        circlePositions[i] = circleData[i];

	        boundsXMin = Math.min(boundsXMin, xp - radius - gap);
	        boundsXMax = Math.max(boundsXMax, xp + radius + gap);
	        boundsYMin = Math.min(boundsYMin, yp - radius - gap);
	        boundsYMax = Math.max(boundsYMax, yp + radius + gap);

	    }

	    boundsWidth = boundsXMax - boundsXMin;
	    boundsHeight = boundsYMax - boundsYMin;

	    drawCircles();

	    $(window).bind("resize", resizeWindowCircles);
	    $(document).bind("mousemove", getClosest);
	    $(document).bind("click", getPopup);


	    isReady = true;


	});
}
	
function clearPopular() {
	isReady = false;
	$(window).unbind("resize", resizeWindowCircles);
	$(document).unbind("mousemove", getClosest);
	$(document).unbind("click", getPopup);
	$('canvas').css('visibility', 'hidden');
	
}



function resizeWindowCircles(){
	graphWidth = $(window).width(); //pageWidth() - 20;
	graphHeight = $(window).height(); //pageHeight() - 20;
	
	centreX = graphWidth * 0.5;
	centreY = graphHeight * 0.5;
	if ( isReady ) {
		drawCircles();
	}
}





function drawCircles() {
	
	popularWall.width = graphWidth;
	popularWall.height = graphHeight;
	
	ctx.fillStyle=backgroundColor;
	ctx.fillRect(0, 0, graphWidth, graphHeight);
	
	scaleX = graphWidth / boundsWidth;
	scaleY = graphHeight / boundsHeight;
	scale = Math.min( scaleX, scaleY );
	
	if ( scale == scaleX ) {
		startX = 0;
		startY = (graphHeight - boundsHeight * scale) * 0.5;
	} else if ( scale == scaleY ){
		startX = (graphWidth - boundsWidth * scale) * 0.5;
		startY = 0;
	}
	
	for ( i = 0; i < circles; i++ ) {
		xp = startX + (circleData[i].x - boundsXMin) * scale;
		yp = startY + (circleData[i].y - boundsYMin) * scale;
		radius = circleData[i].r * scale;
		circlePositions[i] = { x: xp, y: yp, r: radius };
		mouseOut( i );
	}
	
}



function getClosest(e){
	
	posX = e.pageX;
	posY = e.pageY;

	distance = 200000;
	closestIndex = circles;

	if (circles) {

	    for (j = 0; j < circles; j++) {
	        deltaX = posX - circlePositions[j].x;
	        deltaY = posY - circlePositions[j].y;
	        tempDistance = Math.sqrt(deltaX * deltaX + deltaY * deltaY) - circlePositions[j].r;
	        distance = Math.min(tempDistance, distance);
	        if (tempDistance == distance) {
	            closestIndex = j;
	            closestDistance = distance + circlePositions[j].r;
	        }
	    }

	    var isOver = (closestDistance < circlePositions[closestIndex].r);
	    if (isOver) {

	        document.body.style.cursor = 'pointer';

	        if (lastClosestIndex != closestIndex) {
	            mouseOver(closestIndex);
	            if (lastClosestIndex > -1) {
	                mouseOut(lastClosestIndex);
	            }
	            lastClosestIndex = closestIndex;
	        }

	    } else {

	        document.body.style.cursor = 'default';
	        if (lastClosestIndex > -1) {
	            mouseOut(lastClosestIndex);
	        }
	        lastClosestIndex = -1;
	    }
	}
} 

function mouseOut( id ) {
	ctx.fillStyle = backgroundColor;
	ctx.beginPath();
	ctx.arc(circlePositions[id].x, circlePositions[id].y, circlePositions[id].r + 6, 0, pi2, 0);
	ctx.closePath();
	ctx.fill();
	
	//alert( circleData[id].col + ' ' + getCircleColour( circleData[id].col, 0.8 ) );
	
	ctx.fillStyle = getCircleColour( circleData[id].col, 0.8 );
	ctx.beginPath();
	ctx.arc(circlePositions[id].x, circlePositions[id].y, circlePositions[id].r, 0, pi2, 0);
	ctx.closePath();
	ctx.fill();
}

function mouseOver( id ) {
	ctx.fillStyle = getCircleColour( circleData[id].col, 1 );
	ctx.beginPath();
	ctx.arc(circlePositions[id].x, circlePositions[id].y, circlePositions[id].r + 5, 0, pi2, 0);
	ctx.closePath();
	ctx.fill();
}

function getPopup() {
	$("div.eventCloud").remove();
	if ( lastClosestIndex > -1 ) {
		var globalOps = {
			leftPos: circlePositions[lastClosestIndex].x,
			topPos: circlePositions[lastClosestIndex].y,
	    cat: clouds[lastClosestIndex].category
		}
		//alert( circlePositions[lastClosestIndex].x + ' ' + circlePositions[lastClosestIndex].y );
		requestInfoPop(clouds[lastClosestIndex].id, globalOps);
	}
}


function getRandomPosition( tempX, tempY) {

    if (fails[i] > maxfails) {
        
        return [tempX, tempY];
    }
    
	tempX += Math.sin(angle)*5;
	tempY += Math.cos(angle)*5;
	
	if ( tempX > graphWidth ) tempX -= graphWidth;
	if ( tempX < 0 ) tempX += graphWidth;
	
	if ( tempY > graphHeight ) tempY -= graphHeight;
	if ( tempY < 0 ) tempY += graphHeight;
	
	var ok = true;
	
	for ( j = i - 1; j > -1; j-- ) {
		
		deltaX = tempX - circleData[j].x;
		deltaY = tempY - circleData[j].y;
		distance = Math.sqrt( deltaX * deltaX + deltaY * deltaY ) - radius - circleData[j].r;
		
		if ( distance < gap * 2 ) {
			ok = false;
			j = 0;
		}
		
	}
	if ( !ok ) {
	    fails[i]++;
	    
		return getRandomPosition(tempX,tempY);
	} else {

    return [tempX, tempY];
    
	}
	
}



function getCircleColour( hex, opacity ) {
	// modded from http://hex2rgba.devoth.com/js/main.js
	
	hex = ( hex.charAt(0) == "#" ? hex.substr(1) : hex );
	// check if 6 letters are provided
	if (hex.length == 6) {
		r = parseInt(hex.substring(0, 2), 16);
		g = parseInt(hex.substring(2, 4), 16);
		b = parseInt(hex.substring(4, 6), 16);
	} else if (hex.length == 3) {
		r = parseInt(hex.substring(0, 1) + hex.substring(0, 1), 16);
		g = parseInt(hex.substring(1, 2) + hex.substring(1, 2), 16);
		b = parseInt(hex.substring(2, 3) + hex.substring(2, 3), 16);
	}
	
	// ('rgb(' + r + ', ' + g + ', ' + b + ')');
	return 'rgba(' + r + ', ' + g + ', ' + b + ', ' + opacity + ')';
}

