MAIN_URL = "http://screenshoot.me/";
TWITTER_BUTTON = "<a href=\"http://twitter.com/share\" class=\"twitter-share-button\" data-url=\"%URL%\" data-counturl=\"%URL%\" data-count=\"none\" data-text=\"Check this out\">Tweet</a>";
TWITTER_BUTTON_SCRIPT = {type: "text/javascript", src: "http://platform.twitter.com/widgets.js"};
FB_BUTTON = "<iframe src=\"http://www.facebook.com/plugins/like.php?app_id=226662560679377&amp;href=%URL%&amp;send=false&amp;layout=button_count&amp;width=150&amp;show_faces=false&amp;action=recommend&amp;colorscheme=light&amp;font&amp;height=21\" style=\"border:none; overflow:hidden; width:150px; height:21px; margin-left: 5px\"></iframe>";

var MAX_IMAGE_SIZE = 4*1024*1024;

function getImage() {
	drawProcessingScreen(context, canvas);
	resetCrop();
	_getImage();
}

function _getImage() {
	var img = new Image();
	try {
		img.src = applet.getClipboardImage("png");
	} catch(e) {
		setTimeout(_getImage, 1000);
		return;
	}

	setTimeout(function(){ applyOnCanvas(img);}, 500);
}

function setImage() {
	applet.setClipboardImage(canvas.toDataURL());
}

function applyOnCanvas(img) {
	if (img.width == 0 || img.height == 0) {
		drawTitleScreen(context, canvas);
	} else {
		canvas.width = img.width;
		canvas.height = img.height;
		context.drawImage(img, 0, 0);
	}
	saveBitmap();
}

function cropImage() {
	if (cropDimension) {
		restoreWholeBitmap();
		var w = cropDimension[0] + cropDimension[2] + 1 > canvas.width ? canvas.width - cropDimension[0] : cropDimension[2] + 1;
		var h = cropDimension[1] + cropDimension[3] + 1 > canvas.height ? canvas.height - cropDimension[1] : cropDimension[3] + 1;
		cropData = context.getImageData(cropDimension[0], cropDimension[1], w, h);
		canvas.width = w;
		canvas.height = h;
		context.putImageData(cropData, 0, 0);
		saveBitmap();
		resetCrop();
	}
}

