;

//

var contented = (function() {
	"use strict";
	
	// @ref https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/toBlob 
	if (!HTMLCanvasElement.prototype.toBlob) {
		Object.defineProperty(HTMLCanvasElement.prototype, 'toBlob', {
			value: function (callback, type, quality) {

				var binStr = atob( this.toDataURL(type, quality).split(',')[1] ),
					len = binStr.length,
					arr = new Uint8Array(len);

				for (var i = 0; i < len; i++ ) {
					arr[i] = binStr.charCodeAt(i);
				}

				callback( new Blob( [arr], {type: type || 'image/png'} ) );
			}
		});
	}

	var getCurrentScriptPath = function () {
        // Determine current script path
        // @ref https://stackoverflow.com/a/26023176
        var scripts = document.querySelectorAll('script[src]');
        var currentScript = scripts[scripts.length - 1].src;
        var currentScriptChunks = currentScript.split('/');
        var currentScriptFile = currentScriptChunks[currentScriptChunks.length - 1];

        return currentScript.replace(currentScriptFile, '');
    };
	
	var currentScriptPath = getCurrentScriptPath();
	var baseURL = currentScriptPath.replace('sdk.js', '');
	
	return {
		"loaded": false,
		
		"baseURL": baseURL,
		
		"__preInit": [],
		
		/**
		* initArea shows the contented upload widget over the top of a target DOM element.
		*
		* @param any        element       Drop target (string selector / DOMElement / jQuery)
		* @param Function   onUploaded    Called with an array of upload IDs
		* @param Function   onClose       Called when the widget is being destroyed
		*/
		"init": function(elementSelector, onUploaded, onClose) {
			contented.__preInit.push([elementSelector, onUploaded, onClose]);
		},
		
		/**
		* supportsDrop returns whether drag-and-drop is supported by this browser.
		*
		* @return bool
		*/
		"supportsDrop": function() {
			return ('ondrop' in window && 'FormData' in window && 'FileReader' in window);
		},
		
		"getPreviewURL": function(id) {
			return baseURL + "p/" + encodeURIComponent(id);
		},
		"getMultiPreviewURL": function(items) {
			return baseURL + "p/" + encodeURIComponent(items.join("-"));
		},
		"getDownloadURL": function(id) {
			return baseURL + "get/" + encodeURIComponent(id);
		},
		"getInfoJSONURL": function(id) {
			return baseURL + "info/" + encodeURIComponent(id);
		},
		"getThumbnailURL": function(thumbnailType, id) {
			return baseURL + "thumb/" + encodeURIComponent(thumbnailType) + "/" + encodeURIComponent(id);
		},
		"thumbnail": {
			"small_square": "s",
			"medium_square": "b",
			"medium": "t",
			"large": "m",
			"xlarge": "l",
			"xxlarge": "h"
		}
	};
	
})();

