//C:\util\flex_sdk_4.6\frameworks\flex-config.xml(47): Error: unable to open 'libs/player/11.1/playerglobal.swc'


        // http://www.adobe.com/devnet/flashplayer/articles/rtmfp_stratus_app_03.html

        // see this video:
        // http://tv.adobe.com/#vi+f15384v1056

        /// <summary>
        /// Default constructor
        /// </summary>
        public FlashStratusDemo()
        {

            var t = new TextField
            {
                multiline = true,
                text = "powered by jsc",
                background = true,
                x = 0,
                y = 0,
                width = 400,
                alwaysShowSelection = true,
            }.AttachTo(this);

            var c = new NetConnection();



            Func<NetStatusEvent, string> get_Code =
                e =>
                {
                    var info = new DynamicContainer { Subject = e.info };
                    var code = (string)info["code"];

                    return code;
                };


            c.netStatus +=
                status =>
                {
                    // http://livedocs.adobe.com/flash/9.0/ActionScriptLangRefV3/flash/events/NetStatusEvent.html#info


                    t.appendText("\nc.netStatus: " + get_Code(status));

                    if (get_Code(status) == "NetConnection.Connect.Success")
                    {
                        t.appendText("\n" + c.nearID);

                        #region we could be a client

                        var q = new TextField
                        {
                            background = true,
                            x = 0,
                            y = 200,
                            width = 400,
                            alwaysShowSelection = true,
                            text = "enter id here",
                            type = TextFieldType.INPUT
                        }.AttachTo(this);


                        q.change +=
                            delegate
                            {
                                if (q.text.Length != c.nearID.Length)
                                    return;

                                if (q.text == c.nearID)
                                    return;

                                t.appendText("\ntarget set");
                                q.Orphanize();

                                var r = new NetStream(c, q.text);

                                r.netStatus +=
                                    r_status =>
                                    {

                                        t.appendText("\nr.netStatus: " + get_Code(r_status));
                                    };

                                r.client = new DynamicDelegatesContainer
									{
										{"handler1", 
											(string x) =>
											{
												t.appendText("\nhandler1: " + x);
												t.setSelection( t.length, t.length);
											}
										}
									}.Subject;

                                r.play("stream1");
                            };
                        #endregion

                        // yay! we are online
                        var s = new NetStream(c, NetStream.DIRECT_CONNECTIONS);

                        s.client = new DynamicDelegatesContainer
						{
							{"onPeerConnect", 
								(NetStream x) =>
								{
									
									t.appendText("\nonPeerConnect: " + x.farID);
									t.setSelection( t.length, t.length);

									q.Orphanize();

									return true;
								}
							}
						}.Subject;

                        s.netStatus +=
                            s_status =>
                            {

                                t.appendText("\ns.netStatus: " + get_Code(s_status));
                            };









                        s.publish("stream1");

                        #region broadcast the data
                        var counter = 0;

                        5000.AtInterval(
                            delegate
                            {
                                counter++;

                                s.send("handler1", "counter = " + counter);
                            }
                        );
                        #endregion

                    }
                };




            // "Developer Key" means any license key, activation code, or similar 
            // installation, access or usage control codes, including serial numbers 
            // and electronic certificates digitally signed by Adobe, designed to 
            // uniquely identify your Developer Program and link it to you 
            // the Developer.

            // Attention: You cannot use this key in your applications.
            //c.connect("rtmfp://stratus.adobe.com/3f37a156abb67621000856d1-08d2970f1b43/");
            c.connect("rtmfp://stratus.adobe.com/3f37a156abb67621000856d1-08d2970f1b43");

            // X:\jsc.svn\examples\actionscript\MultitouchExample\MultitouchFingerTools.FlashLAN\ApplicationCanvas.Session.cs
        }
		private void Initialize()
		{
			var stage = this.stage;

			if (stage == null)
				throw new Exception("stage is null");


			this.graphics.beginFill(0xefff80);
			this.graphics.drawRect(0, 0, stage.stageWidth, stage.stageHeight / 2);

			this.graphics.beginFill(0xef8fff);
			this.graphics.drawRect(0, stage.stageHeight / 2, stage.stageWidth, stage.stageHeight / 2);


			var info = new TextField
			{
				selectable = false,
				multiline = true,
				width = stage.stageWidth,
				height = stage.stageHeight 
			}.AttachTo(this);

			var snapcontainer = this.Attach(new Shape());
			var vectorized = this.Attach(new Shape());
			var delta = new Shape { alpha = 0.5 }.AttachTo(this);

			var ego = new Sprite { mouseEnabled = false, x = stage.stageWidth / 2, y = stage.stageHeight / 2 }.AttachTo(this);
			var ego_img = gtataxi.ToBitmapAsset().AttachTo(ego);

			ego_img.x = -ego_img.width / 2;
			ego_img.y = -ego_img.height / 2;

			Action<string, object> Write = (p, e) =>
					{
						info.appendText(p + e.ToString() + Environment.NewLine);
						info.setSelection(info.text.Length - 1, info.text.Length - 1);
					};





			var mouseDown_args = default(MouseEvent);
			var mouseUp_fadeOut = default(Timer);

			uint color = 0;

			var snap_radius = 64;

			stage.mouseDown +=
					e =>
					{
						color = 0;

						// snap to old point
						if (mouseDown_args != null)
							if (snapcontainer.alpha > 0)
								if ((mouseDown_args.ToStagePoint() - e.ToStagePoint()).length < snap_radius)
								{
									color = 0xff;

									e = mouseDown_args;
								}

						mouseDown_args = e;

						Write("down ", new { e.localX, e.localY, e.buttonDown });
					};

			Action<Shape, double, double, uint> DrawArrow =
					(s, x, y, c) =>
					{


						s.graphics.lineStyle(2, c, 1);
						s.graphics.moveTo(mouseDown_args.stageX, mouseDown_args.stageY);
						s.graphics.lineTo(x, y);
						s.graphics.drawCircle(x, y, 4);
					};

			var mouseMove_args = default(MouseEvent);
			var delta_pos = 0.0;

			stage.mouseMove +=
					e =>
					{
						if (e.buttonDown)
						{
							mouseMove_args = e;

							if (mouseUp_fadeOut != null)
								mouseUp_fadeOut.stop();

							vectorized.alpha = 1;
							vectorized.graphics.clear();

							snapcontainer.alpha = 1;
							snapcontainer.graphics.clear();


							snapcontainer.graphics.lineStyle(2, 0xff, 1);
							snapcontainer.graphics.drawCircle(mouseDown_args.stageX, mouseDown_args.stageY, snap_radius);

							DrawArrow(vectorized, e.stageX, e.stageY, color);
						}
						else
						{
							if (delta_pos == 0)
								Write("move ", new { e.stageY, stage.stageHeight, stageScaleY = stage.scaleY, this.scaleY, stage.height });
							//Write("move ", new { e.stageX, e.stageY, stage.stageWidth, stage.stageHeight, stage.scaleX, stage.scaleY });
						}
					};

			stage.mouseUp +=
					e =>
					{
						Write("up ", new { e.localX, e.localY, e.buttonDown });

						if (mouseUp_fadeOut != null)
							mouseUp_fadeOut.stop();


						mouseUp_fadeOut = 50.AtInterval(
								t =>
								{
									vectorized.alpha -= 0.02;

									snapcontainer.alpha -= 0.04;
								}
						);
					};


			var delta_acc_min = 0.02;
			var delta_acc = delta_acc_min;
			var delta_acc_acc = delta_acc_min * 0.01;

			var delta_deacc_min = 0.03;
			var delta_deacc = delta_deacc_min;

			(1000 / 24).AtInterval(
				t =>
				{
					if (mouseDown_args == null)
						return;

					if (mouseMove_args == null)
						return;

					delta.graphics.clear();

					if (vectorized.alpha == 1)
					{
						delta_pos += delta_acc;
						//delta_deacc = (delta_deacc - delta_deacc_acc).Max(delta_deacc_min);
						delta_acc += delta_acc_acc;
					}
					else
					{
						delta_pos -= delta_deacc;
						delta_acc -= delta_acc_acc;

						if (delta_acc < delta_acc_min)
							delta_acc = delta_acc_min;

						//delta_deacc += delta_deacc_acc;
					}

					delta_pos = delta_pos.Min(1).Max(0);

					var u = (mouseMove_args.ToStagePoint() - mouseDown_args.ToStagePoint()) * delta_pos;
					var z = mouseDown_args.ToStagePoint() + u;

					if (delta_pos > 0)
						if (mouseDown_args.stageY > stage.height / 2)
						{
							// boolean
							Write("rot ", new { delta_pos, u.x, u.y });

							ego.rotation += u.x * 0.2;

							var p = ego.ToPoint().MoveToArc(((int)ego.rotation).DegreesToRadians(), -u.y * 0.2);

							ego.x = p.x;
							ego.y = p.y;
						}
						else
						{
							Write("pan ", new { delta_pos, u.x, u.y });

							var p = ego.ToPoint().MoveToArc(u.GetRotation() + ((int)ego.rotation + 270).DegreesToRadians(), -u.length * 0.2);

							ego.x = p.x;
							ego.y = p.y;
						}

					DrawArrow(delta, z.x, z.y, 0xff00);
				}
			);
		}