function saveImage() {
    var imageContent = canvas.toDataURL();
    if (imageContent.length > MAX_IMAGE_SIZE) {
        alert('This image is too big - '+(imageContent.length/(1024*1024)).toFixed(2)+'MB!\nThe maximum allowed image size is 4MB.');
        return;
    }
    
	if (bitmap) {
		restoreWholeBitmap();
		
		resetCrop();
		
		document.getElementById("content_editor").style.display = "none";
		document.getElementById("text_fields").style.display = "none";
		
		var desiredKey = "";
		if (/^\w{6,16}$/.test(lastKey) && document.getElementById("key_state_OK").style.display != "none") {
			desiredKey = "?desiredkey="+lastKey; // set the user's desired key
		}
		
		function handlerFunction(response) {
			url = MAIN_URL + response;
			document.getElementById("saving").innerHTML = "<div style=\"float: left\">Your image is here: <a href='"+url+"'>"+url+"</a></div><div id=\"new_screenshot_copy_url\" style=\"float: left; margin-left: 12px\"></div>\
			<div style=\"clear: both\"><a href='"+url+"' id=\"savingImage\"></a></div>\
            <div id=\"upload_new_one_button\" style=\"margin-top: 8px\"></div>\
            <div style=\"margin-top: 34px\"><div id='social_fb' class='fb-button'></div><div id='social_t' class='twitter-button'></div><div id='social_p1' class='plus1-button'></div></div>";
            
            generateShareButtons(url, document.getElementById('social_fb'), document.getElementById('social_t'), document.getElementById('social_p1'));
            
            var colorMap = {def: {border: "#FE9", bg: ["#FC3", "#FE9"]}, hover: {border: "#FE9", bg: ["#F90", "#FC0"]}, click: {border: "#FE9", bg: ["#F93", "#F93"]}, font: {color: "#336", style: "normal normal bold 11px 'Georgia'"}};
            var copyUrlBtn = buttonFactory(document.getElementById("new_screenshot_copy_url"), "Copy URL", 92, 24, colorMap, function(){});
            var code = clipboardButton(url, 92, 24, copyUrlBtn);
            var div = document.createElement('div');
            div.style.position = 'relative';
            div.style.top = '-32px';
            div.innerHTML = code;
            document.getElementById('new_screenshot_copy_url').appendChild(div);
            
            var uploadNewBtn = buttonFactory(document.getElementById("upload_new_one_button"), "Upload new one", 120, 24, colorMap, restartEditor);
            
			var img = new Image();
			img.src = imageContent;
			img.style.borderStyle = "none";
			img.onload = function() {
				var maxSide = Math.max(this.width, this.height);
				var SITE_LIMIT = 200;
				if (maxSide > SITE_LIMIT) {
					this.style.width = (SITE_LIMIT/maxSide*this.width)+"px";
					this.style.height = (SITE_LIMIT/maxSide*this.height)+"px";
				}
				document.getElementById("savingImage").appendChild(this);
			}

            addImageToGallery(response);
		}
		
        jx.loadImage("index.php"+desiredKey, imageContent, handlerFunction);
		
		document.getElementById("desired_key").value = "";
		_checkKey("");
		
		document.getElementById("saving").innerHTML = "Please wait a few seconds (uploading " + parseInt(imageContent.length/1024+1) + "KB)...";
	}
}

function restartEditor() {
    cropDimension = null; 
    document.getElementById("text_fields").style.display = "";
    document.getElementById("content_editor").style.display = "";
    document.getElementById("saving").innerHTML = "";
    drawTitleScreen(context, canvas); 
    saveBitmap();
}

function checkKey(key) {

	if (lastKey == key || key.length > 16 || key.length < 6) {
		if (key.length < 6) setKeyState("ERR");
		lastKey = key;
		return;
	}

	lastKey = key;
	
	if (!/^\w{6,16}$/.test(key)) {
		setKeyState("INV")
		return;
	}

	if (keyTimer) clearTimeout(keyTimer);
	keyTimer = setTimeout(function(){_checkKey(key)}, 1000);
}

function _checkKey(key) {
	if (key != document.getElementById("desired_key").value || key.length < 6) return;

	function handlerFunction(response) {
		setKeyState(/^(OK)|(USED)|(INV)$/.test(response) ? response : "ERR");
	}
	
	setKeyState("SPIN");
	jx.load("check.php?key="+key, handlerFunction, "text", "GET", null, "text/plain");
}

function setKeyState(state) {
	var states = ["ERR", "OK", "USED", "INV", "SPIN"];
	for (var i in states) {
		document.getElementById("key_state_" + states[i]).style.display = "none";
	}
	if (document.getElementById("key_state_" + state)) {
		document.getElementById("key_state_" + state).style.display = "inline";
	}
}

function saveBitmap(noUndo) {
	if (!noUndo && bitmap) undoStack.push(bitmap);
	bitmap = context.getImageData(0, 0, canvas.width, canvas.height);
}

function restoreWholeBitmap() {
	context.putImageData(bitmap, 0, 0);
}

function undo() {
	var imgData = undoStack.pop();
	if (imgData) {
		canvas.width = imgData.width;
		canvas.height = imgData.height;
		bitmap = imgData;
		context.putImageData(imgData, 0, 0);
	}
}

function restoreBitmap() {
	if (_imgData) {
		for (i in _imgData) {
			context.putImageData(_imgData[i][0], _imgData[i][1], _imgData[i][2]);
		}
	}
}

