
$.each(['me','us','we','them'],function(i,v) {
	window[v] = {
		'aud': {},
		'in': {},
		'rec': {},
		'src': {},
		'analyzer': {},
		'osc': {},
		'buffer': {},
		'data': {},
		'ctx': {},
		'mix': {},
		'pc': {},
		'out': {},
		'timestamp': {},
		'id': {},
		'type': {},
		'uuid': {},
		'app': {}
	};
});


async function jpCanvas(app) {
	var whiteboard = document.getElementById('whiteboard');
	var apper = $('.wind')[$('.wind').length - 1];
	app = ($(apper).attr('app') || $('#search').val());
	var wb = $(whiteboard);
	if (wb.attr('status') == 'recording') {
		wb.attr('status', 'stopped');
		jpStop(app,'marker');
	}
	else {
		wb.attr('status', 'recording');
		var timestamp = Date.now();
		var marker = markerInfoGrabber();
		var formData = new FormData();
		var type = 'video';
		formData.delete('timestamp');
		formData.append('timestamp', timestamp);

		formData.delete('app');
		formData.append('app', app);
		we['in'][app] = whiteboard.captureStream(marker['flipbook_interval']);
		we['rec'][app] = new MediaRecorder(we['in'][app]);
		we['timestamp'][app] = Date.now();
		console.log(we);
		we['rec'][app].start();
		$('#marker_record').attr('src', '/images/make believe/stop.png');
		$('#marker_pause').attr('app', app);
		$('#marker_pause').show();
		we['rec'][app].ondataavailable = (event) => { 
			var data = event.data;
			data.type = 'track';
			var ext = 'webm';
			if (type == 'audio') {
				ext = 'weba';
			}
			var formData = new FormData();
			var duration = (Date.now() - we['timestamp'][app]) * -1;
			formData.append('app', app);
			formData.append('duration', duration);
			formData.append('timestamp', timestamp);
			formData.append('type', type);
			formData.append('blob', data, app + '.' + ext);

			$('#marker_record').attr('src', '/images/make believe/record.png');
			$('#marker_pause').hide();
			$('#marker_pause').removeAttr('app');
			$.ajax({
				url: '/manager/upload_file',
				type: 'POST',
				data: formData,
				success: function (response) {
					continent_record({'uuid':response['uuid'], 'app':response['app'],'timestamp':response['timestamp']});
				},
				cache: false,
				contentType: false,
				processData: false
			});
		};
	}
};