;(function() {
	"use strict";
	
	var loadScript = function(url, onLoad) {
		var script = document.createElement('script');
		script.onload = onLoad;
		script.src = url;
		document.head.appendChild(script);
	};
	
	var loadScripts = function(urls, onLoad) {
		// load sequentially
		var i = 0;
		var loadNext = function() {
			if (i === urls.length) {
				onLoad();
				return;
			}
			
			var url = urls[i];
			i += 1;
			loadScript(url, loadNext);
		};
		loadNext();
	};
		
    var formatBytes = function(bytes) {
		var k = 1024, m = (1024*1024), g = (1024*1024*1024);
		
        if (bytes < k) {
            return bytes + " B";
        } else if (bytes < m) {
            return (bytes / k).toFixed(1) + " KiB";
        } else if (bytes < g) {
            return (bytes / m).toFixed(1) + " MiB";
        } else {
            return (bytes / g).toFixed(1) + " GiB";
        }
    };
	
	// @ref https://stackoverflow.com/a/2117523
	var guid = function uuidv4() {
		return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
			var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8);
			return v.toString(16);
		});
	};

	var afterScriptsLoaded = function() {		

		var initArea = function (elementSelector, onUploaded, onClose) {
			onUploaded = onUploaded || function () { };
			onClose = onClose || function () { };

			if ($(elementSelector).length != 1) {
				return; // should only find one element
			}
			var element = $(elementSelector)[0];

			// <input type="hidden" name="MAX_FILE_SIZE" value="` + ret.MaxUploadBytes + `" /> 

			// Create a new div for ourselves on top of the existing area
			$.get(contented.baseURL + "about", function (ret) {
				
				var extraText = "";
				if (ret.MaxUploadBytes > 0) {
					extraText = " (max " + formatBytes(ret.MaxUploadBytes) + ")";
				}

				$.get(contented.baseURL + "widget.html", function (widgetHtml) {

					var $f = $("<div>").html(widgetHtml);
					$f.find(".contented-extratext").text(extraText);

					// Tab buttons
					
					var hasSetupDrawingBoardYet = false;
					var setType = function (type) {
						$f.find(".contented-upload-type").removeClass("contented-upload-type-active");
						$f.find(".contented-upload-type[data-upload-type=" + type + "]").addClass("contented-upload-type-active");

						$f.find(".contented-upload-if").removeClass("contented-active");
						$f.find(".contented-if-" + type).addClass("contented-active");
						
						if (type == "drag") {
							enablePasteHandler();
						} else {
							disablePasteHandler();
						}
						
						if (type == "drawing" && !hasSetupDrawingBoardYet) {
							setupDrawingBoard();
							hasSetupDrawingBoardYet = true;
						}
					};

					$f.find(".contented-upload-type").click(function () {
						setType($(this).attr('data-upload-type'));
					});

					// Widget positioning

					var $element = $(element);
					var offset = $element.offset();

					$f.css({
						'position': 'absolute',
						'left': offset.left + "px",
						'top': offset.top + "px",
						'width': $element.width() + "px",
						'min-width': $element.width() + "px",
						'max-width': $element.width() + "px",
						'height': $element.height() + "px",
						'min-height': $element.height() + "px",
						'max-height': $element.height() + "px"
					});

					// Drag and drop support
					
					$f.find('.contented').on('dragover dragenter', function (e) {
						e.preventDefault();
						e.stopPropagation();
						$(this).addClass('is-dragging');
					});

					$f.find('.contented').on('dragleave dragend', function (e) {
						e.preventDefault();
						e.stopPropagation();
						$(this).removeClass('is-dragging');
					});

					$f.find('.contented').on('drop', function (e) {
						e.preventDefault();
						e.stopPropagation();
						handleUploadFrom(e.originalEvent.dataTransfer.files);
					});

					$f.find('.contented-file-upload').on('click', function(e) {
						e.preventDefault();
						e.stopPropagation();
						handleUploadFrom($(".contented-file-selector")[0].files);
					});

					// Pastebin
					
					$f.find('.contented-paste-upload').on('click', function(e) {
						e.preventDefault();
						e.stopPropagation();
						var blob = new Blob([$(".contented-if-paste textarea").val()], {type : 'text/plain'});
						handleUploadFrom([blob]);
					});

					// Ctrl+V uploads
					
					var pasteHandler = function(e) {
						e.preventDefault();
						e.stopPropagation();
						
						var items = (e.clipboardData || e.originalEvent.clipboardData).items;
						var items_length = items.length;
						var blobs = [];
						var handled = 0;
						var haveHandled = function() {
							handled += 1;
							if (handled == items_length) {
								
								if (blobs.length > 0) {
									handleUploadFrom( blobs );
								} else {
									// alert("Pasted 0 files");
								}
							}
						};
						
						for (var i = 0; i < items.length; ++i) {
							var item = items[i];
							var mimeType = item.type;
							if (item.kind === 'file') {
								blobs.push(item.getAsFile());
								haveHandled();
								
							} else if (item.kind === 'string') {
								item.getAsString(function(s) {
									blobs.push( new Blob([s], {type : mimeType}) );
									haveHandled();
								});
								
							} else {
								// file|string are the only supported types in
								// all browsers at the time of writing
								// Ignore future possibilities
								haveHandled();
							}
						}
					};
					var enablePasteHandler = function() {
						document.addEventListener('paste', pasteHandler);
					};
					var disablePasteHandler = function() {
						document.removeEventListener('paste', pasteHandler);
					};
					
					// Embed in DOM, load default area
					
					$("body").append($f);
					if (!contented.supportsDrop()) {
						setType('file');
					} else {
						setType('drag');
					}
					
					// Drawing board
					
					var setupDrawingBoard = function() {
						
						$("head").append(
							'<link rel="stylesheet" type="text/css" href="' + contented.baseURL + 'drawingboard-0.4.6.min.css">'
						);
						
						var db_id = "contented-drawing-area-" + guid();
						var $db = $("<div>").attr('id', db_id);
						
						DrawingBoard.Control.ContentedUpload = DrawingBoard.Control.extend({
							name: 'upload',

							initialize: function() {
								var $el = this.$el;
								
								$el.append('<button class="contented-drawingboard-upload">Upload</button>');
								$el.on('click', '.contented-drawingboard-upload', $.proxy(function(e) {
									e.preventDefault();
									e.stopPropagation();
									
									$el.prop('disabled', true);
									$el.text('Saving...');
									
									$db.find("canvas")[0].toBlob(function(theBlob) {
										handleUploadFrom([ theBlob ]);
									});
								}, this));
							}
						});
						
						$db.css({
							//'width': $f.find(".contented-content-area").width(),
							'height': $f.find(".contented-content-area").height(),
							'overflow': 'hidden'
						});
						
						$f.find(".contented-drawing-area").append($db);
						var db = new DrawingBoard.Board(db_id, {
							'controls': [
								'Color',
								'Size',
								'DrawingMode',
								'Navigation',
								'ContentedUpload'
							],
							'controlsPosition': 'center',
							'enlargeYourContainer': false,
							'webStorage': false,
							'droppable': false // don't mess with existing drop support
						});
						
					};

					// Close button
					
					var ourClose = function () {
						$f.remove(); // remove from dom
						disablePasteHandler();
						onClose(); // upstream close
					};
					$f.find(".contented-close").click(function () {
						ourClose();
					})

					// Progress bar
					
					var setProgressCaption = function(message) {
						$f.find(".contented-if-progress label").text(message);
					};
					var setProgressPercentage = function(frc) {
						$f.find(".contented-progress-element").css('width', (frc * 100) + "%");
					};

					// Common upload handler
					
					var handleUploadFrom = function(files) {

						setProgressCaption("Uploading, please wait...");
						setProgressPercentage(0);
						setType("progress");

						$f.find(".contented-upload-type-selector").hide();
						$f.find(".contented").removeClass('is-dragging');

						// Ajax uploader
						var ajaxData = new FormData();
						for (var i = 0; i < files.length; ++i) {
							ajaxData.append("f", files[i]);
						}

						// ajax request
						$.ajax({
							url: contented.baseURL + "upload",
							type: "POST",
							data: ajaxData,
							dataType: 'json', // response type
							cache: false,
							contentType: false,
							processData: false,
							xhr: function() {
								var xhr = $.ajaxSettings.xhr();
								xhr.upload.addEventListener(
									'progress',
									function(ev) {
										if (ev.lengthComputable) {
											setProgressCaption("Uploading (" + formatBytes(ev.loaded) + " / " + formatBytes(ev.total) + ")...");
											setProgressPercentage(ev.total == 0 ? 0 : ev.loaded / ev.total);
										}
									},
									false
								);
								return xhr;
							},
							complete: function () {
								setProgressPercentage(1);
							},
							success: function (data) {
								setProgressCaption("Upload completed successfully.");
								onUploaded(data);
								ourClose();
							},
							error: function () {
								setProgressCaption("Upload failed!");
							}
						});

					}
					
					// .

				});

			});

		}
		
		// Update fields in global variable
		contented.init = initArea;
		contented.loaded = true;
		
		// Call initArea for all pre-initialised elements
		for (var i = 0; i < contented.__preInit.length; ++i) {
			initArea(contented.__preInit[i][0], contented.__preInit[i][1], contented.__preInit[i][2]);
		}
	};
		
	// Load scripts
	var needScripts = [];
	if (typeof jQuery === "undefined") {
		needScripts.push(contented.baseURL + "jquery-1.12.4.min.js");
	}
	if (typeof DrawingBoard === "undefined") {
		needScripts.push(contented.baseURL + "drawingboard-0.4.6.min.js");
	}
	
	loadScripts(needScripts, afterScriptsLoaded);
	
})()
