﻿function EwaUtils() { };

EwaUtils.promiseCallback = function (promise) {
	return function (result) {
		if (result.getSucceeded())
			promise.resolveWith(null, [result]);
		else
			promise.rejectWith(null, [result]);
	}
}

EwaUtils.setCells = function (ewa, data, sheetName, startRow, startColumn, callback) {
	var maxRange = 10000;

	// assume a square matrix
	var rowCount = data.length;
	var colCount = data[0].length;

	var remaining = rowCount * colCount;

	// This is called each time a result returns
	var outstanding = 0;
	function Completed(result) {
		outstanding--;
		if (outstanding == 0) {
			callback(result);
		}
	}

	// indices of the next row and column to get relative to the top left of the range
	var nextRow = 0;
	var nextCol = 0;

	while (remaining) {
		// Get as many columns as possible
		var colsToGet = Math.min(colCount - nextCol, maxRange);

		// Then get as many rows as possible at that column count
		var rowsToGet = Math.min(Math.floor(maxRange / colsToGet), rowCount - nextRow);

		// populate the data rows
		var rows;
		if (colsToGet == colCount) {
			rows = data.slice(nextRow, nextRow + rowsToGet);
		} else {
			rows = [];
			for (var i = 0; i < rowsToGet; i++) {
				rows[i] = data[nextRow + i].slice(nextCol, nextCol + colsToGet);
			}
		}

		// Queue up the request, but don't wait for it to be completed
		var range = ewa.getActiveWorkbook().getRange(sheetName, startRow + nextRow, startColumn + nextCol, rowsToGet, colsToGet);
		range.setValuesAsync(rows, Completed, null);
		outstanding++;

		// Accounting
		nextRow += rowsToGet;
		if (nextRow == rowCount) {
			nextRow = 0;
			nextCol += colsToGet;
		}

		remaining -= rowsToGet * colsToGet;
	}
}

EwaUtils.loadEwaIsolatedAsync = function (fileToken, iframe, props, callback, userContext, version) {
	var frameDoc = iframe.contentWindow.document;

	// set some style
	EwaUtils._ensureBodyStyle(iframe);

	// create the div
	var div = frameDoc.createElement('div');
	div.setAttribute('id', iframe.id || 'innerDivId');
	var style = div.style;
	style.height = "100%";
	style.width = "100%";
	style.backgroundColor = "White";
	style.color = "Black";
	frameDoc.body.appendChild(div);

	function scriptLoaded() {
		iframe.contentWindow['Ewa'].EwaControl.loadEwaAsync(fileToken, div.id, props, callback, userContext);
	}

	// load the script element
	// TODO: what if the script download fails?
	EwaUtils._loadScriptElement(frameDoc, EwaUtils._getIncludeUrl(version), scriptLoaded);
}

EwaUtils.getIsolatedEwa = function (iframe) {
	var EwaNamespace = iframe.contentWindow['Ewa'];
	if (EwaNamespace && EwaNamespace.EwaControlCollection.getCount() > 0) {
		return EwaNamespace.EwaControlControlCollection.getItem(0);
	}

	return null;
}

EwaUtils.setMessage = function (iframe, message) {
	var frameDoc = iframe.contentWindow.document;
	var messageDiv = frameDoc.getElementById(EwaUtils._msgId);
	if (!messageDiv) {
		EwaUtils._ensureBodyStyle(iframe);

		var container = frameDoc.createElement("div");
		container.setAttribute("id", EwaUtils._msgCntId);
		var style = container.style;
		style.zIndex = 1000000;
		style.position = "absolute";
		style.left = "0";
		style.top = "0";
		style.width = "100%";
		style.height = "100%"

		var background = frameDoc.createElement("div");
		style = background.style;
		style.position = "absolute";
		style.left = "0";
		style.top = "0";
		style.width = "100%";
		style.height = "100%";
		style.backgroundColor = "Black";
		style.opacity = 0.7;
		style.filter = 'alpha(opacity=70)';
		container.appendChild(background);

		var messageWidth = Math.min(frameDoc.body.clientWidth, 300);
		var margin = -1 * Math.floor(messageWidth / 2);

		messageDiv = frameDoc.createElement("div");
		messageDiv.setAttribute("id", EwaUtils._msgId);
		style = messageDiv.style;
		style.width = messageWidth + "px";
		style.textAlign = "center";
		style.position = "absolute";
		style.left = "50%";
		style.top = "50%";
		style.marginLeft = margin + "px";
		style.fontSize = "12pt";
		style.color = "White";
		container.appendChild(messageDiv);

		frameDoc.body.appendChild(container);
	}

	messageDiv.innerHTML = message;
}

EwaUtils.setMessageVisible = function (iframe, visible) {
	var messageContainer = iframe.contentWindow.document.getElementById(EwaUtils._msgCntId);
	if (messageContainer) {
		var style = messageContainer.style;
		if (visible) {
			style.visibility = style.display = "";
		} else {
			style.visibility = "hidden";
			style.display = "none";
		}
	}
}

EwaUtils.getMessageVisible = function (iframe) {
	var messageContainer = iframe.contentWindow.document.getElementById(EwaUtils._msgCntId);
	return messageContainer && messageContainer.style.visibility != "hidden";
}

EwaUtils._getIncludeUrl = function (version) {
	return "//r.office.microsoft.com/r/rlidExcelWLJS?kip=1&v=" + encodeURIComponent(version || 1);
}

EwaUtils._ensureBodyStyle = function (iframe) {
	var style = iframe.contentWindow.document.body.style;
	style.margin = 0;
	style.padding = 0;
	style.backgroundColor = "White";
}

EwaUtils._loadScriptElement = function (targetDoc, src, callback) {
	var se = targetDoc.createElement('script');
	se.setAttribute('type', 'text/javascript');
	se.src = src;

	var internalCallback = function () {
		if (se.readyState) se.onreadystatechange = null;
		else se.onload = se.onerror = null;

		callback();
	}

	if (se.readyState) {
		se.onreadystatechange = function () {
			if (se.readyState === 'loaded' || se.readyState === 'complete') {
				internalCallback();
			}
		};
	} else {
		se.onload = se.onerror = internalCallback;
	}

	targetDoc.getElementsByTagName('head')[0].appendChild(se);
}

EwaUtils._msgId = "EwaUtilsMessage";
EwaUtils._msgCntId = 'EwaUtilsMessageContainer';