async function jpStart(app,pref,uuid) {
	var timestamp = Date.now();
	var type = 'video';
	var id = app + '_cam';
	console.log(id + ' ' + type + ' ' + uuid);
	me['id'][app] = id;
	me['type'][app] = type;
	me['uuid'][app] = uuid;
	me['app'][app] = app;
	if (!me[app]) {
		var constraints = await constraintMaker(pref);
		console.log(constraints);
		if (pref == 'audio') {
			constraints['video'] = false;
			id = app + '_snd';
		}
		if (app) {
			try {
				me['id'][app] = id;
				me['type'][app] = type;
				me['uuid'][app] = uuid;
				if (!me['in'][app]) {
					me['in'][app] = await navigator.mediaDevices.getUserMedia(constraints);

				}
				if (!me['rec'][app] || me['rec'][app].state == "inactive" ) {
					me['rec'][app] = new MediaRecorder(me['in'][app]);
					me['timestamp'][app] = Date.now();
					me['rec'][app].start();
				}
				me['rec'][app].ondataavailable = (event) => { 
					
					var data = event.data;
					data.type = 'track';
					var json = JSON.stringify(data);
					var formData = new FormData();
					var duration = (Date.now() - me['timestamp'][app]) * -1;
					formData.append('app', app);
					formData.append('duration', duration);
					formData.append('timestamp', me['timestamp'][app]);
					formData.append('type', type);
					formData.append('blob', data, app + '.webm');
					formData.append('uuid', uuid);
					$.ajax({
							url: '/manager/upload_file',
							type: 'POST',
							data: formData,
							success: function (response) {
								continent_record({'uuid':response['uuid'], 'app':response['app'],'timestamp':response['timestamp']});
							},
							cache: false,
							contentType: false,
							processData: false
					});

				};

				me['rec'][app].onstop = function(event) {
					console.log('Recorder stopped for ' + app);
					if (pref == 'video') {
						$('#' + id).remove();
						$('.appointment[app="' + app + '"]').find('.media_out.vid').html('');
					}
					else {
						$('#' + id).hide();
					}
				};
				var app_vid_html = $('#' + app + '_cam').parent().html();
				console.log(app_vid_html);
				if (pref == 'audio') {
					$('#' + id).show();
					me['out'][app] = document.getElementById(id);
					me['out'][app].srcObject = me['rec'][app].stream;
					me['out'][app].muted = true;
				} else {
					var jmiss = JSON.stringify(misses);
					$.ajax({
						url: '/manager/media_window',
						type: 'GET',
						data: { id: id, contents: app_vid_html, timestamp: timestamp, app: app + '_cam', app_name: app, misses: jmiss },
						success: function(response) {

							var vid = $('.appointment[app="' + app + '"]').find('.media_out.vid');
							vid.html(response.html);
							me['out'][app] = document.getElementById(id);
							me['out'][app].srcObject = me['rec'][app].stream;
							me['out'][app].muted = true;

						}
					});
				}

				me['rec'][app].onstart = function(event) {
					console.log('Recorder started for ' + app);
					me['aud'][app] = new Audio;
					me['aud'][app].srcObject = me['in'][app];
					$('#' + id).show();
					jpScope(app);

				};
			}
			catch(error) { console.log('error',error); }
		}
		else {
			if (!me['in'][app]) {
				me['in'][app] = await navigator.mediaDevices.getUserMedia(constraints);
			}
			jpSmooth('', me['in'][app]);
		}

	}
	else {

	}
}

async function constraintMaker(pref) {

	var constraints = { 'audio': false, 'video': false };
	var isVideo = false;
	var isInitialized = false;
	var hasAudio = false;
	var hasVideo = false;
	var av = await navigator.mediaDevices.enumerateDevices();
	console.log(av);
	$.each(av, function(i,v) {
		var mic = localStorage.getItem('audioinput' + v.deviceId );
		var cam = localStorage.getItem('videoinput' + v.deviceId );
		var spkr = localStorage.getItem('audiooutput' + v.deviceId );
		if (v.kind == 'audioinput') {
			console.log(v.deviceId);

			hasAudio = true;
			if (mic == 'on' && v.deviceId) {
				isInitialized = true;
				constraints['audio'] = { deviceId: { exact: v.deviceId } };
				console.log('mic is on');
			}
		}
		else if (v.kind == 'videoinput') {
			hasVideo = true;
			if (cam == 'on' && v.deviceId) {

				isInitialized = true;
				constraints['video'] = { 
					deviceId: { 
						exact: v.deviceId 
					},
					width: { ideal: 1280, max:4000 },
					height: { ideal: 720, max:3000 }
				};
				isVideo = true;
			}
		}
	});


	if (isVideo == false || pref == 'audio') {
		constraints['video'] = false;

	//	say_it('ok no vid');
	}
	if (isInitialized == false) {
	//	say_it('ok no init');
		constraints = { 'video': false, 'audio': true };
		if (hasVideo == true || pref != 'audio') {
			constraints['video'] = true;
		}
		var test = await navigator.mediaDevices.getUserMedia(constraints);
		test.onstart = function(event) {
			test.stop();
		};
	}
	// say_it('the end');

	return constraints;
}

function jpScope(app) {
	var x = 0;
	var canvas = document.getElementById('visualizer_' + app);
	var ctx = canvas.getContext("2d");

	var sliceWidth = canvas.width / me['buffer'][app];

  ctx.clearRect(0, 0, canvas.width, canvas.height);

  me['analyzer'][app].getByteFrequencyData(me['data'][app]);

	for (var i = 0; i < me['buffer'][app]; i++) {
		var v = me['data'][app][i] / 128.0;
		var y = v * (canvas.height / 2);

		if (i === 0) {
			ctx.moveTo(x, y);
		} else {
			ctx.lineTo(x, y);
		}
		x += sliceWidth;
	}
	ctx.stroke();
  //console.log(frequency);
  //requestAnimationFrame(jpScope(app));

}

