<head>
	<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600&display=swap" rel="stylesheet">
	<link rel="stylesheet" href="https://pro.fontawesome.com/releases/v5.10.0/css/all.css" integrity="sha384-AYmEC3Yw5cVb3ZcuHtOA93w35dYTsvhLPVnYs9eStHfGJvOvKxVfELGroGkvsg+p" crossorigin="anonymous"/>
</head>

<body>
	<form id="inputForm">
		<div class="header">
			<div class="header__grid">
				<img class="header__logo" src="https://uploads-ssl.webflow.com/5f6bc60e665f54545a1e52a5/5f80933ccbecc0e990f4411b_roboflow_inference.png" alt="Roboflow Inference">
				<div>
					<label class="header__label" for="model">Model Name</label>
					<input class="input" type="text" id="model" />
				</div>
				<div>
					<label class="header__label" for="access_token">Access Token</label>
					<input class="input" type="text" id="access_token" />
				</div>
			</div>
		</div>

		<div class="content">
			<div class="content__grid">
				<div class="col-12-s6-m4" id="method">
					<label class="input__label">Upload Method</label>
					<div>
						<button data-value="upload" id="computerButton" class="bttn left fill active">Upload</button>
						<button data-value="url" id="urlButton" class="bttn right fill">URL</button>
					</div>
				</div>

				<div class="col-12-m8" id="fileSelectionContainer">
					<label class="input__label" for="file">Select File</label>
					<div class="flex">
						<input class="input input--left flex-1" type="text" id="fileName" disabled />
						<button id="fileMock" class="bttn right active">Browse</button>
					</div>
					<input style="display: none;" type="file" id="file" />
				</div>

				<div class="col-12-m8" id="urlContainer">
					<label class="input__label" for="file">Enter Image URL</label>
					<div class="flex">
						<input type="text" id="url" placeholder="https://path.to/your.jpg" class="input"/><br>
					</div>
				</div>

				<div class="col-12-m6">
					<label class="input__label" for="classes">Filter Classes</label>
					<input type="text" id="classes" placeholder="Enter class names" class="input"/><br>
					<span class="text--small">Separate names with commas</span>
				</div>

				<div class="col-6-m3 relative">
					<label class="input__label" for="confidence">Min Confidence</label>
					<div>
						<i class="fas fa-crown"></i>
						<span class="icon">%</span>
						<input type="number" id="confidence" value="50" max="100" accuracy="2" min="0" class="input input__icon"/></div>
					</div>
				<div class="col-6-m3 relative">
					<label class="input__label" for="overlap">Max Overlap</label>
					<div>
						<i class="fas fa-object-ungroup"></i>
						<span class="icon">%</span>
						<input type="number" id="overlap" value="50" max="100" accuracy="2" min="0" class="input input__icon"/></div>
				</div>
				<div class="col-6-m3" id="format">
					<label class="input__label">Inference Result</label>
					<div>
						<button id="imageButton" data-value="image" class="bttn left fill active">Image</button>
						<button id="jsonButton" data-value="json" class="bttn right fill">JSON</button>
					</div>
				</div>
				<div class="col-12 content__grid" id="imageOptions">
					<div class="col-12-s6-m4" id="labels">
						<label class="input__label">Labels</label>
						<div>
							<button class="bttn left active">Off</button>
							<button data-value="on" class="bttn right">On</button>
						</div>
					</div>
					<div class="col-12-s6-m4" id="stroke">
						<label class="input__label">Stroke Width</label>
						<div>
							<button data-value="1" class="bttn left active">1px</button>
							<button data-value="2" class="bttn">2px</button>
							<button data-value="5" class="bttn">5px</button>
							<button data-value="10" class="bttn right">10px</button>
						</div>
					</div>
				</div>
				<div class="col-12">
					<button type="submit" value="Run Inference" class="bttn__primary">Run Inference</button>
				</div>
			</div>
			<div class="result" id="resultContainer">
				<div class="divider"></div>
				<div class="result__header">
					<h3 class="headline">Result</h3>
					<a href="#">Copy Code</a>
				</div>
				<pre id="output" class="codeblock"/> here is your json </pre>
			</div>
		</div>
	</form>
</body>
body {
  	font-family: 'Inter', sans-serif;
  	color: #666666;
	background-color: #f7fafc;
	font-size: 16px;
	padding-bottom: 5rem;
}

.headline {
	font-size: 1.25rem;
	font-weight: 600;
}

.text--small {
	font-size: 0.875rem;
}

a {
	color: #606FC7;
	font-weight: 600;
}

a:hover {
	color: #434190;
}

i {
	position: absolute;
	padding: 0.75rem;
	color: #606FC7;
}

span.icon {
	position: absolute;
	padding: 0.5rem;
	right: 0;
}