function prepare(_brushSizeSlider, _brushColorField) {

	if (!navigator.javaEnabled()) {
		alert("ScreenShootMe requires Java Runtime Environment! Please install JRE 1.5 or later and come back.");
	}
	
	applet = document.getElementById('pasteimage');
	canvas = document.getElementById('canvas');
	context = canvas.getContext('2d');
	
	undoStack = new ImageStack(25);
	
	sx = sy = null;
	mousePos = [0, 0];
	mouseDown = false;
	setMouseMode("SELECT");
	
	context.fillStyle = "#FFF";
	context.fillRect(0, 0, canvas.width, canvas.height);
	
	drawTitleScreen(context, canvas);
	
	bitmap = null;
	saveBitmap();
	mouseMoved = false;
	document.onmousemove = mouseMove;
	
	canvasOffsetLeft = document.getElementById("content_editor").offsetLeft + 120 + 12 + 3 + 1; 
	canvasOffsetTop = document.getElementById("content_editor").offsetTop + 2;
	
	resetCrop();
	
	lastKey = "";
	keyTimer = null;
	
	brushSizeSlider = _brushSizeSlider;
	brushColorField = _brushColorField;
	
}

function setMouseMode(v) {
	if (v == "SELECT") {
		mouseMode = "SELECT";
		resetCrop();
		canvas.onmousedown = function(e) {
			document.onmouseup = canvas.onmouseup;
			mouseDown = true;
			resetCrop();
			restoreWholeBitmap();
			sx = mousePos[0];
			sy = mousePos[1];
			if (sx < 0) sx = 0;
			if (sy < 0) sy = 0;
			e.preventDefault();
		} 
		canvas.onmouseup = function(e) {
			document.onmouseup = function(){};
			if (!mouseDown) return;
			if (sx != null && sy != null && mouseDown && mousePos[0] != sx && mousePos[1] != sy) {
				dimOut(sx, sy, mousePos[0]-sx, mousePos[1]-sy);
			}
			mouseDown = false;
			sx = sy = null;
		}
				
	} else {
		restoreWholeBitmap();
		mouseMode = "BRUSH";
		resetCrop();
		canvas.onmousedown = function(e) {
			document.onmouseup = canvas.onmouseup;
			if (!mouseMoved) { // Draw dot
				mousePos = mouseCoords(e);
				context.beginPath();
				context.fillStyle = getBrushColor();
				context.arc(mousePos[0], mousePos[1], getBrushSize()/2, 0, Math.PI*2, true);
				context.fill();
				context.closePath();
			}
			mouseMoved = true;
			mouseDown = true;
			cropData = null;
			sx = mousePos[0];
			sy = mousePos[1];
			if (sx < 0) sx = 0;
			if (sy < 0) sy = 0;
			e.preventDefault();
		} 
		canvas.onmouseup = function(e) {
			document.onmouseup = function(){};
			mouseMoved = false;
			mouseDown = false;
			sx = sy = null;
			saveBitmap();
		}
	}
}

function mouseMove(e) {
	e = e || window.event; 
	if (mouseDown && mouseMode == "BRUSH") {
		mouseMoved = true;
		context.beginPath();
		context.moveTo(mousePos[0], mousePos[1]);
		mousePos = mouseCoords(e);
	    context.lineTo(mousePos[0], mousePos[1]);
	    context.lineWidth = getBrushSize();
	    context.strokeStyle = getBrushColor();
		context.lineCap = "round";
		context.stroke();
		context.closePath();
	} else {
		mousePos = mouseCoords(e);
		if (mouseDown) drawSelectedArea();
	}
}

function mouseCoords(e){ 
	return [e.clientX + (document.documentElement.scrollLeft || document.body.scrollLeft) - document.documentElement.clientLeft - canvasOffsetLeft, 
		e.clientY + (document.documentElement.scrollTop || document.body.scrollTop) - document.documentElement.clientTop - canvasOffsetTop]; 
}