async function jpScreen(app,uuid) {
	var id = app + '_scr';
	var timestamp = Date.now();
	var type = 'screen';
	me['id'][app] = id;
	me['type'][app] = type;
	me['uuid'][app] = uuid;
	me['app'][app] = app;
	try {
		if (app) {

			if (!us['in'][app]) {
				var options = { 'surfaceSwitching': 'include', 'audio': true, 'video': { 'displaySurface': 'monitor' }};
				us['in'][app] = await navigator.mediaDevices.getDisplayMedia(options);
				console.log(us);
			}
			if (!us['rec'][app] || us['rec']['app'].state =="inactive" ) {
				us['rec'][app] = new MediaRecorder(us['in'][app]);
				us['timestamp'][app] = Date.now();
				us['rec'][app].start();
				$('#' + id).show();

			}

			us['rec'][app].ondataavailable = (event) => { 
				event.data.app = app;
				
				var data = event.data;
				data.type = 'screen';

				var json = JSON.stringify(data);

				var formData = new FormData();
				var duration = data.size;
				var duration = (Date.now() - us['timestamp'][app]) * -1;
				formData.append('app', app);
				formData.append('duration', duration);
				formData.append('timestamp', us['timestamp'][app]);
				formData.append('type', 'screen');
				formData.append('blob', data, app + '.webm');
				formData.append('duration', duration);
				formData.append('uuid', uuid);
				$.ajax({
						url: '/manager/upload_file',
						type: 'POST',
						data: formData,
						success: function (response) {
							continent_record({'uuid':response['uuid'], 'app':response['app'],'timestamp':response['timestamp']});
						},
						cache: false,
						contentType: false,
						processData: false
				});
				us['mix'][app] = data;
			};
			us['rec'][app].onstart = function(event) {
				console.log('Recorder started for ' + app);

			};
			us['rec'][app].onstop = function(event) {
				console.log('Recorder stopped for ' + app);
				$('#' + id).remove();
				$('.appointment[app="' + app + '"]').find('.media_out.scr').html('');
			};
			var app_vid_html = $('#' + app + '_scr').parent().html();
			var jmiss = JSON.stringify(misses);
			$.ajax({
				url: '/manager/media_window',
				type: 'GET',
				data: { id:id, contents: app_vid_html, timestamp: timestamp, app: app + '_scr', app_name: app, misses: jmiss },
				success: function(response) {
					console.log(response);
					if ($('#club_scr').length > 0) {
						us['out'][app] = document.getElementById(id);
						us['out'][app].srcObject = us['rec'][app].stream;

						$('#' + id).css({'width': '100%' });
					}
					else {
						var vid = $('.appointment[app="' + app + '"]').find('.media_out.scr');
						vid.html(response.html);
						us['out'][app] = document.getElementById(id);
						us['out'][app].srcObject = us['rec'][app].stream;
					}

					us['out'][app].muted = true;
				

				}
			});
		}
		else {
			if (!us['in'][app]) {
				var options = { 'surfaceSwitching': 'include', 'audio': true, 'video': { 'displaySurface': 'monitor' }};
				us['in'][app] = await navigator.mediaDevices.getDisplayMedia(options);
			}
			jpSmooth('', us['in'][app]);
		}
	}
	catch (error) { 

	}
}

function jpReport(app) {

	var apps = [];
	var appts = { me: [], us: [], them: [], we: [] };
	$.each(appts, function(s,d) {
		$.each(window[s], function(i,v) {
			var seen = [];
			$.each(v, function(ir,vr) {
				console.log(ir);
				if (app == ir) {
					seen = $.grep(apps, function(irs,vrs) {
						console.log(irs);
						return irs['app'] == ir;
					});
				}
				if (seen == 0) {
					appts[app] = [];
					appts[app].push(s);
					apps.push({ app: window[s]['app'][app], in: window[s]['in'][app], perspective: s, type: window[s]['type'][app], id: window[s]['id'][app], uuid: window[s]['uuid'][app] });
				}
			});
		});
	});
	

	return apps;
}

