﻿var util = {
	getCssClass: function(str) {
		return str.replace(/\W/g, '');
	},

	createMargin: function(codeEl) {
		var code = $(codeEl);
		var codeHtml = code.html();

		// a newline before the closing tag will be absorbed by the renderer so don't count it
		if(codeHtml.substring(codeHtml.length - 1, codeHtml.length) == '\n') {
			codeHtml = codeHtml.substring(0, codeHtml.length - 1);
		}

		// count the lines
		var lines = 1;
		var i = 0;
		var next = 0;

		while((next = codeHtml.indexOf('\n', i)) != -1) {
			i = next + 1;
			lines++;
		}

		// add +1 for divs
		lines += code.find('div').length;

		var marginHtml = '<div class="margin">'
		for(var i = 0; i < lines; i++) {
			marginHtml += '<div><span class="IndicatorMargin">&nbsp;</span><span class="LineNumbers">' + (i + 1) + '</span></div>';
		}
		marginHtml += '</div>';

		var customisable = code.closest('.customisable');
		var margin = $(marginHtml).prependTo(customisable);
	},

	beginLoad: function() {
		var asyncLoad = $("#asyncLoad");
		if(asyncLoad.length == 0) {
			asyncLoad = $('<div id="asyncLoad">Loading...</div>').appendTo("body");
		}

		var top = $(window).height() / 2 - 20;
		var left = $(window).width() / 2 - 90;

		asyncLoad.css("top", top + "px").css("left", left + "px");

		asyncLoad.fadeIn(500);
	},

	endLoad: function() {
		$("#asyncLoad").fadeOut(500);
	},

	addOutlining: function(code, editable) {
		var olDirections = code.find(".ol");

		// add vertical rule
		var startY = olDirections.first().position().top + 4;
		var endY = olDirections.last().position().top + 14;

		$('<div class="ol-vertical-rule OutliningMarginVerticalRule"></div>')
			.css("top", (startY) + "px")
			.css("height", (endY - startY) + "px")
			.appendTo(code);

		// add start blocks
		olDirections.filter(".start-block").each(function() {
			var el = $(this);
			var top = el.position().top;

			var box = $('<div class="ol-start-block OutliningMarginSquare">&ndash;</div>');

			if(el.hasClass("collapse")) box.text('+');
			else box.addClass("expanded");

			box.css("top", (top + 4) + "px")
				.appendTo(code);
		});
		setItems("Outlining Margin Square", editable);

		// add end blocks
		olDirections.filter(".end-block").each(function() {
			var el = $(this);
			var bottom = el.position().top + 14;

			// make an adjustment for end block inside a collapsible region
			if(!el.offsetParent().hasClass("code")) {
				bottom += el.offsetParent().position().top;
			}

			$('<div class="ol-end-block OutliningMarginVerticalRule"></div>')
				.css("top", bottom + "px")
				.appendTo(code);
		});

		setItems("Outlining Margin Vertical Rule", editable); // must be done last because it applies to all

		// CollapsibleRegion - add background in margin (only does the 1st found)
		var colRegion = $('.CollapsibleRegion').eq(0);
		if(colRegion.length > 0) {
			var top = colRegion.position().top;
			var height = colRegion.height();

			$('<div class="ol-colregion"></div>')
				.css("top", top + "px")
				.css("height", height + "px")
				.appendTo(code);

			// shift collapsible region left to meet margin
			var width = colRegion.width();
			colRegion.css("width", width + 2 + "px");

			setItems("Collapsible Region", editable);
		}

	},

	addBreakpoints: function(code, editable) {
		var bp = code.find('.BreakpointEnabled,.CurrentStatement');

		var setting = settings.Categories['Text Editor'].Items['Breakpoint (Enabled)'];
		var default_bg = rgbToString(setting.bg);

		bp.each(function(i, el) {
			var statement = $(el);
			var circle = $('<div class="bp-circle"></div>');

			if(statement.hasClass('CurrentStatement')) {
				circle.addClass('current');
			}

			circle.appendTo(code).css('top', statement.position().top + "px");

		});

	},

	supports_canvas: null,
	underlineSquiggle: function(element, color) {
		var el = $(element);
		var width = el.width();

		var c = document.createElement("canvas");

		if(util.supports_canvas == null) {
			if(c.getContext) util.supports_canvas = true;
			else util.supports_canvas = false;
		}

		if(!util.supports_canvas) {
			el.css("border-bottom", "1px dashed " + color);
			return;
		}

		el.css("position", "relative").css("overflow", "hidden");

		var cEl = el.children("canvas");
		var clear = false;

		if(cEl.length == 0) {
			cEl = $(c).appendTo(el);
		} else {
			c = cEl[0];
			clear = true;
		}

		c.style.position = "absolute";
		c.style.bottom = "-1px";
		c.style.left = "0";

		c.width = width;
		c.height = 3;

		var ctx = c.getContext('2d');

		if(clear) {
			ctx.clearRect(0, 0, width, 3);
		}

		ctx.strokeStyle = color;
		ctx.beginPath();

		var radius = 1.5;
		for(var x = 1; x < width; x += radius * 4) {
			ctx.arc(x + radius, 2, radius, Math.PI, 0, false);
			ctx.arc(x + radius * 3, 1, radius, Math.PI, 0, true);
		}
		ctx.stroke();

		// doesn't work in IE9
		//cEl.css("width", "100%"); // Chrome seems to overrun the width sometimes, this sets it back to normal
	}
}