function drawSelectedArea() {
	restoreBitmap();
	context.fillStyle = "#0000FF";
	if (mousePos[0] < 0) mousePos[0] = 0;
	if (mousePos[1] < 0) mousePos[1] = 0;
	drawSelectionArea(sx, sy, mousePos[0]-sx, mousePos[1]-sy);
}

function drawSelectionArea(x, y, w, h, interval) {

	if (w == 0 || h == 0) return;

	if (!interval) interval = 2;
	
	if (w < 0) {
		x += w;
		w = -w;
		if (x < 0) {
			w += x;
			x = 0;
		}
	} else if (x+w >= canvas.width) {
		w = canvas.width - x - 1;
	}
	
	if (h < 0) {
		y += h;
		h = -h;
		if (y < 0) {
			h += y;
			y = 0;
		}
	} else if (y+h >= canvas.height) {
		h = canvas.height - y - 1;
	}
	
	_imgData = [[context.getImageData(x, y, w, 1), x, y], [context.getImageData(x, y+h, w, 1), x, y+h], [context.getImageData(x, y, 1, h), x, y], [context.getImageData(x+w, y, 1, h), x+w, y]];
	imgData = [context.getImageData(x, y, w, 1), context.getImageData(x, y+h, w, 1), context.getImageData(x, y, 1, h), context.getImageData(x+w, y, 1, h)];
	limit = [w, h];
	
	for (l = 0; l < 4; l++) {
		for (i = 0; i < 4*limit[parseInt(l/2)]; i += 4) {
			imgData[l].data[i] = imgData[l].data[i+1] = imgData[l].data[i+2] = (~((imgData[l].data[i]+imgData[l].data[i+1]+imgData[l].data[i+2])/3)) & 0xFF;
			if (parseInt((i+1)/(4*interval)) % 2) i += 4*interval;
		}
		context.putImageData(imgData[l], _imgData[l][1], _imgData[l][2]);
	}
}

function dimOut(x, y, w, h) {

	if (w < 0) {
		x += w;
		w = -w;
	}
	
	if (h < 0) {
		y += h;
		h = -h;
	}

	context.fillStyle = "rgba(0, 0, 0, 0.5)";
	context.fillRect(0, 0, x, canvas.height);
	context.fillRect(x, 0, canvas.width-x, y);
	context.fillRect(x+w+1, y, canvas.width-x-w-1, h+1);
	context.fillRect(x, y+h+1, canvas.width-x, canvas.height-y-h-1);
	
	if (x < 0) x = 0;
	if (y < 0) y = 0;
	
	cropDimension = [x, y, w, h];
}

function resetCrop() {
	cropDimension = null;
	_imgData = null;
}

function getBrushColor() {
	return brushColorField.value;
}

function getBrushSize() {
	return brushSizeSlider.getValue() - 0.5;
}

function generateShareButtons(url, fbContainer, tContainer, p1Container) {

    fbContainer.innerHTML = FB_BUTTON.replace("%URL%", escape(url));

    tContainer.innerHTML = TWITTER_BUTTON.replace(/%URL%/g, url);
    var tScript = document.createElement("script");
	tScript.type = TWITTER_BUTTON_SCRIPT.type;
	tScript.src = TWITTER_BUTTON_SCRIPT.src;
    tContainer.appendChild(tScript);
    
    gapi.plusone.render(p1Container, {"size": "medium", "count": "false", "href": url});
}

function clipboardButton(text, w, h, btn) {
    var clip = new ZeroClipboard.Client();
    clip.setText(text);
    
    if (btn) {
        clip.addEventListener('onMouseOver', btn.button.onmouseover);
        clip.addEventListener('onMouseOut', btn.button.onmouseout);
        clip.addEventListener('onMouseDown', btn.button.onmousedown);
        clip.addEventListener('onMouseUp', btn.button.onmouseup);
    }
    
    return clip.getHTML(w, h);
}