function jpRestore(app,jpR) {
	var apps = [];
	var appts = { me: [], us: [], them: [], we: [] };
	console.log(jpR);
	$.each(jpR, function(s,d) {
		console.log(s);
		console.log(d);
		if (d['app'] == app && d['in']) {
			console.log(v);
			if (d['app'] == app) {
				jpStart(d['app'],d['type'], d['uuid']);
			}
			else if ( s == 'us' ) {
				jpScreen(d['app'],d['uuid']);
			}
		}
	});
}



function jpStop(app,imperative,uuid) {

	console.log('jpStop ' + app);
	if ((imperative == 'video' || imperative == 'audio') || imperative == undefined) {
		try {
			me['in'][app].getTracks().forEach(function(track) {
				console.log(track);
				track.stop();
			});
			me['in'][app] = undefined;
			me['rec'][app].stop();
	//		me['rec'][app] = undefined;
			me['out'][app] = undefined;
		}
		catch  {
			$.each(me['in'],function(i,v) {
				console.log(i);
				try {
					me['rec'][i].getTracks().forEach(function(track) {
						console.log(track);
						track.stop();
					});
				}
				catch {
					me['in'][app] = undefined;
					me['rec'][app] = undefined;
					me['out'][app] = undefined;
				}
			});

		}
	}
	if (imperative == 'screen' || imperative == undefined) {
		try {
			us['in'][app].getTracks().forEach(function(track) {
				console.log(track);
				track.stop();
			});
			us['in'][app] = undefined;
			us['rec'][app].stop();
			us['rec'][app] = undefined;
			us['out'][app] = undefined;
		}
		catch  {
			$.each(us['in'],function(i,v) {
				console.log(i);
				try {
					us['rec'][i].getTracks().forEach(function(track) {
						console.log(track);
						track.stop();
					});
				}
				catch {
					us['in'][app] = undefined;
					us['rec'][app] = undefined;
					us['out'][app] = undefined;
				}
			});

		}
	}
	if (imperative == 'marker' || imperative == undefined) {
		try {
			we['in'][app].getTracks().forEach(function(track) {
				console.log(track);
				track.stop();
			});
			we['in'][app] = undefined;
			we['rec'][app].stop();
			we['rec'][app] = undefined;
			we['out'][app] = undefined;
		}
		catch  {
			$.each(we['in'],function(i,v) {
				console.log(i);
				try {
					we['rec'][i].getTracks().forEach(function(track) {
						console.log(track);
						track.stop();
					});
				}
				catch {
					we['in'][app] = undefined;
					we['rec'][app] = undefined;
					we['out'][app] = undefined;
				}
			});

		}
	}
}

function inputClose(app) {
	var timestamp = Date.now();
	console.log(app + ' is getting shut down');
	me['in'][app] = null;
	me['out'][app] = null;

}

function jpAppointmentWriter() {

};

function jpWatcher() {
	var returner = {};

	$.each(me['out'], function(i,v) {

		var id = $(v).attr('id');
		var video = document.getElementById(id);
		if ($(video).is('video')) {
			var canvas = document.createElement('canvas');
			var ratio = video.videoWidth / video.videoHeight;
			canvas.width = 640 || 0;
			canvas.height = ratio * canvas.width || 0;
			canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);

			var image = canvas.toDataURL('image/png');
			returner[i] = { 'image': image, 'ratio': ratio, 'width': canvas.width, 'height': canvas.height };
		}
	});
	$.each(us['out'], function(i,v) {
		var id = $(v).attr('id');
		var video = document.getElementById(id);
		if ($(video).is('video')) {
			var canvas = document.createElement('canvas');

			var ratio = video.videoWidth / video.videoHeight;
			canvas.width = 640 || 0;
			canvas.height = ratio * canvas.width || 0;
			canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);

			var image = canvas.toDataURL('image/png');
			returner[i] = { 'image': image, 'ratio': ratio, 'width': canvas.width, 'height': canvas.height };
		}
	});
	if ($('#whiteboard').is(':visible')) {
		var canvas = document.getElementById('whiteboard');
		var vcanvas = document.createElement('canvas');
		var ratio = canvas.width / canvas.height;
		vcanvas.width = 640 || 0;
		vcanvas.height = ratio * vcanvas.width;
		vcanvas.getContext('2d').drawImage(canvas, 0, 0, vcanvas.width, vcanvas.height);
		var image = vcanvas.toDataURL('image/png');
		returner['we'] = { 'image': image, 'ratio': ratio, 'width': canvas.width, 'height': canvas.height };
	}
	return returner;
}