.header {
	background-color: white;
	padding: 1rem;
	padding-bottom: 2.5rem;
}

.header__grid {
	display: grid;
	grid-template-columns: repeat(1, minmax(0, 1fr));
	grid-template-rows: repeat(3, minmax(0, 1fr));
	gap: 1.5rem;
	max-width: 56rem;
}

.header__logo {
	height: 4rem;
}

.header__label {
	text-transform: uppercase;
	display: block;
	margin-bottom: 0.5rem;
	font-size: 0.875rem;
	font-weight: 600;
	color: #718096;
}

.content {
	padding: 1rem;
	width: 100%;
}

.content__grid {
	display: grid;
	grid-template-columns: repeat(12, minmax(0, 1fr));
	grid-template-rows: repeat(3, minmax(0, 1fr));
	max-width: 56rem;
	column-gap: 1rem;
	row-gap: 2.5rem;
	padding-top: 1rem;
	padding-bottom: 1rem;
}

.flex {
	display: flex;
}

.flex-1 {
	flex: 1 1 0%;
}

.relative {
	position: relative;
}

.col-6-m3 {
	grid-column: span 6 / span 6;
}

.col-12-s6-m4, .col-12-m6, .col-12-m8, .col-12 {
	grid-column: span 12 / span 12;
}

.result {
	max-width: 56rem;
}

.result__header {
	display: flex;
	justify-content: space-between;
	margin-bottom: 1rem;
}

.divider {
	border-width: 1px;
	border-color: #cbd5e0;
	margin-top: 2.5rem;
	margin-bottom: 2.5rem;
	height: 0;
}

input:disabled {
	background-color: white;
}

.input {
	border-width: 1px;
	border-color: #cbd5e0;
	border-radius: 0.25rem;
	height: 2.5rem;
	width: 100%;
	padding-left: 0.5rem;
	padding-right: 0.5rem;
}

.input--left {
	border-top-right-radius: 0;
	border-bottom-right-radius: 0;
	margin-right: -1rem;
}

.input__icon {
	padding-left: 2.5rem;
	padding-right: 2.5rem;
}

.input__label {
	margin-bottom: 0.5rem;
	display: block;
}

.bttn {
	padding-top: 0.5rem;
	padding-bottom: 0.5rem;
	padding-left: 0.75rem;
	padding-right: 0.75rem;
	background-color: white;
	border-width: 1px;
	border-color: #cbd5e0;
	margin-right: -0.5rem;
	height: 2.5rem;
}

.bttn.fill {
	width: 50%;
}

.bttn:focus {
	outline: 1px dotted;
}

.bttn:hover {
	background-color: #edf2f7;
}

.left {
	border-top-left-radius: 0.25rem;
	border-bottom-left-radius: 0.25rem;
}

.right {
	border-top-right-radius: 0.25rem;
	border-bottom-right-radius: 0.25rem;
	margin-right: 0;
}

.bttn.active {
	background-color: #606FC7;
	color: white;
	border-width: 1px;
	border-color: #606FC7;
}

.bttn__primary {
	background-color: #606FC7;
	color: white;
	border-width: 1px;
	border-color: #606FC7;
	border-radius: 0.25rem;
	font-size: 1.125rem;
	padding-left: 1.25rem;
	padding-right: 1.25rem;
	padding-top: 0.75rem;
	padding-bottom: 0.75rem;
}

.bttn.active:hover, .bttn__primary:hover {
	background-color: #4c51bf;
}

.codeblock {
	border-width: 1px;
	border-color: #cbd5e0
	border-radius: 0.25rem;
	display: block;
	padding: 0.75rem;
	background-color: white;
}

#urlContainer {
	display: none;
}

/* small breakpoint */
@media (min-width: 640px) {
	.header {
		padding: 2.5rem;
	}
	.header__grid {
		grid-template-columns: repeat(2, minmax(0, 1fr));
		grid-template-rows: repeat(2, minmax(0, 1fr));
	}
	.header__logo {
		grid-column: span 2 / span 2;
	}
	.content {
		padding: 2.5rem;
	}
	.content__grid {
		column-gap: 1rem;
		row-gap: 2.5rem;
	}
	.col-12-s6-m4 {
		grid-column: span 6 / span 6;
	}
}

/* medium breakpoint */
@media (min-width: 768px) {
	.header__grid {
		grid-template-columns: repeat(3, minmax(0, 1fr));
		grid-template-rows: repeat(1, minmax(0, 1fr));
	}
	.header__logo {
		grid-column: span 1 / span 1;
	}
	.col-6-m3 {
		grid-column: span 3 / span 3;
	}
	.col-12-s6-m4 {
		grid-column: span 4 / span 4;
	}
	.col-12-m6 {
		grid-column: span 6 / span 6;
	}
	.col-12-m8 {
		grid-column: span 8 / span 8;
	}
	.bttn {
		padding-left: 1rem;
		padding-right: 1rem;
	}
}

