<krpano>

	<include url="%VIEWER%/plugins/copy_to_clipboard.xml" />

	<!-- chroma key settings UI -->
	<layer name="chromakey_control" keep="true" type="container" bgcapture="true" width="200" height="335" align="right" x="10" y="0" bgalpha="1.0" bgcolor="0xFFFFFF" bgborder="0 0x00000 0.7" bgroundedge="1" bgshadow="0 1 4 0x000000 1.0" ondown="draglayer();">

		<layer name="ckc_check" style="pp_checkbox" checked="true" onclick="switch(checked); if(checked AND chromakeybackup, copy(hotspot[get(chromakey_helper_hotspot)].chromakey,chromakeybackup), copy(chromakeybackup,hotspot[get(chromakey_helper_hotspot)].chromakey); set(hotspot[get(chromakey_helper_hotspot)].chromakey,null); );" />
		<layer name="ckc_info" style="pp_text" html="Chroma Key Mask" align="top" y="8" x="0" capture="false" />

		<layer name="ckc_color" type="container" bgborder="1 0x000000 0.12" bgroundedge="1" bgcolor="0xFFFFFF" align="top" x="0" y="32" width="180" height="calc:180+22">

			<layer name="ckc_colorplane" type="container" bgcapture="true" align="lefttop" width="180" height="180" handcursor="false"
				onloaded="draw_ycbcr_colorplane()"
				ondown="asyncloop(pressed,
							calc(color, ycbcr_to_rgb24(128 ,calc(hitx*255), calc((1.0-hity)*255)) );
							ckc_update_color(get(color));
							set(layer[ckc_picker_pos], x=calc(hitx*100+'%'), y=calc(hity*100+'%'));
						);"
				>
				<layer name="ckc_picker_pos" type="container" width="15" height="15" bgroundedge="15" bgborder="1 0xFFFFFF" visible="false" align="lefttop" edge="center" scale="0.5" enabled="false" />
			</layer>

			<layer name="ckc_color_bg" type="text" align="leftbottom" width="100%" height="22" vcenter="true" x="0" y="0" css="text-align:left;" padding="0 0 0 44" handcursor="false"
				onloaded="txtsplit(hotspot[get(chromakey_helper_hotspot)].chromakey, '|', color, threshold, smoothing); if(isvalue(color), ckc_update_color(get(color)));"
				/>

			<layer name="ckc_colorpicker_icon"
				url="colorpicker_icon.png"
				align="rightbottom" width="18" height="18" x="2" y="2"
				onclick="pick_color_from_screen(color, ckc_update_color(get(color)); );"
				/>

		</layer>

		<layer name="ckc_threshold" style="pp_button|pp_valuecontrol" align="bottom" x="0" y="70" width="180" cursor="col-resize"
			varstep="0.05"
			vardragrange="1.0"
			getvar="txtsplit(hotspot[get(chromakey_helper_hotspot)].chromakey, '|', color, var, smoothing); if(!isset(var), set(var,0.1)); if(!isset(smoothing), set(smoothing,0.1));"
			setvar="clamp(var,0.0,3.0); roundval(var,3); txtjoin(hotspot[get(chromakey_helper_hotspot)].chromakey, '|', color, var, smoothing); getvar(); calc(html,'Threshold: ' + roundval(var,3));"
			/>

		<layer name="ckc_smoothing" style="pp_button|pp_valuecontrol" align="bottom" x="0" y="40" width="180" cursor="col-resize"
			varstep="0.01"
			vardragrange="0.2"
			getvar="txtsplit(hotspot[get(chromakey_helper_hotspot)].chromakey, '|', color, threshold, var); if(!isset(var), if(!isset(threshold), set(threshold,0.1)); set(var,0.1));"
			setvar="clamp(var,0.0,1.0); roundval(var,3); txtjoin(hotspot[get(chromakey_helper_hotspot)].chromakey, '|', color, threshold, var); getvar(); calc(html,'Smoothing: ' + roundval(var,3));"
			/>

		<layer name="ckc_clipboard" style="pp_button" align="bottom" x="0" y="10" width="180"
			html="Copy XML to Clipboard"
			onclick="copy_to_clipboard(calc('chromakey='+unescape(%22)+hotspot[get(chromakey_helper_hotspot)].chromakey+unescape(%22)));"
			/>

	</layer>


	<!-- an action to update all color related UI elements -->
	<action name="ckc_update_color" scope="local" args="color">
		calc(ycbcr, rgb24_to_ycbcr24(color));
		calc(cb, (ycbcr RSHT 8) BAND 255);
		calc(cr, ycbcr BAND 255);
		set(global.layer[ckc_picker_pos], visible=true, x=calc(cb/255*100+'%'), y=calc((255-cr)/255*100+'%'));
		txtsplit(global.hotspot[get(chromakey_helper_hotspot)].chromakey, '|', skip, threshold, smoothing);
		tohex(color, '0x', 6);
		copy(global.layer[ckc_color_bg].bgcolor, color);
		calc(global.layer[ckc_color_bg].html, 'Color: ' + $color);
		txtjoin(global.hotspot[get(chromakey_helper_hotspot)].chromakey, '|', color, threshold, smoothing);
	</action>


	<!-- color picker: make a screenshot, show it, and pick a color from it -->
	<action name="pick_color_from_screen" type="Javascript"><![CDATA[

		var hs = krpano.get("hotspot[get(chromakey_helper_hotspot)]");

		var backup = hs.chromakey;
		hs.chromakey = null;	// disable the chromakey setting for the screenshot

		var screenshotcanvas = krpano.webGL.makeScreenshot(0, 0, true, "canvas");

		hs.chromakey = backup;	// restore the chromakey setting

		if (screenshotcanvas)
		{
			var backup_onkeydown = krpano.events.onkeydown;

			// cancel picking with any keyboard key
			krpano.events.onkeydown = function()
			{
				krpano.removelayer("screenshotimage",true);
				krpano.events.onkeydown = backup_onkeydown;
			}

			var image = krpano.addlayer("screenshotimage");
			image.url = screenshotcanvas.toDataURL();		// convert the screenshot-canvas to a base64 data-url for showing it
			image.parent = "STAGE";
			image.align = "lefttop";
			image.width = "100%";
			image.height = "100%";
			image.handcursor = "false";
			image.zorder = 999;
			image.cursor = "crosshair";
			image.onclick = function()
			{
				var pix = screenshotcanvas.getContext('2d').getImageData(krpano.mouse.x,krpano.mouse.y, 1, 1).data;

				krpano.removelayer("screenshotimage",true);
				krpano.events.onkeydown = backup_onkeydown;

				var color = (pix[0] << 16) | (pix[1] << 8) | pix[2];

				// set a global 'color' variable in krpano and do a callback
				krpano.set(args[1], color);
				krpano.call(args[2]);
			};

			// some info UI
			var pickborder = krpano.addlayer("pickborder");
			pickborder.type = "container";
			pickborder.parent = "screenshotimage";
			pickborder.align = "center";
			pickborder.width = "-80";
			pickborder.height = "-80";
			pickborder.bgborder = "40 0x000000 1.0";
			pickborder.enabled = false;

			var pickinfo = krpano.addlayer("pickinfo");
			pickinfo.type = "text";
			pickinfo.parent = "screenshotimage";
			pickinfo.align = "top";
			pickinfo.y = 5;
			pickinfo.html = "PICK A COLOR";
			pickinfo.css = "font-size:24px;font-weight:bold;color:#FFFFFF;"
			pickinfo.bg = false;
			pickinfo.enabled = false;
		}

	]]></action>


	<!-- UI styles -->
	<style name="pp_text"
	       type="text"
	       css="color:#000000;"
	       bg="false"
	       />

	<style name="pp_button"
	       type="text"
	       css="text-align:center;"
	       height="22"
	       padding="4 8"
	       bgborder="1 0x000000 0.12"
	       bgroundedge="1"
	       bgcolor="0xFFFFFF"
	       ondown.addevent="set(bgcolor,0xDDDDDD);"
	       onup.addevent="if(!hovering,set(bgcolor,0xFFFFFF),set(bgcolor,0xEEEEEE));"
	       onover.addevent="if(!pressed,set(bgcolor,0xEEEEEE));"
	       onout.addevent="if(!pressed,set(bgcolor,0xFFFFFF));"
	       />

	<style name="pp_valuecontrol"
	       ondown.addevent="pp_valuecontrol_ondown();"
	       onloaded.addevent="getvar(); setvar(); pp_valuecontrol_add_incdec_buttons();"
	       />

	<style name="pp_checkbox"
	       type="container" align="lefttop" width="35" height="30" zorder="2" children="false" bgcapture="true" xxbgborder="1 0xFF0000"
	       onloaded="pp_checkbox_init();"
	       onclick.addevent="delayedcall(0, onloaded() );"
	       />


	<action name="pp_checkbox_init" scope="localonly">
		addlayer(calc(caller.name + '_border'), layer1);
		addlayer(calc(caller.name + '_fill'), layer2);
		set(layer1, parent=get(caller.name), keep=get(caller.keep), type=container, zorder=1, align=lefttop, x=10, y=10, width=14, height=14, bgborder='1 0x000000 0.12', bgroundedge=1);
		set(layer2, parent=get(caller.name), keep=get(caller.keep), type=container, zorder=2, align=lefttop, x=11, y=11, width=12, height=12, bgcolor=0x000000, bgalpha=0.24);
		tween(layer2.bgalpha|global.layer[get(caller.parent)].alpha, calc(caller.checked ? '0.24|1.0' : '0.05|0.7'), 0.15);
	</action>


	<!-- an action for add increase/decrease buttons on the value control -->
	<action name="pp_valuecontrol_add_incdec_buttons" scope="localonly">
		addlayer(calc(caller.name + '_inc'), layer_inc);
		addlayer(calc(caller.name + '_dec'), layer_dec);
		layer_inc.loadstyle(pp_button);
		layer_dec.loadstyle(pp_button);
		set(layer_inc, parent=get(caller.name), keep=get(caller.keep), align=right, html='+', ondown='set(stepdir,+1); pp_valuecontrol_incdec_ondown();');
		set(layer_dec, parent=get(caller.name), keep=get(caller.keep), align=left,  html='-', ondown='set(stepdir,-1); pp_valuecontrol_incdec_ondown();');
	</action>


	<!-- an action for increasing or decreasing the button values -->
	<action name="pp_valuecontrol_incdec_ondown">
		copy(t1,timertick);
		asyncloop(pressed,
			calc(dt,timertick - t1);
			if(dt GT 500,
				callwith(calc('layer['+parent+']'),
					calc(dt,timertick - t1);
					calc(stepscale, dt GT 2000 ? (dt / 1000) : 1.0);
					getvar();
					calc(var, var + stepdir * stepscale * varstep / display.currentfps);
					setvar();
				);
			);
		  ,
			calc(dt,timertick - t1);
			if(dt LT 500,
				callwith(calc('layer['+parent+']'),
					getvar();
					calc(var, (var + stepdir * varstep) / varstep);
					Math.round(var);
					calc(var, var * varstep);
					setvar();
				);
			);
		);
	</action>


	<!-- an action for changing the button value by dragging/moving the mouse around -->
	<action name="pp_valuecontrol_ondown">
		if(vardragrange GT 0,
			copy(startx, mouse.stagex);
			copy(starty, mouse.stagey);
			getvar();
			copy(startv, var);
			asyncloop(pressed,
				calc(dx, (mouse.stagex - startx) / pixelwidth );
				calc(dy, (mouse.stagey - starty) / pixelwidth );
				if(dx*dx GT dy*dy,
					calc(var,startv + dx * vardragrange);
				  ,
					calc(var,startv + dy * vardragrange);
				);
				setvar();
			  );
		);
	</action>


	<!-- add fast color conversion functions -->
	<action autorun="preinit" type="Javascript"><![CDATA[

		krpano.inlinefunctions.rgb24_to_ycbcr24 = function(rgb)
		{
			var r = (rgb >> 16) & 255;
			var g = (rgb >> 8) & 255;
			var b = rgb & 255;
			var y  = (0.2989*r + 0.5866*g + 0.1145*b);
			var cb = (0.5647*(b - y) + 128.5) | 0;
			var cr = (0.7132*(r - y) + 128.5) | 0;
			y = (y + 0.5) | 0;
			if (y  < 0) y  = 0; else if (y  > 255) y  = 255;
			if (cb < 0) cb = 0; else if (cb > 255) cb = 255;
			if (cr < 0) cr = 0; else if (cr > 255) cr = 255;
			return (y << 16) | (cb << 8) | cr;
		}

		krpano.inlinefunctions.ycbcr_to_rgb24 = function(y,cb,cr)
		{
			var r = (y + 1.4022*(cr - 128));
			var b = (y + 1.7710*(cb - 128));
			var g = (1.7036*y - 0.1943*b - 0.5093*r + 0.5) | 0;
			r = (r + 0.5) | 0;
			b = (b + 0.5) | 0;
			if (r < 0) r = 0; else if (r > 255) r = 255;
			if (g < 0) g = 0; else if (g > 255) g = 255;
			if (b < 0) b = 0; else if (b > 255) b = 255;
			return (r << 16) | (g << 8) | b;
		}

	]]></action>


	<!-- draw a YCbCr color plane -->
	<action name="draw_ycbcr_colorplane" type="Javascript"><![CDATA[

		var canvas = document.createElement("canvas");
		canvas.width = 256;
		canvas.height = 256;
		canvas.style.width = "100%";
		canvas.style.height = "100%";
		canvas.style.pointerEvents = "none";
		caller.sprite.appendChild(canvas);

		var ycbcr_to_rgb24 = krpano.inlinefunctions.ycbcr_to_rgb24;
		var x,y;
		var ctx = canvas.getContext("2d");
		for (y=0; y < 256; y++)
		for (x=0; x < 256; x++)
		{
			ctx.fillStyle = "#" +(ycbcr_to_rgb24(128,x,255-y)|0x1000000).toString(16).slice(1);
			ctx.fillRect(x,y, 1,1);
		}

	]]></action>


	<!-- drag a layer with an ondown event -->
	<action name="draglayer">
		copy(drag_currentx, x);
		copy(drag_currenty, y);
		copy(drag_stagex, mouse.stagex);
		copy(drag_stagey, mouse.stagey);
		indexoftxt(align_contains_right, get(align), 'right');
		indexoftxt(align_contains_bottom, get(align), 'bottom');
		calc(drag_align_x, align_contains_right GE 0 ? -1 : +1);
		calc(drag_align_y, align_contains_bottom GE 0 ? -1 : +1);
		asyncloop(pressed,
			calc(x, drag_currentx + (mouse.stagex - drag_stagex)*drag_align_x);
			calc(y, drag_currenty + (mouse.stagey - drag_stagey)*drag_align_y);
		  );
	</action>


</krpano>