let localStream;
let pc1;
let pc2;
var jpSmoothInterval;

function jpSmooth(app,sourceStream) {
    pc1 = new RTCPeerConnection(servers); // eslint-disable-line new-cap
    console.log('Created local peer connection object pc1');
    pc1.onicecandidate = e => onIceCandidate(pc1, e);
    pc2 = new RTCPeerConnection(servers); // eslint-disable-line new-cap
    console.log('Created remote peer connection object pc2');
    pc2.onicecandidate = e => onIceCandidate(pc2, e);
    pc2.ontrack = gotRemoteStream;
    sourceStream.getTracks().forEach(track => pc1.addTrack(track, sourceStream));
    pc1.createOffer().then(gotDescription1).catch(error => console.log(`createOffer failed: ${error}`));
}

function jpViewAdjuster(streams) {
	var container = $('#mailbox_video_container');
	var videos = container.find('video');
	$.each(streams, function(i,v) {
		console.log(streams[i]);
		var id = streams[i].id;
		if ($('#' + id).length == 0) {
			container.append('<video class="jpSmoothStream" id="' + id + '" mute autoplay></video>');
			var audioElement = document.getElementById(id);
			audioElement.muted = true;
			them['in'][id] = streams[i];
		  audioElement.srcObject = them['in'][id];
			them['pc'][id] = pc2;
			videos = container.find('video');
			var width = container.width();
			var height = container.height();
			width = numeral(container.width() / videos.length).value();
			$('#' + id ).width(width);
		}
	});
	clearInterval(jpSmoothInterval);
	jpSmoothInterval = setInterval(function() {
		$('.jpSmoothStream').each(function(ir,vr) {
			var id = $(vr).attr('id');
			var v = document.getElementById(id);
			if (them['stats'][id] == v.currentTime) {
				$(vr).remove();
				them['pc'][id].close();
			}
			them['stats'][id] = v.currentTime
		});
	},1000);
}

function gotRemoteStream(e) {
	jpViewAdjuster(e.streams);
}

function gotDescription1(desc) {
  console.log(`Offer from pc1\n${desc.sdp}`);

  pc1.setLocalDescription(desc);
  pc2.setRemoteDescription(desc);
  pc2.createAnswer()
      .then(gotDescription2)
      .catch(error => logError(`createAnswer failed: ${error}`));
}

function gotDescription2(desc) {
  console.log(`Answer from pc2\n${desc.sdp}`);
  pc2.setLocalDescription(desc);
  pc1.setRemoteDescription(desc);
}

function getOtherPc(pc) {
  return (pc === pc1) ? pc2 : pc1;
}

function getName(pc) {
  return (pc === pc1) ? 'pc1' : 'pc2';
}

function onIceCandidate(pc, event) {
  getOtherPc(pc)
      .addIceCandidate(event.candidate)
      .then(() => onAddIceCandidateSuccess(pc), err => onAddIceCandidateError(pc, err));
  console.log(`${getName(pc)} ICE candidate:\n${event.candidate ? event.candidate.candidate : '(null)'}`);
}

function onAddIceCandidateSuccess() {
  console.log('AddIceCandidate success.');
}

function onAddIceCandidateError(error) {
  logError(`Failed to add Ice Candidate: ${error.toString()}`);
}