#resultContainer {
	display: none;
}
$(function() {
	retrieveDefaultValuesFromLocalStorage();

	setupButtonListeners();
});

var infer = function() {
	$('#output').html("Inferring...");
	$("#resultContainer").show();
	$('html').scrollTop(100000);

	getSettingsFromForm(function(settings) {
		$.ajax(settings).then(function(response) {
			if(settings.format == "json") {
				var pretty = $('<pre>');
				var formatted = JSON.stringify(response, null, 4)

				pretty.html(formatted);
				$('#output').html("").append(pretty);
				$('html').scrollTop(100000);
			} else {
				var arrayBufferView = new Uint8Array(response);
				var blob = new Blob([arrayBufferView], {
					'type': 'image\/jpeg'
				});
				var base64image = window.URL.createObjectURL(blob);

				var img = $('<img/>');
				img.get(0).onload = function() {
					$('html').scrollTop(100000);
				};
				img.attr('src', base64image);
				$('#output').html("").append(img);
			}
		});
	});
};

var retrieveDefaultValuesFromLocalStorage = function() {
	try {
		var access_token = localStorage.getItem("rf.access_token");
		var model = localStorage.getItem("rf.model");
		var format = localStorage.getItem("rf.format");

		if (access_token) $('#access_token').val(access_token);
		if (model) $('#model').val(model);
		if (format) $('#format').val(format);
	} catch (e) {
		// localStorage disabled
	}

	$('#model').change(function() {
		localStorage.setItem('rf.model', $(this).val());
	});

	$('#access_token').change(function() {
		localStorage.setItem('rf.access_token', $(this).val());
	});

	$('#format').change(function() {
		localStorage.setItem('rf.format', $(this).val());
	});
};

var setupButtonListeners = function() {
	// run inference when the form is submitted
	$('#inputForm').submit(function() {
		infer();
		return false;
	});

	// make the buttons blue when clicked
	// and show the proper "Select file" or "Enter url" state
	$('.bttn').click(function() {
		$(this).parent().find('.bttn').removeClass('active');
		$(this).addClass('active');

		if($('#computerButton').hasClass('active')) {
			$('#fileSelectionContainer').show();
			$('#urlContainer').hide();
		} else {
			$('#fileSelectionContainer').hide();
			$('#urlContainer').show();
		}

		if($('#jsonButton').hasClass('active')) {
			$('#imageOptions').hide();
		} else {
			$('#imageOptions').show();
		}

		return false;
	});

	// wire styled button to hidden file input
	$('#fileMock').click(function() {
		$('#file').click();
	});

	// grab the filename when a file is selected
	$("#file").change(function() {
		var path = $(this).val().replace(/\\/g, "/");
		var parts = path.split("/");
		var filename = parts.pop();
		$('#fileName').val(filename);
	});
};

var getSettingsFromForm = function(cb) {
	var settings = {
		method: "POST",
	};

	var parts = [
		"https://infer.roboflow.com/",
		$('#model').val(),
		"?access_token=" + $('#access_token').val()
	];

	var classes = $('#classes').val();
	if(classes) parts.push("&classes=" + classes);

	var confidence = $('#confidence').val()/100;
	if(confidence) parts.push("&confidence=" + confidence);

	var overlap = $('#overlap').val()/100;
	if(overlap) parts.push("&overlap=" + overlap);

	var format = $('#format .active').attr('data-value');
	parts.push("&format=" + format);
	settings.format = format;

	if(format == "image") {
		var labels = $('#labels .active').attr('data-value');
		if(labels) parts.push("&labels=on");

		var stroke = $('#stroke .active').attr('data-value');
		if(stroke) parts.push("&stroke=" + stroke);

		settings.xhr = function() {
			var override = new XMLHttpRequest();
			override.responseType = 'arraybuffer';
			return override;
		}
	}

	var method = $('#method .active').attr('data-value');
	if(method == "upload") {
		var file = $('#file').get(0).files && $('#file').get(0).files.item(0);
		if(!file) return alert("Please select a file.");

		getBase64fromFile(file).then(function(base64image) {
			settings.url = parts.join("");
			settings.data = base64image;

			console.log(settings);
			cb(settings);
		});
	} else {
		var url = $('#url').val();
		if(!url) return alert("Please enter an image URL");

		parts.push("&image=" + encodeURIComponent(url));

		settings.url = parts.join("");
		console.log(settings);
		cb(settings);
	}
};

var getBase64fromFile = function(file) {
	return new Promise(function(resolve, reject) {
		var reader = new FileReader();
		reader.readAsDataURL(file);
		reader.onload = function() {
			resolve(reader.result);
		};
		reader.onerror = function(error) {
			reject(error);
		};
	});
};