var isConnecting = new Store.Value.Boolean(false);
Screen.Conference = function() {

	var RTC = function(parent, canvas, devname, id, remoteParent) {
		let callApp;
		console.log("init callapp");
		if (parent == null) {
			console.log("parent was null");
			parent = document.body;
		}
		awrtc.SLog.SetLogLevel(awrtc.SLogLevel.Info);
		callApp = new apps.VideoInputApp();
		callApp.mUiRemoteVideoParent = remoteParent;



		const media = new awrtc.Media();
		awrtc.Media.SharedInstance.VideoInput.AddCanvasDevice(canvas, devname, canvas.width , canvas.height , 30);

		setInterval(() => {
			awrtc.Media.SharedInstance.VideoInput.UpdateFrame(devname);
		}, 50);
		//apps.VideoInputApp.sVideoDevice = devname;
		callApp.sVideoDevice = devname;
		callApp.setupUi(parent);
		this.callApp = callApp;
		callApp.___id = id;
		this.id = id;
	}

	var resultProcessor = function(canvasElement) {
		window.canvasElement = canvasElement;
		let segmentations = [false,false,false];
		let sPointer = 0;
		var w = window.videoSize.w, h = window.videoSize.h;

		var tmpCanvas = D.h('canvas', {width: w, height: h}),
			tmpCtx = tmpCanvas.getContext('2d'),

			composedMaskCanvas = D.h('canvas', {width: w, height: h}),
			composedMaskCtx = composedMaskCanvas.getContext('2d'),
			composedData = composedMaskCtx.getImageData(0,0,w,h),
			composedDataData = composedData.data;

		const canvasCtx = window.canvasCtx = canvasElement.getContext('2d');

		return function(results){
			var max = Math.max;

			var image = results.segmentationMask;

			tmpCtx.clearRect(0,0,w,h);
			tmpCtx.drawImage(image,0,0,image.width,image.height,0,0,w,h);
			segmentations = [segmentations[1], segmentations[2], tmpCtx.getImageData(0,0,w,h).data];

			sPointer++;
			var tresh = 64;//window.tresh || 50;
			var pos = canvasElement.position;
			var from = w*pos[0]/100,
				to = w*pos[1]/100;
			var seg1 = segmentations[ 1 ],
					seg2 = segmentations[ 2 ],
				  seg0 = segmentations[ 0 ];
			if(sPointer>3){
				var pointer;
				for(var j = 0; j < h; j++){
					pointer = j*w*4+3;

					for( var i = 0; i < w; i++ ){

						//if( ){
						composedDataData[ pointer ] =
							composedDataData[ pointer - 2 ] =
								i<from || i > to ||
								seg2[ pointer ] + (seg1[ pointer ]>>1) + (seg0[ pointer ]>>2) < tresh ? 255 : 0;
						pointer += 4;
						//}
					}
				}
				composedMaskCtx.putImageData(composedData,0,0);

			}
			canvasCtx.drawImage(
				results.image, 0, 0, canvasElement.width, canvasElement.height );

			canvasCtx.drawImage( composedMaskCanvas/*results.segmentationMask*/, 0, 0,
				canvasElement.width, canvasElement.height );
		};
	}

	var single = new Store.Value.Boolean(true);

	var linkHook = _=>
		store.sub('conference_id', function(val) {
			_(document.location.origin+document.location.pathname+'#/'+val)
		}),
		link = D.h('a', { href: linkHook }, linkHook );

	var streams = {};

	var cameraID = 0;
	var remoteVideoEl = D.div({cls: 'remote-video'});

	var instanciating = 0;
	store.sub(['appLoaded', 'callScreenCamerasTune', 'cameraID'], function(loaded, tune) {
		if(!loaded)
			return
		if(!tune)
			return;
		if(instanciating<2){
			instanciating++;
			setTimeout(function() {
				usersBlock.appendChild( generateCameraUI() )
			}, 300);
		}
	});

	var generateCameraUI = function() {
		var currentCameraID = cameraID;
		cameraID++;
		store.set('cameraID', cameraID);
		var camTypes = store.get('webcamtypes');
		store.set('webcam'+currentCameraID, camTypes[currentCameraID % camTypes.length].value);

		var userRoles = store.get('userRoles');
		store.set('userRole'+currentCameraID, userRoles[currentCameraID % userRoles.length].value);

		var guestPositions = store.get('guestPositions');
		store.set('guestPosition'+currentCameraID, false);
		var cameras = ['Left', 'Center', 'Right']
		var cameraCanvas, canvasResizerEl,
			dom = D.div( { cls: 'block camera-block', style: { marginBottom: '80px' } },
				D.div( { cls: 'header' }, cameras[currentCameraID%3] + ' Camera' ),
				canvasResizerEl = CanvasResizer(
					cameraCanvas = D.h( 'canvas', {
						cls: "output_canvas",
						width: window.videoSize.w+"px",
						height: window.videoSize.h+"px",
						style: {
							/*display: 'none',*/
							width: '320px'
						}
					} )
				),

				/*Select( {
					values: 'userRoles',
					bind: store.bind( 'userRole' ),
					label: 'Your role',
					disabled: isConnected
				} ),*/
				Select( {
					values: 'videoinput',
					bind: store.bind( 'videoinput' + currentCameraID ),
					label: 'Camera device',
					disabled: isConnected
				} ),
/*				Select( {
					values: 'webcamtypes',
					bind: store.bind( 'webcam' + cameraID ),
					label: 'Camera position',
					filter: store.bind( 'userRole' + cameraID ),
					disabled: isConnected
				} ),*/

			);


		var video1 = D.h('video');
		var cameraCanvasCtx = cameraCanvas.getContext('2d');
/*		var updateVideos = function() {
			console.log(111);
			cameraCanvasCtx.drawImage(video1,0,0);

			requestAnimationFrame(updateVideos);
		};
		requestAnimationFrame(updateVideos);*/

		store.sub(['inputsSetted'], (is) => {
			/*store.set('videoinput1', devices.videoinput[devices.videoinput.length - 1].value);
			store.set('videoinput2', devices.videoinput[Math.max(0,devices.videoinput.length - 2)].value);
			store.set('videoinput3', devices.videoinput[Math.max(0,devices.videoinput.length - 3)].value);
*/

			if(!is)
				return;
			var count = devices.videoinput.length;
			store.set('videoinput'+currentCameraID, devices.videoinput[
				(count-1-currentCameraID +count*currentCameraID)%count
			].value);
		});
		store.sub(['inputsSetted', 'videoinput'+currentCameraID], async (is, input) => {
			if(!is)
				return;

			if(input){
				try{
					if(input in streams){
						stream = streams[input];
					}else{
						var stream = await navigator.mediaDevices.getUserMedia( {
							video: {
								deviceId: { exact: input },
								width: window.videoSize.w
							}
						} );

					}
					streams[input] = stream;
					var video = video1;
					video.srcObject = stream;
					video.play();
					canvasResizerEl.style.display = 'block';

				}catch(e){
					video1.srcObject = null;
					video1.pause();
					canvasResizerEl.style.display = 'none';
					console.error(e)
				}
			}
			for(var streamID in streams){
				var inUse = false;
				for(var j = 0; j <= cameraID; j++){
					if(store.get('videoinput'+j) === streamID){
						inUse = true;
						break;
					}
				}
				if(!inUse){
					var stream = streams[streamID];
					stream.getTracks().forEach(function(track) {
						track.stop();
					});
					delete streams[streamID];
				}
			}


		});
		window.instances || (window.instances = []);
		var RTCinstance;

		store.sub(['appLoaded'], function(loaded, callScreenCamerasTune) {
			if(!loaded)// || !callScreenCamerasTune)
				return;
			RTCinstance = new RTC(
				currentCameraID ? null : document.querySelector("#videoinputapp1"),
				cameraCanvas, 'canvas'+currentCameraID,
				currentCameraID,
				currentCameraID ? null : remoteVideoEl
			);
			window.instances.push(RTCinstance);
			RTCinstance.mUiRemoteVideoParent = currentCameraID ? null : remoteVideoEl;

			var slots = {
				OfficeUser: {1: 0, 2: 1},
				OfficeUserLeft: {1: 0, 2: 1},
				RemoteUser: {1: 2, 2: 3},
			};

			RTCinstance.callApp.connectMessage = ()=>{
				var slot = slots[store.get( 'userRole' )][store.get( 'guestPosition' )];

				return {
					"roomSlot": slot,
					"webCam": cameras[currentCameraID%3]
				}
			};


			var selfieSegmentation = new SelfieSegmentation( {
				locateFile: ( file ) => {
					return `https://cdn.jsdelivr.net/npm/@mediapipe/selfie_segmentation/${file}`;
				}
			} );
			selfieSegmentation.setOptions( {
				modelSelection: 1,
			} );

			var resultProcessorFn = resultProcessor(cameraCanvas)

			selfieSegmentation.onResults( function(){
				resultProcessorFn.apply( this, arguments )
			} );

			var segmentation = async function() {

				if( store.get( 'callScreenCamerasTune' ) ){
						if( video1.videoWidth > 10 && store.get( 'videoinput' + currentCameraID ) ){
							try{
								await selfieSegmentation.send( { image: video1 } );
							}catch( e ){

							}
						}
					}

				requestAnimationFrame(segmentation);

			};
			console.log(video1, canvasResizerEl, canvasElement, currentCameraID)
			requestAnimationFrame(segmentation);
		});
		return dom;
	}
	var usersBlock, tooMuchUsers = new Store.Value.Boolean(false);
	var dom = D.div({cls: 'page-content'},
    D.div({cls: 'top-bar'},
      D.h('img', {src: 'amazon-logo.svg'}),
      D.div({cls: 'buttons hidden'},
        D.h('button', {cls: ['button secondary', {hidden: Store.NOT(isConnected)}], onclick: ()=>store.set('connection', false)}, 'End session'),
        D.h('button', {cls: ['button primary', {hidden: isConnected}], onclick: ()=>store.set('connection', true)}, 'Ready to connect')
      )
    ),
		content = D.div({cls: 'content content-fullpage'},

			D.div({cls: 'block'},
				D.div({cls: 'description gray'}, 'You are the host of this session'),
				D.div({cls: 'description'}, 'Session ID: ', store.val('conference_id')),
				D.div({cls: 'description'}, 'Link to session: ', link),

			),
			Screen.PositionSelect(),

			usersBlock = D.div({cls: ['users-block', {
						hidden: Store.NOT(store.val('callScreenCamerasTune'))
					}]},
				generateCameraUI(),
				/*generateCameraUI(),
				generateCameraUI()*/
			),

			D.div({cls: ['bottom-buttons', {
						hidden: Store.NOT(store.val('callScreenCamerasTune'))
					}]},
				D.div({style: {minWidth:'10px'}},
					D.h('button', {
						cls: ['button primary', {hidden: Store.OR(isConnected, isConnecting)}],
						onclick: ()=>{
							isConnecting.set(true);
							store.set('connection', true)
						}
					}, 'Ready to connect'),

					D.h('button', {
						cls: ['button orange', {hidden: Store.NOT(Store.OR(isConnected, isConnecting))}],
						onclick: function(){
							var _self = this;
							store.set('connection', false);
							_self.style.display = 'none';
							setTimeout(function(  ){
								store.set('connection', true);
								setTimeout(function() {
									_self.style.display = 'block';
								}, 300)

							}, 300);
						}
					}, 'Reconnect')
				),

				D.h('button', {
					cls: ['button orange', {hidden: /*isConnected*/false}],
					onclick: ()=>{
						store.set('connection', false);
						Screen.show( 'Main', true );
					}}, 'Exit to main menu')
			),


			window.addACameraBtn = D.h('button', {cls: ['button primary hidden', {hidden: Store.OR(isConnected, tooMuchUsers)}],
				onclick: ()=> {
					usersBlock.appendChild(generateCameraUI())
					/*if(cameraID > 1)
						tooMuchUsers.set(true);*/
				}
			}, 'Add camera'),


		D.div({cls: 'block hidden'},
				D.div({cls: 'header'}, 'Conference info'),

				LabeledInput({label: 'Session ID', cls: 'callapp_address input', autocomplete: 'off', value: getConferenceID()}, 'conference_id'), // LUCID
			),
			D.div({cls: ['block', {hidden: true}]}, //Store.NOT(isConnected)
				D.div({cls: ['header']}, 'Remote video'),
				remoteVideoEl

			)
		)
	);



	var devices = {audioinput: [], audiooutput: [], videoinput: []};

	function gotDevices(deviceInfos) {
		// Handles being called several times to update labels. Preserve values.


		for (let i = 0; i !== deviceInfos.length; ++i) {
			const deviceInfo = deviceInfos[i];
			const option = {value: deviceInfo.deviceId};
			if(!(deviceInfo.kind in devices)){
				devices[ deviceInfo.kind ] = [];
			}
			devices[deviceInfo.kind].push(option);
			var count = devices[deviceInfo.kind].length;
			if (deviceInfo.kind === 'audioinput') {
				option.text = deviceInfo.label || `microphone ${count}`;
			}  else if (deviceInfo.kind === 'audiooutput') {
				option.text = deviceInfo.label || `speaker ${count}`;
			} else if (deviceInfo.kind === 'videoinput') {
				option.text = deviceInfo.label || `camera ${count}`;
			} else {
				console.log('Some other kind of source/device: ', deviceInfo);
			}
		}

		store.set('videoinput', devices.videoinput);
		store.set('audioinput', devices.audioinput);

		store.set('inputsSetted', true);
		console.log(devices);
		/*const values = selectors.map(select => select.value);
		selectors.forEach(select => {
			while (select.firstChild) {
				select.removeChild(select.firstChild);
			}
		});
		for (let i = 0; i !== deviceInfos.length; ++i) {
			const deviceInfo = deviceInfos[i];
			const option = document.createElement('option');
			option.value = deviceInfo.deviceId;
			if (deviceInfo.kind === 'audioinput') {
				option.text = deviceInfo.label || `microphone ${audioInputSelect.length + 1}`;
				audioInputSelect.appendChild(option);
			} else if (deviceInfo.kind === 'audiooutput') {
				option.text = deviceInfo.label || `speaker ${audioOutputSelect.length + 1}`;
				audioOutputSelect.appendChild(option);
			} else if (deviceInfo.kind === 'videoinput') {
				option.text = deviceInfo.label || `camera ${videoSelect.length + 1}`;
				videoSelect.appendChild(option);
			} else {
				console.log('Some other kind of source/device: ', deviceInfo);
				continue;
			}
		}
		selectors.forEach((select, selectorIndex) => {
			if (Array.prototype.slice.call(select.childNodes).some(n => n.value === values[selectorIndex])) {
				select.value = values[selectorIndex];
			}
		});*/
	}
	var handleError = function(e) {
		console.log('Error', e)
	}







//gotDevices([{"deviceId":"default","kind":"audioinput","label":"Default - Microphone (2- Razer Kiyo) (1532:0e03)","groupId":"c9b2965558c8600ceaa11c06017152dc99f8721fef0585ad9432838b46f8f9f7"},{"deviceId":"communications","kind":"audioinput","label":"Communications - Microphone (2- Razer Kiyo) (1532:0e03)","groupId":"c9b2965558c8600ceaa11c06017152dc99f8721fef0585ad9432838b46f8f9f7"},{"deviceId":"1517d03bc4bc8e08292b02b454b79e3a93f39fa14d7c589c47c80d093093ed1e","kind":"audioinput","label":"Microphone (Steam Streaming Microphone)","groupId":"20a28b389c696bd36556474101f44876ee56f686b3717913354b85fa804c8c7a"},{"deviceId":"b963d76466dcc0490a58d9624e987a3e69d689c2529adf66f39efae8fccd031c","kind":"audioinput","label":"Microphone (Razer Kiyo) (1532:0e03)","groupId":"ea58a01565e810e30b4d7873050388edb9dc43a11007253ecc9dabd4201230fd"},{"deviceId":"3a664d8417e7000b78f8619667da3e38280269edb222a74d1375786e9c8e70d3","kind":"audioinput","label":"Mic in at rear panel (Pink) (Realtek(R) Audio)","groupId":"8e1aab63dd80f414dce561f4e368bb484c065834f3941db045ca722f61d254a4"},{"deviceId":"46ac5b427bdd38a095664fe7e817a5e7fb7cd2a7077558e72112ade79f27f3a5","kind":"audioinput","label":"Microphone (2- Razer Kiyo) (1532:0e03)","groupId":"c9b2965558c8600ceaa11c06017152dc99f8721fef0585ad9432838b46f8f9f7"},{"deviceId":"78f07683774a206866fdb098d8cac2cb5afc980ba3e670f85393eb16d5e914b9","kind":"audioinput","label":"Headset Microphone (Oculus Virtual Audio Device)","groupId":"05a90cf47adb203e6eb67353f82529c636dc92833ed13f011042a32a370c44c7"},{"deviceId":"68cb94c20ca0b8f17bbaad703c76cbce402793b5e18ddc89e68f38865ed82478","kind":"videoinput","label":"Intel(R) RealSense(TM) 435 with RGB Module Depth (8086:0b07)","groupId":"eb53f0590ee544f7848664d5e2ac6c8430659c4a34e26edf401b57fd9a8ce83c"},{"deviceId":"943c211869cd4e58039d142e22b98ca0cc53dc4d7f60723c832cf73b52b49d6f","kind":"videoinput","label":"Intel(R) RealSense(TM) 435 with RGB Module RGB (8086:0b07)","groupId":"16dd5ec91babf1e3d461bb5afe04bd4713b0c95d3c538ea6f3515dc5c3aacb9a"},{"deviceId":"0329d90dd74edc8657af0bb0d32652989fb1c162d0c294794cbc7fd76e4cf9a9","kind":"videoinput","label":"USB Video Device (1532:0e03)","groupId":"a5fe4973e22ce5b529b8cccd14ce14ed356709d356c94228cb5c2e77d804f297"},{"deviceId":"426bd00749eecdb8ce1da28ecae7d99e78310cc57aedbdf947e9288f4660ad12","kind":"videoinput","label":"USB Video Device (1532:0e03)","groupId":"1b4fc078561da2a5b19c21531d27485fa6f19368d8440d2740d94809c3b5da84"},{"deviceId":"default","kind":"audiooutput","label":"Default - Speakers (Realtek(R) Audio)","groupId":"8e1aab63dd80f414dce561f4e368bb484c065834f3941db045ca722f61d254a4"},{"deviceId":"communications","kind":"audiooutput","label":"Communications - Headphones (Oculus Virtual Audio Device)","groupId":"05a90cf47adb203e6eb67353f82529c636dc92833ed13f011042a32a370c44c7"},{"deviceId":"7c5103d23dc4e21fb0c436dbf039909bc2c70611a92587da582edd74bbee8460","kind":"audiooutput","label":"PHL BDM3490 (NVIDIA High Definition Audio)","groupId":"731a927b663a4a209a3359d16c1c1f214ded54c07f084f659ff4809e6cf588d5"},{"deviceId":"218fa70f234dbf497b6044345c531d15120f56a49e872e3062a0d9da11f8d158","kind":"audiooutput","label":"Speakers (Steam Streaming Microphone)","groupId":"20a28b389c696bd36556474101f44876ee56f686b3717913354b85fa804c8c7a"},{"deviceId":"11c4193f457b6e9cfa44f88fa6742d8a151ce7dfd8bd71b8fd97d0f5b664a6ec","kind":"audiooutput","label":"DELL U2715H (NVIDIA High Definition Audio)","groupId":"4cd1fd9ed5fe4bb80fe7984a3c60e472548f37e157239e4d901ffe8394af5205"},{"deviceId":"f9893c7a1ce8fd1f229a37d8963f9db9504c03cff47e173bc4f1ab4ee20696db","kind":"audiooutput","label":"Headphones (Oculus Virtual Audio Device)","groupId":"05a90cf47adb203e6eb67353f82529c636dc92833ed13f011042a32a370c44c7"},{"deviceId":"c611d06286b441cb1e3440e9bf09f534d98b4ed2e41528eb9c54cb7e41779c63","kind":"audiooutput","label":"Speakers (Steam Streaming Speakers)","groupId":"4d0e12aa90d61a5867f01beea961e77cb03796fd77a2c8cde7f25ec82b718ee9"},{"deviceId":"e00a5fe0a89b8c5bd2858060265e9b0937249601678974e5f3180f797e99ef9e","kind":"audiooutput","label":"Speakers (Realtek(R) Audio)","groupId":"8e1aab63dd80f414dce561f4e368bb484c065834f3941db045ca722f61d254a4"},{"deviceId":"e29c7603a6e3b56aaf3ffc5535f563dd2bce09ce208722837aecee06eaf358d9","kind":"audiooutput","label":"Realtek Digital Output (Realtek(R) Audio)","groupId":"7ae806bf56274db2fab2c6c03a14eed45022de19176702d33821bb7c8e436e8d"}])
	;(async function() {

/*
		try{
			await new Promise(((resolve, reject) => {
				navigator.permissions.query( { name: 'microphone' } ).then(function(result) {
					if (result.state === 'granted') {
						console.log(result.state);

						resolve();
					} else if (result.state === 'prompt') {
						console.log('waiting permission')
					}else{
						reject();
					}
					// Don't do anything if the permission was denied.
				});
			}));
		}catch(error){
			console.log('Got error :', error);
		}
*/

		try{
			await new Promise(((resolve, reject) => {
				navigator.permissions.query( { name: 'camera' } )
					.then(async function(result) {
						if (result.state === 'granted') {
							console.log(result.state);

							resolve();
						} else if (result.state === 'prompt') {
							console.log('waiting permission')
							try{
								await new Promise(((r1, reject) => {
									navigator.mediaDevices.getUserMedia( { video: { width: window.videoSize.w, height: window.videoSize.h } } )
										.then( function( stream ){
											r1();
											resolve();
										} )
										.catch( function( err ){
											reject(err);
											/* handle the error */
										} );
								}));
							}catch( e ){
								console.log('Got error :', e);

							}


						}else{
							reject();
						}
						// Don't do anything if the permission was denied.
					})
					.catch((error) => {
						console.log('Got error :', error);
						reject(error);
					});
			}));
		}catch(error){
			console.log('Got error :', error);
		}

		navigator.mediaDevices.enumerateDevices()
			/*.then(devices => {
				var cameras = devices.filter(device => device.kind == "videoinput");
				return Promise.all(cameras.map(async function(camera) {
					var constraints = { deviceId: { exact: camera.deviceId }, width: window.videoSize.w };
					var media = await navigator.mediaDevices.getUserMedia({ video: constraints })
					debugger
					return media;
				}))

			})*/
			.then(gotDevices).catch(handleError);

		var soundDisablerID = setInterval(function() {
			D('video').map(a=>a.muted = true)
		}, 2000);
		window.enableSound = function() {
			clearInterval(soundDisablerID);
			D('video').map(a=>a.muted = false)

		}
	})();
	return dom;
};

Screen.Conference.beforeShow = function() {
	isConnecting.set(false);
	store.set({
		connection: false,
		callScreenCamerasTune: false
	});
};
