// Editor debug icons
// to add new std debug icons just add IconType, IconsTypesMaterials and ComponentTypes items

enum IconsTypes
{
    ICON_POINT_LIGHT = 0,
    ICON_SPOT_LIGHT,
    ICON_DIRECTIONAL_LIGHT,
    ICON_CAMERA,
    ICON_SOUND_SOURCE,
    ICON_SOUND_SOURCE_3D,
    ICON_SOUND_LISTENERS,
    ICON_ZONE,
    ICON_SPLINE_PATH,
    ICON_TRIGGER,
    ICON_CUSTOM_GEOMETRY,
    ICON_PARTICLE_EMITTER,
    ICON_COUNT
}

enum IconsColorType
{
    ICON_COLOR_DEFAULT = 0,
    ICON_COLOR_SPLINE_PATH_BEGIN,
    ICON_COLOR_SPLINE_PATH_END
}

Array<Color> debugIconsColors = { Color(1,1,1) , Color(1,1,0), Color(0,1,0) };

Array<String> IconsTypesMaterials = {"DebugIconPointLight.xml",
                                     "DebugIconSpotLight.xml",
                                     "DebugIconLight.xml",
                                     "DebugIconCamera.xml",
                                     "DebugIconSoundSource.xml",
                                     "DebugIconSoundSource.xml",
                                     "DebugIconSoundListener.xml",
                                     "DebugIconZone.xml",
                                     "DebugIconSplinePathPoint.xml",
                                     "DebugIconCollisionTrigger.xml",
                                     "DebugIconCustomGeometry.xml",
                                     "DebugIconParticleEmitter.xml"};

Array<String> ComponentTypes = {"Light",
                                "Light",
                                "Light",
                                "Camera",
                                "SoundSource",
                                "SoundSource3D",
                                "SoundListener",
                                "Zone",
                                "SplinePath",
                                "RigidBody",
                                "CustomGeometry",
                                "ParticleEmitter"};

Array<BillboardSet@> debugIconsSet(ICON_COUNT);
Node@ debugIconsNode = null;
int stepDebugIconsUpdate = 100; //ms
uint timeToNextDebugIconsUpdate = 0;
int stepDebugIconsUpdateSplinePath = 1000; //ms
uint timeToNextDebugIconsUpdateSplinePath = 0;
const int splinePathResolution = 16;
const float splineStep = 1.0f / splinePathResolution;
bool debugIconsShow = true;
Vector2 debugIconsSize = Vector2(64, 64);
Vector2 debugIconsSizeSmall = debugIconsSize / 1.5;
VariantMap debugIconsPlacement;
const int debugIconsPlacementIndent = 1.0;
const float debugIconsOrthoDistance = 15.0;
const float debugIconAlphaThreshold = 0.1;
const float maxDistance = 50.0;

void CreateDebugIcons(Node@ tempNode)
{
    if (editorScene is null) return;
    debugIconsSet.Resize(ICON_COUNT);
    for (int i = 0; i < ICON_COUNT; ++i)
    {
        debugIconsSet[i] = tempNode.CreateComponent("BillboardSet");
        debugIconsSet[i].material = cache.GetResource("Material", "Materials/Editor/" + IconsTypesMaterials[i]);
        debugIconsSet[i].sorted = true;
        debugIconsSet[i].temporary = true;
        debugIconsSet[i].fixedScreenSize = true;
        debugIconsSet[i].viewMask = 0x80000000;
    }
}

void UpdateViewDebugIcons()
{
    if (editorScene is null || timeToNextDebugIconsUpdate > time.systemTime) return;

    debugIconsNode = editorScene.GetChild("DebugIconsContainer", true);

    if (debugIconsNode is null)
    {
        debugIconsNode = editorScene.CreateChild("DebugIconsContainer", LOCAL);
        debugIconsNode.temporary = true;
    }
    // Checkout if debugIconsNode do not have any BBS component, add all at once
    BillboardSet@ isBSExist = debugIconsNode.GetComponent("BillboardSet");
    if (isBSExist is null)
        CreateDebugIcons(debugIconsNode);

    if (debugIconsSet[ICON_POINT_LIGHT] !is null)
    {
        for (int i = 0; i < ICON_COUNT; ++i)
            debugIconsSet[i].enabled = debugIconsShow;
    }

    if (debugIconsShow == false) return;

    Vector3 camPos = activeViewport.cameraNode.worldPosition;
    bool isOrthographic = activeViewport.camera.orthographic;
    debugIconsPlacement.Clear();

    for (int iconType = 0; iconType < ICON_COUNT; ++iconType)
    {
        if (debugIconsSet[iconType] !is null)
        {
            // SplinePath update resolution
            if (iconType == ICON_SPLINE_PATH && timeToNextDebugIconsUpdateSplinePath > time.systemTime)
                continue;

            Array<Node@> nodes = editorScene.GetChildrenWithComponent(ComponentTypes[iconType], true);

            // Clear old data
            if (iconType == ICON_SPLINE_PATH)
                ClearCommit(ICON_SPLINE_PATH, ICON_SPLINE_PATH + 1, nodes.length * splinePathResolution);
            else if (iconType == ICON_POINT_LIGHT || iconType == ICON_SPOT_LIGHT || iconType == ICON_DIRECTIONAL_LIGHT)
                ClearCommit(ICON_POINT_LIGHT, ICON_DIRECTIONAL_LIGHT + 1, nodes.length);
            else if (iconType == ICON_SOUND_SOURCE || iconType == ICON_SOUND_SOURCE_3D)
                ClearCommit(ICON_SOUND_SOURCE, ICON_SOUND_SOURCE_3D + 1, nodes.length);
            else
                ClearCommit(iconType, iconType + 1, nodes.length);

            if (nodes.length > 0)
            {
                // Fill with new data
                for (uint i = 0; i < nodes.length; ++i)
                {
                    Component@ component = nodes[i].GetComponent(ComponentTypes[iconType]);
                    if (component is null) continue;

                    Color finalIconColor = debugIconsColors[ICON_COLOR_DEFAULT];
                    float distance = (camPos - nodes[i].worldPosition).length;
                    if (isOrthographic)
                        distance = debugIconsOrthoDistance;
                    int iconsOffset = debugIconsPlacement[StringHash(nodes[i].id)].GetInt();
                    float iconsYPos = 0;

                    if (iconType == ICON_SPLINE_PATH)
                    {
                        SplinePath@ sp = cast<SplinePath>(component);
                        if (sp !is null)
                        {
                            if (sp.length > 0.01f)
                            {
                                for (int step = 0; step < splinePathResolution; step++)
                                {
                                    int index = (i * splinePathResolution) + step;
                                    Vector3 splinePoint = sp.GetPoint(splineStep * step);
                                    Billboard@ bb = debugIconsSet[ICON_SPLINE_PATH].billboards[index];
                                    float stepDistance = (camPos - splinePoint).length;
                                    if (isOrthographic)
                                        stepDistance = debugIconsOrthoDistance;

                                    if (step == 0) // SplinePath start
                                    {
                                        bb.color = debugIconsColors[ICON_COLOR_SPLINE_PATH_BEGIN];
                                        bb.size = debugIconsSize;
                                        bb.position = splinePoint;
                                    }
                                    else if ((step+1) >= (splinePathResolution - splineStep)) // SplinePath end
                                    {
                                        bb.color = debugIconsColors[ICON_COLOR_SPLINE_PATH_END];
                                        bb.size = debugIconsSize;
                                        bb.position = splinePoint;
                                    }
                                    else // SplinePath middle points
                                    {
                                        bb.color = finalIconColor;
                                        bb.size = debugIconsSizeSmall;
                                        bb.position = splinePoint;
                                    }
                                    bb.enabled = sp.enabled;
                                    // Blend Icon relatively by distance to it
                                    bb.color = Color(bb.color.r, bb.color.g, bb.color.b, 1.2f - 1.0f / (maxDistance / stepDistance));
                                    if (bb.color.a < debugIconAlphaThreshold)
                                        bb.enabled = false;
                                }
                            }
                        }
                    }
                    else
                    {
                        Billboard@ bb = debugIconsSet[iconType].billboards[i];
                        bb.size = debugIconsSize;

                        if (iconType == ICON_TRIGGER)
                        {
                            RigidBody@ rigidbody = cast<RigidBody>(component);
                            if (rigidbody !is null)
                            {
                                if (rigidbody.trigger == false)
                                    continue;
                            }
                        }
                        else if (iconType == ICON_POINT_LIGHT || iconType == ICON_SPOT_LIGHT || iconType == ICON_DIRECTIONAL_LIGHT)
                        {
                            Light@ light = cast<Light>(component);
                            if (light !is null)
                            {
                                if (light.lightType == LIGHT_POINT)
                                    bb = debugIconsSet[ICON_POINT_LIGHT].billboards[i];
                                else if (light.lightType == LIGHT_DIRECTIONAL)
                                    bb = debugIconsSet[ICON_DIRECTIONAL_LIGHT].billboards[i];
                                else if (light.lightType == LIGHT_SPOT)
                                    bb = debugIconsSet[ICON_SPOT_LIGHT].billboards[i];

                                finalIconColor = light.effectiveColor;
                            }
                        }

                        bb.position = nodes[i].worldPosition;
                        // Blend Icon relatively by distance to it
                        bb.color = Color(finalIconColor.r, finalIconColor.g, finalIconColor.b, 1.2f - 1.0f / (maxDistance / distance));
                        bb.enabled = component.enabled;
                        // Discard billboard if it almost transparent
                        if (bb.color.a < debugIconAlphaThreshold)
                            bb.enabled = false;
                        IncrementIconPlacement(bb.enabled, nodes[i], 1);
                    }
                }
                Commit(iconType, iconType+1);
                // SplinePath update resolution
                if (iconType == ICON_SPLINE_PATH)
                    timeToNextDebugIconsUpdateSplinePath = time.systemTime + stepDebugIconsUpdateSplinePath;
            }
        }
    }
    timeToNextDebugIconsUpdate = time.systemTime + stepDebugIconsUpdate;
}

void ClearCommit(int begin, int end, int newLength)
{
    for (int i = begin; i < end; ++i)
    {
        BillboardSet@ iconSet = debugIconsSet[i];
        iconSet.numBillboards = newLength;

        for (int j = 0; j < newLength; ++j)
        {
            Billboard@ bb = iconSet.billboards[j];
            bb.enabled = false;
        }

        iconSet.Commit();
    }
}

void Commit(int begin, int end)
{
    for (int i = begin; i < end; ++i)
    {
        debugIconsSet[i].Commit();
    }
}

void IncrementIconPlacement(bool componentEnabled, Node@ node, int offset)
{
    if (componentEnabled == true)
    {
        int oldPlacement = debugIconsPlacement[StringHash(node.id)].GetInt();
        debugIconsPlacement[StringHash(node.id)] = Variant(oldPlacement + offset);
    }
}

// Editor debug icons
// to add new std debug icons just add IconType, IconsTypesMaterials and ComponentTypes items

enum IconsTypes
{
    ICON_POINT_LIGHT = 0,
    ICON_SPOT_LIGHT,
    ICON_DIRECTIONAL_LIGHT,
    ICON_CAMERA,
    ICON_SOUND_SOURCE,
    ICON_SOUND_SOURCE_3D,
    ICON_SOUND_LISTENERS,
    ICON_ZONE,
    ICON_SPLINE_PATH,
    ICON_TRIGGER,
    ICON_CUSTOM_GEOMETRY,
    ICON_PARTICLE_EMITTER,
    ICON_COUNT
}

enum IconsColorType
{
    ICON_COLOR_DEFAULT = 0,
    ICON_COLOR_SPLINE_PATH_BEGIN,
    ICON_COLOR_SPLINE_PATH_END
}

Array<Color> debugIconsColors = { Color(1,1,1) , Color(1,1,0), Color(0,1,0) };

Array<String> iconsTypesMaterials = {"DebugIconPointLight.xml",
                                     "DebugIconSpotLight.xml",
                                     "DebugIconLight.xml",
                                     "DebugIconCamera.xml",
                                     "DebugIconSoundSource.xml",
                                     "DebugIconSoundSource.xml",
                                     "DebugIconSoundListener.xml",
                                     "DebugIconZone.xml",
                                     "DebugIconSplinePathPoint.xml",
                                     "DebugIconCollisionTrigger.xml",
                                     "DebugIconCustomGeometry.xml",
                                     "DebugIconParticleEmitter.xml"};

Array<String> componentTypes = {"Light",
                                "Light",
                                "Light",
                                "Camera",
                                "SoundSource",
                                "SoundSource3D",
                                "SoundListener",
                                "Zone",
                                "SplinePath",
                                "RigidBody",
                                "CustomGeometry",
                                "ParticleEmitter"};

Array<BillboardSet@> debugIconsSet(ICON_COUNT);
Node@ debugIconsNode = null;
int stepDebugIconsUpdate = 100; //ms
uint timeToNextDebugIconsUpdate = 0;
int stepDebugIconsUpdateSplinePath = 1000; //ms
uint timeToNextDebugIconsUpdateSplinePath = 0;
const int splinePathResolution = 16;
const float splineStep = 1.0f / splinePathResolution;
bool debugIconsShow = true;
Vector2 debugIconsSize = Vector2(64, 64);
Vector2 debugIconsSizeSmall = debugIconsSize / 1.5;
VariantMap debugIconsPlacement;
const int debugIconsPlacementIndent = 1.0;
const float debugIconsOrthoDistance = 15.0;
const float debugIconAlphaThreshold = 0.1;
const float maxDistance = 50.0;

void CreateDebugIcons(Node@ tempNode)
{
    if (editorScene is null) return;
    debugIconsSet.Resize(ICON_COUNT);
    for (int i = 0; i < ICON_COUNT; ++i)
    {
        debugIconsSet[i] = tempNode.CreateComponent("BillboardSet");
        debugIconsSet[i].material = cache.GetResource("Material", "Materials/Editor/" + iconsTypesMaterials[i]);
        debugIconsSet[i].sorted = true;
        debugIconsSet[i].temporary = true;
        debugIconsSet[i].fixedScreenSize = true;
        debugIconsSet[i].viewMask = 0x80000000;
    }
}

void UpdateViewDebugIcons()
{
    if (editorScene is null || timeToNextDebugIconsUpdate > time.systemTime) return;

    debugIconsNode = editorScene.GetChild("DebugIconsContainer", true);

    if (debugIconsNode is null)
    {
        debugIconsNode = editorScene.CreateChild("DebugIconsContainer", LOCAL);
        debugIconsNode.temporary = true;
    }
    // Checkout if debugIconsNode do not have any BBS component, add all at once
    BillboardSet@ isBSExist = debugIconsNode.GetComponent("BillboardSet");
    if (isBSExist is null)
        CreateDebugIcons(debugIconsNode);

    if (debugIconsSet[ICON_POINT_LIGHT] !is null)
    {
        for (int i = 0; i < ICON_COUNT; ++i)
            debugIconsSet[i].enabled = debugIconsShow;
    }

    if (debugIconsShow == false) return;

    Vector3 camPos = activeViewport.cameraNode.worldPosition;
    bool isOrthographic = activeViewport.camera.orthographic;
    debugIconsPlacement.Clear();

    for (int iconType = 0; iconType < ICON_COUNT; ++iconType)
    {
        if (debugIconsSet[iconType] !is null)
        {
            // SplinePath update resolution
            if (iconType == ICON_SPLINE_PATH && timeToNextDebugIconsUpdateSplinePath > time.systemTime)
                continue;

            Array<Node@> nodes = editorScene.GetChildrenWithComponent(componentTypes[iconType], true);

            // Clear old data
            if (iconType == ICON_SPLINE_PATH)
                ClearCommit(ICON_SPLINE_PATH, ICON_SPLINE_PATH + 1, nodes.length * splinePathResolution);
            else if (iconType == ICON_POINT_LIGHT || iconType == ICON_SPOT_LIGHT || iconType == ICON_DIRECTIONAL_LIGHT)
                ClearCommit(ICON_POINT_LIGHT, ICON_DIRECTIONAL_LIGHT + 1, nodes.length);
            else
                ClearCommit(iconType, iconType + 1, nodes.length);

            if (nodes.length > 0)
            {
                // Fill with new data
                for (uint i = 0; i < nodes.length; ++i)
                {
                    Component@ component = nodes[i].GetComponent(componentTypes[iconType]);
                    if (component is null) continue;

                    Color finalIconColor = debugIconsColors[ICON_COLOR_DEFAULT];
                    float distance = (camPos - nodes[i].worldPosition).length;
                    if (isOrthographic)
                        distance = debugIconsOrthoDistance;
                    int iconsOffset = debugIconsPlacement[StringHash(nodes[i].id)].GetInt();
                    float iconsYPos = 0;

                    if (iconType == ICON_SPLINE_PATH)
                    {
                        SplinePath@ sp = cast<SplinePath>(component);
                        if (sp !is null)
                        {
                            if (sp.length > 0.01f)
                            {
                                for (int step = 0; step < splinePathResolution; step++)
                                {
                                    int index = (i * splinePathResolution) + step;
                                    Vector3 splinePoint = sp.GetPoint(splineStep * step);
                                    Billboard@ bb = debugIconsSet[ICON_SPLINE_PATH].billboards[index];
                                    float stepDistance = (camPos - splinePoint).length;
                                    if (isOrthographic)
                                        stepDistance = debugIconsOrthoDistance;

                                    if (step == 0) // SplinePath start
                                    {
                                        bb.color = debugIconsColors[ICON_COLOR_SPLINE_PATH_BEGIN];
                                        bb.size = debugIconsSize;
                                        bb.position = splinePoint;
                                    }
                                    else if ((step+1) >= (splinePathResolution - splineStep)) // SplinePath end
                                    {
                                        bb.color = debugIconsColors[ICON_COLOR_SPLINE_PATH_END];
                                        bb.size = debugIconsSize;
                                        bb.position = splinePoint;
                                    }
                                    else // SplinePath middle points
                                    {
                                        bb.color = finalIconColor;
                                        bb.size = debugIconsSizeSmall;
                                        bb.position = splinePoint;
                                    }
                                    bb.enabled = sp.enabled;
                                    // Blend Icon relatively by distance to it
                                    bb.color = Color(bb.color.r, bb.color.g, bb.color.b, 1.2f - 1.0f / (maxDistance / stepDistance));
                                    if (bb.color.a < debugIconAlphaThreshold)
                                        bb.enabled = false;
                                }
                            }
                        }
                    }
                    else
                    {
                        Billboard@ bb = debugIconsSet[iconType].billboards[i];

                        if (iconType == ICON_TRIGGER)
                        {
                            RigidBody@ rigidbody = cast<RigidBody>(component);
                            if (rigidbody !is null)
                            {
                                if (rigidbody.trigger == false)
                                    continue;
                            }
                        }
                        else if (iconType == ICON_POINT_LIGHT || iconType == ICON_SPOT_LIGHT || iconType == ICON_DIRECTIONAL_LIGHT)
                        {
                            Light@ light = cast<Light>(component);
                            if (light !is null)
                            {
                                if (light.lightType == LIGHT_POINT)
                                    bb = debugIconsSet[ICON_POINT_LIGHT].billboards[i];
                                else if (light.lightType == LIGHT_DIRECTIONAL)
                                    bb = debugIconsSet[ICON_DIRECTIONAL_LIGHT].billboards[i];
                                else if (light.lightType == LIGHT_SPOT)
                                    bb = debugIconsSet[ICON_SPOT_LIGHT].billboards[i];

                                finalIconColor = light.effectiveColor;
                            }
                        }

                        bb.position = nodes[i].worldPosition;
                        bb.size = debugIconsSize;

                        // Blend Icon relatively by distance to it
                        bb.color = Color(finalIconColor.r, finalIconColor.g, finalIconColor.b, 1.2f - 1.0f / (maxDistance / distance));
                        bb.enabled = component.enabled;
                        // Discard billboard if it almost transparent
                        if (bb.color.a < debugIconAlphaThreshold)
                            bb.enabled = false;
                        IncrementIconPlacement(bb.enabled, nodes[i], 1);
                    }
                }
                Commit(iconType, iconType+1);
                // SplinePath update resolution
                if (iconType == ICON_SPLINE_PATH)
                    timeToNextDebugIconsUpdateSplinePath = time.systemTime + stepDebugIconsUpdateSplinePath;
            }
        }
    }
    timeToNextDebugIconsUpdate = time.systemTime + stepDebugIconsUpdate;
}

void ClearCommit(int begin, int end, int newLength)
{
    for (int i = begin; i < end; ++i)
    {
        BillboardSet@ iconSet = debugIconsSet[i];
        iconSet.numBillboards = newLength;

        for (int j = 0; j < newLength; ++j)
        {
            Billboard@ bb = iconSet.billboards[j];
            bb.enabled = false;
        }

        iconSet.Commit();
    }
}

void Commit(int begin, int end)
{
    for (int i = begin; i < end; ++i)
    {
        debugIconsSet[i].Commit();
    }
}

void IncrementIconPlacement(bool componentEnabled, Node@ node, int offset)
{
    if (componentEnabled == true)
    {
        int oldPlacement = debugIconsPlacement[StringHash(node.id)].GetInt();
        debugIconsPlacement[StringHash(node.id)] = Variant(oldPlacement + offset);
    }
}

Fix behavior of SoundSource debug icons in editor. Closes #1620.


////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.html.beads
{
	import org.apache.flex.core.IStrand;
	import org.apache.flex.html.supportClasses.DataGridColumn;

	/**
	 *  The DataGridColumnView class extends org.apache.flex.html.beads.ListView and
	 *  provides properties to the org.apache.flex.html.List that makes a column in
	 *  the org.apache.flex.html.DataGrid.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	public class DataGridColumnView extends ListView
	{
		/**
		 *  constructor.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function DataGridColumnView()
		{
		}

		private var _strand:IStrand;

		/**
		 *  @copy org.apache.flex.core.IBead#strand
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		override public function set strand(value:IStrand):void
		{
			super.strand = value;
			_strand = value;
		}

		private var _columnIndex:uint;

		/**
		 *  The zero-based index for the column.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get columnIndex():uint
		{
			return _columnIndex;
		}
		public function set columnIndex(value:uint):void
		{
			_columnIndex = value;
		}

		private var _column:DataGridColumn;

		/**
		 *  The org.apache.flex.html.support.DataGridColumn containing information used to
		 *  present the org.apache.flex.html.List as a column in the
		 *  org.apache.flex.html.DataGrid.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get column():DataGridColumn
		{
			return _column;
		}
		public function set column(value:DataGridColumn):void
		{
			_column = value;
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.html.beads
{
	import org.apache.flex.core.IStrand;
	import org.apache.flex.html.supportClasses.DataGridColumn;

	/**
	 *  The DataGridColumnView class extends org.apache.flex.html.beads.ListView and
	 *  provides properties to the org.apache.flex.html.List that makes a column in
	 *  the org.apache.flex.html.DataGrid.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	public class DataGridColumnView extends ListView
	{
		/**
		 *  constructor.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function DataGridColumnView()
		{
		}

		/**
		 *  @copy org.apache.flex.core.IBead#strand
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		override public function set strand(value:IStrand):void
		{
			super.strand = value;
    	}

		private var _columnIndex:uint;

		/**
		 *  The zero-based index for the column.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get columnIndex():uint
		{
			return _columnIndex;
		}
		public function set columnIndex(value:uint):void
		{
			_columnIndex = value;
		}

		private var _column:DataGridColumn;

		/**
		 *  The org.apache.flex.html.support.DataGridColumn containing information used to
		 *  present the org.apache.flex.html.List as a column in the
		 *  org.apache.flex.html.DataGrid.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get column():DataGridColumn
		{
			return _column;
		}
		public function set column(value:DataGridColumn):void
		{
			_column = value;
		}
	}
}

fix asdoc. Falcon didn't notice private override of protected var


package com.kaltura.kdpfl
{
	import com.kaltura.kdpfl.controller.InitMacroCommand;
	import com.kaltura.kdpfl.controller.LayoutReadyCommand;
	import com.kaltura.kdpfl.controller.PlaybackCompleteCommand;
	import com.kaltura.kdpfl.controller.SequenceItemPlayEndCommand;
	import com.kaltura.kdpfl.controller.SequenceSkipNextCommand;
	import com.kaltura.kdpfl.controller.StartupCommand;
	import com.kaltura.kdpfl.controller.media.InitChangeMediaMacroCommand;
	import com.kaltura.kdpfl.controller.media.LiveStreamCommand;
	import com.kaltura.kdpfl.controller.media.MediaReadyCommand;
	import com.kaltura.kdpfl.events.DynamicEvent;
	import com.kaltura.kdpfl.model.ExternalInterfaceProxy;
	import com.kaltura.kdpfl.model.type.DebugLevel;
	import com.kaltura.kdpfl.model.type.NotificationType;
	import com.kaltura.kdpfl.view.controls.KTrace;
	import com.kaltura.kdpfl.view.media.KMediaPlayerMediator;
	import com.kaltura.puremvc.as3.core.KView;

	import flash.display.DisplayObject;

	import mx.utils.ObjectProxy;

	import org.osmf.media.MediaPlayerState;
	import org.puremvc.as3.interfaces.IFacade;
	import org.puremvc.as3.interfaces.IMediator;
	import org.puremvc.as3.interfaces.IProxy;
	import org.puremvc.as3.patterns.facade.Facade;

	public class ApplicationFacade extends Facade implements IFacade
	{
		/**
		 * The current version of the KDP.
		 */
		public var kdpVersion : String = "v3.6.14";

		/**
		 * save any mediator name that is registered to this array in order to delete at any time
		 * (the pure mvc don't support it as built-in function)
		 */
		private var _mediatorNameArray : Array = new Array();
		/**
		 * save any proxy name that is registered to this array in order to delete at any time
		 * (the pure mvc don't support it as built-in function)
		 */
		private var _proxyNameArray : Array = new Array();
		/**
		 * save any notification that create a command name that is registered to this array in order to delete at any time
		 * (the pure mvc don't support it as built-in function)
		 */
		private var _commandNameArray : Array = new Array();

		/**
		 * The bindObject create dynamicly all attributes that need to be binded on it
		 */
		public var bindObject:ObjectProxy = new ObjectProxy();
		/**
		 * a reference to KDP3 main application
		 */
		private var _app : DisplayObject;

		/**
		 * the url of the kdp
		 */
		public var appFolder : String;
		public var debugMode : Boolean = false;
		/**
		 *
		 * will affect the traces that will be sent. See DebugLevel enum
		 */
		public var debugLevel:int;

		private var externalInterface : ExternalInterfaceProxy;

		/**
		 * return the one and only instance of the ApplicationFacade,
		 * if not exist it will be created.
		 * @return
		 *
		 */
		public static function getInstance() : ApplicationFacade
		{
			if (instance == null) instance = new ApplicationFacade();
			return instance as ApplicationFacade;
		}

		/**
		 * All this simply does is fire a notification which is routed to
		 * "StartupCommand" via the "registerCommand" handlers
		 * @param app
		 *
		 */
		public function start(app:DisplayObject):void
		{
			_app = app;
			appFolder = app.root.loaderInfo.url;
			appFolder = appFolder.substr(0, appFolder.lastIndexOf('/') + 1);

			sendNotification(NotificationType.STARTUP, app);
			externalInterface = retrieveProxy(ExternalInterfaceProxy.NAME) as ExternalInterfaceProxy;
		}

		/**
		 * Created to trace all notifications for debug
		 * @param notificationName
		 * @param body
		 * @param type
		 *
		 */
		override public function sendNotification(notificationName:String, body:Object = null, type:String = null):void {
			if (debugMode) {
				var s:String;
				if ((notificationName == NotificationType.BYTES_DOWNLOADED_CHANGE && debugLevel == DebugLevel.HIGH) ||
					(notificationName == NotificationType.PLAYER_UPDATE_PLAYHEAD && (debugLevel == DebugLevel.HIGH || debugLevel == DebugLevel.MEDIUM)) ||
					(notificationName != NotificationType.PLAYER_UPDATE_PLAYHEAD && notificationName != NotificationType.BYTES_DOWNLOADED_CHANGE))
				 {
					if (notificationName == NotificationType.PLAYER_STATE_CHANGE)
						s = 'Sent ' + notificationName + ' ==> ' + body.toString();
					else {
						s = 'Sent ' + notificationName;
						if (body) {
							var found:Boolean = false;
							for (var o:* in body) {
								s += ", " + o + ":" + body[o];
								found = true;
							}
							if (!found) {
								s += ", " + body.toString();
							}
						}
					}
				}

				if (s && s != "null") {
					var curTime:Number = 0;
					var kmediaPlayerMediator:KMediaPlayerMediator = retrieveMediator(KMediaPlayerMediator.NAME) as KMediaPlayerMediator;
					if (kmediaPlayerMediator &&
						kmediaPlayerMediator.player &&
						kmediaPlayerMediator.player.state!=MediaPlayerState.LOADING &&
						kmediaPlayerMediator.player.state!=MediaPlayerState.UNINITIALIZED &&
						kmediaPlayerMediator.player.state!=MediaPlayerState.PLAYBACK_ERROR)
					{
						curTime = kmediaPlayerMediator.player.currentTime;
					}
					var date:Date = new Date();

					KTrace.getInstance().log(date.toTimeString(), ":", s, ", playhead position:", curTime);
				}

			}

			super.sendNotification(notificationName, body, type);
			//For external Flash/Flex application application listening to the KDP events
			_app.dispatchEvent(new DynamicEvent(notificationName, body));

			//For external Javascript application listening to the KDP events
			if (externalInterface)
				externalInterface.notifyJs(notificationName, body);

		}

		/**
		 * controls the routing of notifications to our controllers,
		 * we all know them as commands
		 *
		 */
		override protected function initializeController():void
		{
			super.initializeController();
			registerCommand(NotificationType.STARTUP, StartupCommand);

			// we do both init start KDP life cycle, and start to load the entry simultaneously
			registerCommand(NotificationType.INITIATE_APP, InitMacroCommand);

			//There are several things that need to be done as soon as the layout of the kdp is ready.
			registerCommand(NotificationType.LAYOUT_READY, LayoutReadyCommand );
			//when one call change media we fire the load media command again
			registerCommand(NotificationType.CHANGE_MEDIA, InitChangeMediaMacroCommand);

			registerCommand (NotificationType.LIVE_ENTRY, LiveStreamCommand );

			registerCommand (NotificationType.MEDIA_LOADED, MediaReadyCommand );

			registerCommand (NotificationType.PLAYBACK_COMPLETE, PlaybackCompleteCommand);

			registerCommand(NotificationType.SEQUENCE_ITEM_PLAY_END, SequenceItemPlayEndCommand);

			registerCommand(NotificationType.SEQUENCE_SKIP_NEXT, SequenceSkipNextCommand);
		}

		override protected function initializeView():void
		{
			if ( view != null ) return;
			view = KView.getInstance();
		}

		override protected function initializeFacade():void
		{
			initializeView();
			initializeModel();
			initializeController();
		}

		/**
		 * Help to remove all commands, mediator, proxies from the facade
		 *
		 */
		public function dispose() : void
		{
			var i:int =0;

			for(i=0; i<_commandNameArray.length; i++)
				this.removeCommand( _commandNameArray[i] );

			for(i=0; i<_mediatorNameArray.length; i++)
				this.removeMediator( _mediatorNameArray[i] );

			for(i=0; i<_proxyNameArray.length; i++)
				this.removeProxy( _proxyNameArray[i] );

			_commandNameArray = new Array();
			_mediatorNameArray = new Array();
			_proxyNameArray = new Array();
		}

		/**
		 * after registartion add the notification name to a
		 * @param notificationName
		 * @param commandClassRef
		 *
		 */
		override public function registerCommand(notificationName:String, commandClassRef:Class):void
		{
			super.registerCommand(notificationName, commandClassRef);

			//save the notification name so we can delete it later
			_commandNameArray.push( notificationName );
		}

		override public function registerMediator(mediator:IMediator):void
		{
			super.registerMediator(mediator);

			//save the mediator name so we can delete it later
			_mediatorNameArray.push( mediator.getMediatorName() );
		}

		override public function registerProxy(proxy:IProxy):void
		{
			bindObject[proxy.getProxyName()] = proxy.getData();

			super.registerProxy(proxy);

			//save the proxy name so we can delete it later
			_proxyNameArray.push( proxy.getProxyName() );
		}

		/**
		 * add notification observer for a given mediator
		 * @param notification the notification to listen for
		 * @param notificationHandler handler to be called
		 * @param mediator
		 *
		 */
		public function addNotificationInterest(notification:String, notificationHandler:Function, mediator:IMediator):void {
			(view as KView).addNotificationInterest(notification, notificationHandler, mediator);
		}

		public function get app () : DisplayObject
		{
			return _app;
		}

		public function set app (disObj : DisplayObject) : void
		{
			_app = disObj;
		}

	}
}

package com.kaltura.kdpfl
{
	import com.kaltura.kdpfl.controller.InitMacroCommand;
	import com.kaltura.kdpfl.controller.LayoutReadyCommand;
	import com.kaltura.kdpfl.controller.PlaybackCompleteCommand;
	import com.kaltura.kdpfl.controller.SequenceItemPlayEndCommand;
	import com.kaltura.kdpfl.controller.SequenceSkipNextCommand;
	import com.kaltura.kdpfl.controller.StartupCommand;
	import com.kaltura.kdpfl.controller.media.InitChangeMediaMacroCommand;
	import com.kaltura.kdpfl.controller.media.LiveStreamCommand;
	import com.kaltura.kdpfl.controller.media.MediaReadyCommand;
	import com.kaltura.kdpfl.events.DynamicEvent;
	import com.kaltura.kdpfl.model.ExternalInterfaceProxy;
	import com.kaltura.kdpfl.model.type.DebugLevel;
	import com.kaltura.kdpfl.model.type.NotificationType;
	import com.kaltura.kdpfl.view.controls.KTrace;
	import com.kaltura.kdpfl.view.media.KMediaPlayerMediator;
	import com.kaltura.puremvc.as3.core.KView;

	import flash.display.DisplayObject;

	import mx.utils.ObjectProxy;

	import org.osmf.media.MediaPlayerState;
	import org.puremvc.as3.interfaces.IFacade;
	import org.puremvc.as3.interfaces.IMediator;
	import org.puremvc.as3.interfaces.IProxy;
	import org.puremvc.as3.patterns.facade.Facade;

	public class ApplicationFacade extends Facade implements IFacade
	{
		/**
		 * The current version of the KDP.
		 */
		public var kdpVersion : String = "v3.6.14";

		/**
		 * save any mediator name that is registered to this array in order to delete at any time
		 * (the pure mvc don't support it as built-in function)
		 */
		private var _mediatorNameArray : Array = new Array();
		/**
		 * save any proxy name that is registered to this array in order to delete at any time
		 * (the pure mvc don't support it as built-in function)
		 */
		private var _proxyNameArray : Array = new Array();
		/**
		 * save any notification that create a command name that is registered to this array in order to delete at any time
		 * (the pure mvc don't support it as built-in function)
		 */
		private var _commandNameArray : Array = new Array();

		/**
		 * The bindObject create dynamicly all attributes that need to be binded on it
		 */
		public var bindObject:ObjectProxy = new ObjectProxy();
		/**
		 * a reference to KDP3 main application
		 */
		private var _app : DisplayObject;

		/**
		 * the url of the kdp
		 */
		public var appFolder : String;
		public var debugMode : Boolean = false;
		/**
		 *
		 * will affect the traces that will be sent. See DebugLevel enum
		 */
		public var debugLevel:int;

		private var externalInterface : ExternalInterfaceProxy;

		/**
		 * return the one and only instance of the ApplicationFacade,
		 * if not exist it will be created.
		 * @return
		 *
		 */
		public static function getInstance() : ApplicationFacade
		{
			if (instance == null) instance = new ApplicationFacade();
			return instance as ApplicationFacade;
		}

		/**
		 * All this simply does is fire a notification which is routed to
		 * "StartupCommand" via the "registerCommand" handlers
		 * @param app
		 *
		 */
		public function start(app:DisplayObject):void
		{
			CONFIG::isSDK46 {
				kdpVersion += ".sdk46";
			}

			_app = app;
			appFolder = app.root.loaderInfo.url;
			appFolder = appFolder.substr(0, appFolder.lastIndexOf('/') + 1);

			sendNotification(NotificationType.STARTUP, app);
			externalInterface = retrieveProxy(ExternalInterfaceProxy.NAME) as ExternalInterfaceProxy;
		}

		/**
		 * Created to trace all notifications for debug
		 * @param notificationName
		 * @param body
		 * @param type
		 *
		 */
		override public function sendNotification(notificationName:String, body:Object = null, type:String = null):void {
			if (debugMode) {
				var s:String;
				if ((notificationName == NotificationType.BYTES_DOWNLOADED_CHANGE && debugLevel == DebugLevel.HIGH) ||
					(notificationName == NotificationType.PLAYER_UPDATE_PLAYHEAD && (debugLevel == DebugLevel.HIGH || debugLevel == DebugLevel.MEDIUM)) ||
					(notificationName != NotificationType.PLAYER_UPDATE_PLAYHEAD && notificationName != NotificationType.BYTES_DOWNLOADED_CHANGE))
				 {
					if (notificationName == NotificationType.PLAYER_STATE_CHANGE)
						s = 'Sent ' + notificationName + ' ==> ' + body.toString();
					else {
						s = 'Sent ' + notificationName;
						if (body) {
							var found:Boolean = false;
							for (var o:* in body) {
								s += ", " + o + ":" + body[o];
								found = true;
							}
							if (!found) {
								s += ", " + body.toString();
							}
						}
					}
				}

				if (s && s != "null") {
					var curTime:Number = 0;
					var kmediaPlayerMediator:KMediaPlayerMediator = retrieveMediator(KMediaPlayerMediator.NAME) as KMediaPlayerMediator;
					if (kmediaPlayerMediator &&
						kmediaPlayerMediator.player &&
						kmediaPlayerMediator.player.state!=MediaPlayerState.LOADING &&
						kmediaPlayerMediator.player.state!=MediaPlayerState.UNINITIALIZED &&
						kmediaPlayerMediator.player.state!=MediaPlayerState.PLAYBACK_ERROR)
					{
						curTime = kmediaPlayerMediator.player.currentTime;
					}
					var date:Date = new Date();

					KTrace.getInstance().log(date.toTimeString(), ":", s, ", playhead position:", curTime);
				}

			}

			super.sendNotification(notificationName, body, type);
			//For external Flash/Flex application application listening to the KDP events
			_app.dispatchEvent(new DynamicEvent(notificationName, body));

			//For external Javascript application listening to the KDP events
			if (externalInterface)
				externalInterface.notifyJs(notificationName, body);

		}

		/**
		 * controls the routing of notifications to our controllers,
		 * we all know them as commands
		 *
		 */
		override protected function initializeController():void
		{
			super.initializeController();
			registerCommand(NotificationType.STARTUP, StartupCommand);

			// we do both init start KDP life cycle, and start to load the entry simultaneously
			registerCommand(NotificationType.INITIATE_APP, InitMacroCommand);

			//There are several things that need to be done as soon as the layout of the kdp is ready.
			registerCommand(NotificationType.LAYOUT_READY, LayoutReadyCommand );
			//when one call change media we fire the load media command again
			registerCommand(NotificationType.CHANGE_MEDIA, InitChangeMediaMacroCommand);

			registerCommand (NotificationType.LIVE_ENTRY, LiveStreamCommand );

			registerCommand (NotificationType.MEDIA_LOADED, MediaReadyCommand );

			registerCommand (NotificationType.PLAYBACK_COMPLETE, PlaybackCompleteCommand);

			registerCommand(NotificationType.SEQUENCE_ITEM_PLAY_END, SequenceItemPlayEndCommand);

			registerCommand(NotificationType.SEQUENCE_SKIP_NEXT, SequenceSkipNextCommand);
		}

		override protected function initializeView():void
		{
			if ( view != null ) return;
			view = KView.getInstance();
		}

		override protected function initializeFacade():void
		{
			initializeView();
			initializeModel();
			initializeController();
		}

		/**
		 * Help to remove all commands, mediator, proxies from the facade
		 *
		 */
		public function dispose() : void
		{
			var i:int =0;

			for(i=0; i<_commandNameArray.length; i++)
				this.removeCommand( _commandNameArray[i] );

			for(i=0; i<_mediatorNameArray.length; i++)
				this.removeMediator( _mediatorNameArray[i] );

			for(i=0; i<_proxyNameArray.length; i++)
				this.removeProxy( _proxyNameArray[i] );

			_commandNameArray = new Array();
			_mediatorNameArray = new Array();
			_proxyNameArray = new Array();
		}

		/**
		 * after registartion add the notification name to a
		 * @param notificationName
		 * @param commandClassRef
		 *
		 */
		override public function registerCommand(notificationName:String, commandClassRef:Class):void
		{
			super.registerCommand(notificationName, commandClassRef);

			//save the notification name so we can delete it later
			_commandNameArray.push( notificationName );
		}

		override public function registerMediator(mediator:IMediator):void
		{
			super.registerMediator(mediator);

			//save the mediator name so we can delete it later
			_mediatorNameArray.push( mediator.getMediatorName() );
		}

		override public function registerProxy(proxy:IProxy):void
		{
			bindObject[proxy.getProxyName()] = proxy.getData();

			super.registerProxy(proxy);

			//save the proxy name so we can delete it later
			_proxyNameArray.push( proxy.getProxyName() );
		}

		/**
		 * add notification observer for a given mediator
		 * @param notification the notification to listen for
		 * @param notificationHandler handler to be called
		 * @param mediator
		 *
		 */
		public function addNotificationInterest(notification:String, notificationHandler:Function, mediator:IMediator):void {
			(view as KView).addNotificationInterest(notification, notificationHandler, mediator);
		}

		public function get app () : DisplayObject
		{
			return _app;
		}

		public function set app (disObj : DisplayObject) : void
		{
			_app = disObj;
		}

	}
}

add ".sdk46" to sdk 4.6 client tag

qnd: add ".sdk46" to sdk 4.6 client tag

git-svn-id: 3f608e5a9a704dd448217c0a64c508e7f145cfa1@91631 6b8eccd3-e8c5-4e7d-8186-e12b5326b719


package weavejs.data.source
{
	import weavejs.WeaveAPI;
	import weavejs.api.data.ColumnMetadata;
	import weavejs.api.data.IDataSource;
	import weavejs.api.data.IQualifiedKey;
	import weavejs.api.data.ISelectableAttributes;
	import weavejs.core.LinkableString;
	import weavejs.data.ColumnUtils;
	import weavejs.data.column.DynamicColumn;
	import weavejs.data.column.ProxyColumn;
	import weavejs.data.column.StringColumn;
	import weavejs.util.ArrayUtils;
	import weavejs.util.JS;
	import weavejs.util.StandardLib;

	public class SpatialJoinTransform extends AbstractDataSource implements ISelectableAttributes
	{
		WeaveAPI.ClassRegistry.registerImplementation(IDataSource, SpatialJoinTransform, "Spatial Join Transform");

		public const geometryColumn:DynamicColumn = Weave.linkableChild(this, DynamicColumn);
		public const xColumn:DynamicColumn = Weave.linkableChild(this, DynamicColumn);
		public const yColumn:DynamicColumn = Weave.linkableChild(this, DynamicColumn);
		public const pointProjection:LinkableString = Weave.linkableChild(this, LinkableString);
		private var _source:Object; /* This is a ol.source.Vector */
		private var _parser:Object; /* This is an ol.format.GeoJSON */

		/* Output dataType is determined by the geometryColumn input. */
		/* Output keyType is determined by the xColumn/yColumn input. */

		public function get selectableAttributes():/*/Map<string, (weavejs.api.data.IColumnWrapper|weavejs.api.core.ILinkableHashMap)>/*/Object
		{
			return new JS.Map()
				.set("Join Geometry", geometryColumn)
				.set("Datapoint X", xColumn)
				.set("Datapoint Y", yColumn);
		}

		public function SpatialJoinTransform()
		{
			_source = new StandardLib.ol.source.Vector()
			_parser = new StandardLib.ol.format.GeoJSON();
		}

		override protected function initialize(forceRefresh:Boolean = false):void
		{
			super.initialize(true);
		}

		override protected function requestColumnFromSource(proxyColumn:ProxyColumn):void
		{
			var metadata:Object = proxyColumn.getProxyMetadata();

			var geomKeys:Array = geometryColumn.keys;
			var rawGeometries:Array = weavejs.data.ColumnUtils.getGeoJsonGeometries(geometryColumn, geometryColumn.keys);
			var key:IQualifiedKey;
			var feature:*;

			_source.clear();

			for (var idx:int = 0; idx < geomKeys.length; idx++)
			{
				var rawGeom:* = rawGeometries[idx];
				key = geomKeys[idx] as IQualifiedKey;

				var geometry:* = _parser.readGeometry(rawGeom,
					{
						dataProjection: StandardLib.ol.proj.get(geometryColumn.getMetadata(ColumnMetadata.PROJECTION)),
						featureProjection: StandardLib.ol.proj.get(pointProjection.value)
					}
				);

				if (geometry.getExtent().some(StandardLib.lodash.isNaN))
				{
					JS.error("Dropping feature", key, "due to containing NaN coordinates. Possibly misconfigured projection?");
					continue;
				}

				feature = new StandardLib.ol.Feature({id: key, geometry: geometry});
				_source.addFeature(feature);
			}

			var keys:Array = [];
			var data:Array = [];
			for each (key in ArrayUtils.union(xColumn.keys, yColumn.keys))
			{
				var x:Number = xColumn.getValueFromKey(key, Number);
				var y:Number = yColumn.getValueFromKey(key, Number);

				var features:Array = _source.getFeaturesAtCoordinate([x,y]);

				for each (feature in features)
				{
					var featureKey:* = feature.getId();
					keys.push(key);
					data.push(featureKey.localName);
				}
			}

			var column:StringColumn = new StringColumn();
			column.setRecords(keys, data);
			proxyColumn.setInternalColumn(column);
		}
	}
}

package weavejs.data.source
{
	import weavejs.WeaveAPI;
	import weavejs.api.data.ColumnMetadata;
	import weavejs.api.data.IDataSource;
	import weavejs.api.data.IQualifiedKey;
	import weavejs.api.data.ISelectableAttributes;
	import weavejs.api.data.IWeaveTreeNode;
	import weavejs.core.LinkableString;
	import weavejs.data.ColumnUtils;
	import weavejs.data.column.DynamicColumn;
	import weavejs.data.column.ProxyColumn;
	import weavejs.data.column.StringColumn;
	import weavejs.data.hierarchy.ColumnTreeNode;
	import weavejs.util.ArrayUtils;
	import weavejs.util.JS;
	import weavejs.util.StandardLib;

	public class SpatialJoinTransform extends AbstractDataSource implements ISelectableAttributes
	{
		WeaveAPI.ClassRegistry.registerImplementation(IDataSource, SpatialJoinTransform, "Spatial Join Transform");

		public const geometryColumn:DynamicColumn = Weave.linkableChild(this, DynamicColumn);
		public const xColumn:DynamicColumn = Weave.linkableChild(this, DynamicColumn);
		public const yColumn:DynamicColumn = Weave.linkableChild(this, DynamicColumn);
		public const pointProjection:LinkableString = Weave.linkableChild(this, LinkableString);
		private var _source:Object; /* This is a ol.source.Vector */
		private var _parser:Object; /* This is an ol.format.GeoJSON */

		/* Output dataType is determined by the geometryColumn input. */
		/* Output keyType is determined by the xColumn/yColumn input. */

		public function get selectableAttributes():/*/Map<string, (weavejs.api.data.IColumnWrapper|weavejs.api.core.ILinkableHashMap)>/*/Object
		{
			return new JS.Map()
				.set("Join Geometry", geometryColumn)
				.set("Datapoint X", xColumn)
				.set("Datapoint Y", yColumn);
		}

		public function SpatialJoinTransform()
		{
			_source = new StandardLib.ol.source.Vector();
			_parser = new StandardLib.ol.format.GeoJSON();
		}

		override protected function initialize(forceRefresh:Boolean = false):void
		{
			super.initialize(true);
		}

		override public function getHierarchyRoot():IWeaveTreeNode
		{
			if (!_rootNode)
			{
				_rootNode = new ColumnTreeNode({
					dataSource: this,
					data: this,
					label: getLabel,
					hasChildBranches: false,
					children: [
						generateHierarchyNode({})
					]
				});
			}
			return _rootNode;
		}

		override protected function generateHierarchyNode(metadata:Object):IWeaveTreeNode
		{
			metadata[ColumnMetadata.TITLE] = ColumnUtils.getTitle(this.geometryColumn)
			metadata[ColumnMetadata.KEY_TYPE] = this.xColumn.getMetadata(ColumnMetadata.KEY_TYPE);
			metadata[ColumnMetadata.DATA_TYPE] = this.geometryColumn.getMetadata(ColumnMetadata.KEY_TYPE);
			return new ColumnTreeNode({
				dataSource: this,
				idFields: [],
				data: metadata
			});
		}

		override protected function requestColumnFromSource(proxyColumn:ProxyColumn):void
		{
			var metadata:Object = proxyColumn.getProxyMetadata();

			var geomKeys:Array = geometryColumn.keys;
			var rawGeometries:Array = weavejs.data.ColumnUtils.getGeoJsonGeometries(geometryColumn, geometryColumn.keys);
			var key:IQualifiedKey;
			var feature:*;

			_source.clear();

			for (var idx:int = 0; idx < geomKeys.length; idx++)
			{
				var rawGeom:* = rawGeometries[idx];
				key = geomKeys[idx] as IQualifiedKey;

				var geometry:* = _parser.readGeometry(rawGeom,
					{
						dataProjection: StandardLib.ol.proj.get(geometryColumn.getMetadata(ColumnMetadata.PROJECTION)),
						featureProjection: StandardLib.ol.proj.get(pointProjection.value)
					}
				);

				if (geometry.getExtent().some(StandardLib.lodash.isNaN))
				{
					JS.error("Dropping feature", key, "due to containing NaN coordinates. Possibly misconfigured projection?");
					continue;
				}

				feature = new StandardLib.ol.Feature(geometry);
				feature.setId(key);
				_source.addFeature(feature);
			}

			var keys:Array = [];
			var data:Array = [];
			for each (key in ArrayUtils.union(xColumn.keys, yColumn.keys))
			{
				var x:Number = xColumn.getValueFromKey(key, Number);
				var y:Number = yColumn.getValueFromKey(key, Number);

				var features:Array = _source.getFeaturesAtCoordinate([x,y]);

				for each (feature in features)
				{
					var featureKey:* = feature.getId();
					keys.push(key);
					data.push(featureKey.localName);
				}
			}

			var column:StringColumn = new StringColumn(metadata);

			column.setRecords(keys, data);
			proxyColumn.setInternalColumn(column);
		}
	}
}

Add hierarchy generation to SpatialJoinTransform


//
// $Id$
//
// Vilya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/vilya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.ezgame.client {

import mx.core.UIComponent;
import mx.controls.CheckBox;
import mx.controls.ComboBox;
import mx.controls.HSlider;
import mx.controls.Label;

import com.threerings.util.StreamableHashMap;
import com.threerings.util.StringUtil;

import com.threerings.flex.LabeledSlider;

import com.threerings.parlor.game.client.FlexGameConfigurator;

import com.threerings.ezgame.data.ChoiceParameter;
import com.threerings.ezgame.data.EZGameConfig;
import com.threerings.ezgame.data.Parameter;
import com.threerings.ezgame.data.RangeParameter;
import com.threerings.ezgame.data.ToggleParameter;

/**
 * Adds custom configuration of options specified in XML.
 */
public class EZGameConfigurator extends FlexGameConfigurator
{
    // from GameConfigurator
    override protected function gotGameConfig () :void
    {
        super.gotGameConfig();

        var params :Array = (_config as EZGameConfig).getGameDefinition().params;
        if (params == null) {
            return;
        }

        for each (var param :Parameter in params) {
            if (param is RangeParameter) {
                var range :RangeParameter = (param as RangeParameter);
                var slider :HSlider = new HSlider();
                slider.minimum = range.minimum;
                slider.maximum = range.maximum;
                slider.value = range.start;
                slider.liveDragging = true;
                slider.snapInterval = 1;
                addLabeledControl(param, new LabeledSlider(slider));

            } else if (param is ChoiceParameter) {
                var choice :ChoiceParameter = (param as ChoiceParameter);
                var startDex :int = choice.choices.indexOf(choice.start);
                if (startDex == -1) {
                    Log.getLog(this).warning(
                        "Start value does not appear in list of choices [param=" + choice + "].");
                } else {
                    var combo :ComboBox = new ComboBox();
                    combo.dataProvider = choice.choices;
                    combo.selectedIndex = startDex;
                    addLabeledControl(param, combo);
                }

            } else if (param is ToggleParameter) {
                var check :CheckBox = new CheckBox();
                check.selected = (param as ToggleParameter).start;
                addLabeledControl(param, check);

            } else {
                Log.getLog(this).warning("Unknown parameter in config [param=" + param + "].");
            }
        }
    }

    override protected function flushGameConfig () :void
    {
        super.flushGameConfig();

        // if there were any custom XML configs, flush those as well.
        if (_customConfigs.length > 0) {
            var params :StreamableHashMap = new StreamableHashMap();

            for (var ii :int = 0; ii < _customConfigs.length; ii += 2) {
                var ident :String = String(_customConfigs[ii]);
                var control :UIComponent = (_customConfigs[ii + 1] as UIComponent);
                if (control is LabeledSlider) {
                    params.put(ident, (control as LabeledSlider).slider.value);

                } else if (control is CheckBox) {
                    params.put(ident, (control as CheckBox).selected);

                } else if (control is ComboBox) {
                    params.put(ident, (control as ComboBox).value);

                } else {
                    Log.getLog(this).warning("Unknow custom config type " + control);
                }
            }

            (_config as EZGameConfig).params = params;
        }
    }

    /**
     * Add a control that came from parsing our custom option XML.
     */
    protected function addLabeledControl (param :Parameter, control :UIComponent) :void
    {
        if (StringUtil.isBlank(param.name)) {
            param.name = param.ident;
        }

        var lbl :Label = new Label();
        lbl.text = param.name + ":";
        lbl.styleName = "lobbyLabel";
        lbl.toolTip = param.tip;
        control.toolTip = param.tip;

        addControl(lbl, control);
        _customConfigs.push(param.ident, control);
    }

    /** Contains pairs of identString, control, identString, control.. */
    protected var _customConfigs :Array = [];
}
}

//
// $Id$
//
// Vilya library - tools for developing networked games
// Copyright (C) 2002-2007 Three Rings Design, Inc., All Rights Reserved
// http://www.threerings.net/code/vilya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.ezgame.client {

import mx.core.UIComponent;
import mx.controls.CheckBox;
import mx.controls.ComboBox;
import mx.controls.HSlider;
import mx.controls.Label;

import com.threerings.util.Integer;
import com.threerings.util.StreamableHashMap;
import com.threerings.util.StringUtil;

import com.threerings.flex.LabeledSlider;

import com.threerings.parlor.game.client.FlexGameConfigurator;

import com.threerings.ezgame.data.ChoiceParameter;
import com.threerings.ezgame.data.EZGameConfig;
import com.threerings.ezgame.data.Parameter;
import com.threerings.ezgame.data.RangeParameter;
import com.threerings.ezgame.data.ToggleParameter;

/**
 * Adds custom configuration of options specified in XML.
 */
public class EZGameConfigurator extends FlexGameConfigurator
{
    // from GameConfigurator
    override protected function gotGameConfig () :void
    {
        super.gotGameConfig();

        var params :Array = (_config as EZGameConfig).getGameDefinition().params;
        if (params == null) {
            return;
        }

        for each (var param :Parameter in params) {
            if (param is RangeParameter) {
                var range :RangeParameter = (param as RangeParameter);
                var slider :HSlider = new HSlider();
                slider.minimum = range.minimum;
                slider.maximum = range.maximum;
                slider.value = range.start;
                slider.liveDragging = true;
                slider.snapInterval = 1;
                addLabeledControl(param, new LabeledSlider(slider));

            } else if (param is ChoiceParameter) {
                var choice :ChoiceParameter = (param as ChoiceParameter);
                var startDex :int = choice.choices.indexOf(choice.start);
                if (startDex == -1) {
                    Log.getLog(this).warning(
                        "Start value does not appear in list of choices [param=" + choice + "].");
                } else {
                    var combo :ComboBox = new ComboBox();
                    combo.dataProvider = choice.choices;
                    combo.selectedIndex = startDex;
                    addLabeledControl(param, combo);
                }

            } else if (param is ToggleParameter) {
                var check :CheckBox = new CheckBox();
                check.selected = (param as ToggleParameter).start;
                addLabeledControl(param, check);

            } else {
                Log.getLog(this).warning("Unknown parameter in config [param=" + param + "].");
            }
        }
    }

    override protected function flushGameConfig () :void
    {
        super.flushGameConfig();

        // if there were any custom XML configs, flush those as well.
        if (_customConfigs.length > 0) {
            var params :StreamableHashMap = new StreamableHashMap();

            for (var ii :int = 0; ii < _customConfigs.length; ii += 2) {
                var ident :String = String(_customConfigs[ii]);
                var control :UIComponent = (_customConfigs[ii + 1] as UIComponent);
                if (control is LabeledSlider) {
                    params.put(ident, new Integer((control as LabeledSlider).slider.value));

                } else if (control is CheckBox) {
                    params.put(ident, (control as CheckBox).selected);

                } else if (control is ComboBox) {
                    params.put(ident, (control as ComboBox).value);

                } else {
                    Log.getLog(this).warning("Unknow custom config type " + control);
                }
            }

            (_config as EZGameConfig).params = params;
        }
    }

    /**
     * Add a control that came from parsing our custom option XML.
     */
    protected function addLabeledControl (param :Parameter, control :UIComponent) :void
    {
        if (StringUtil.isBlank(param.name)) {
            param.name = param.ident;
        }

        var lbl :Label = new Label();
        lbl.text = param.name + ":";
        lbl.styleName = "lobbyLabel";
        lbl.toolTip = param.tip;
        control.toolTip = param.tip;

        addControl(lbl, control);
        _customConfigs.push(param.ident, control);
    }

    /** Contains pairs of identString, control, identString, control.. */
    protected var _customConfigs :Array = [];
}
}

Use an Integer here so that we play nicely with Java managers.

git-svn-id: a3e1eb16dde062992de22c830ed8045c8013209a@289 c613c5cb-e716-0410-b11b-feb51c14d237


package aerys.minko.render.shader.node.leaf
{
	import aerys.minko.render.shader.compiler.visitor.IShaderNodeVisitor;
	import aerys.minko.render.shader.node.INode;

	import flash.utils.getQualifiedClassName;

	public class AbstractLeaf implements INode
	{
		public function get name() : String
		{
			return getQualifiedClassName(this);
		}

		public function get size() : uint
		{
			throw new Error('Must be overriden');
		}

		public function AbstractLeaf()
		{
		}

		public function accept(v : IShaderNodeVisitor) : void
		{
		}

		public function isSame(node : INode) : Boolean
		{
			throw new Error('Must be overriden');
		}

		public function toString() : String
		{
			return name;
		}
	}
}

package aerys.minko.render.shader.node.leaf
{
	import aerys.minko.render.shader.compiler.visitor.IShaderNodeVisitor;
	import aerys.minko.render.shader.node.INode;

	import flash.utils.getQualifiedClassName;

	public class AbstractLeaf implements INode
	{
		public function get name() : String
		{
			var className : String = getQualifiedClassName(this);
			return className.substr(className.lastIndexOf(":") + 1);
		}

		public function get size() : uint
		{
			throw new Error('Must be overriden');
		}

		public function AbstractLeaf()
		{
		}

		public function accept(v : IShaderNodeVisitor) : void
		{
		}

		public function isSame(node : INode) : Boolean
		{
			throw new Error('Must be overriden');
		}

		public function toString() : String
		{
			return name;
		}
	}
}

Remove the package name from the name getter in AbstractLeaf


////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.createjs
{
	import org.apache.flex.core.ApplicationBase;
	import org.apache.flex.core.IApplicationView;
	import org.apache.flex.core.IParent;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.IValuesImpl;
	import org.apache.flex.core.ValuesManager;
	import org.apache.flex.events.Event;
	import org.apache.flex.events.IEventDispatcher;
    import org.apache.flex.utils.MXMLDataInterpreter;

    COMPILE::JS
    {
        import org.apache.flex.core.WrappedHTMLElement;
        import createjs.DisplayObject;
        import createjs.Stage;
    }

	//--------------------------------------
	//  Events
	//--------------------------------------

	/**
	 *  Dispatched at startup. Attributes and sub-instances of
	 *  the MXML document have been created and assigned.
	 *  The component lifecycle is different
	 *  than the Flex SDK.  There is no creationComplete event.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	[Event(name="initialize", type="org.apache.flex.events.Event")]

	/**
	 *  Dispatched at startup before the instances get created.
	 *  Beads can call preventDefault and defer initialization.
	 *  This event will be dispatched on every frame until no
	 *  listeners call preventDefault(), then the initialize()
	 *  method will be called.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	[Event(name="preinitialize", type="org.apache.flex.events.Event")]

	/**
	 *  Dispatched at startup after the initial view has been
	 *  put on the display list. This event is sent before
	 *  applicationComplete is dispatched.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	[Event(name="viewChanged", type="org.apache.flex.events.Event")]

	/**
	 *  Dispatched at startup after the initial view has been
	 *  put on the display list.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	[Event(name="applicationComplete", type="org.apache.flex.events.Event")]
	/**
	 *  The Application class is the main class and entry point for a FlexJS
	 *  application.  This Application class is different than the
	 *  Flex SDK's mx:Application or spark:Application in that it does not contain
	 *  user interface elements.  Those UI elements go in the views (ViewBase).  This
	 *  Application class expects there to be a main model, a controller, and
	 *  an initial view.
	 *
     * This is the CreateJS Application class which must be used in place of the normal
	 * FlexJS Application. CreateJS uses the HTML5 <canvas>, rather than the HTML DOM. This
	 * class sets up the canvas and injects the necessary HTML elements into the index.html
	 * file to bootstrap CreateJS.
	 *
	 *  @see ViewBase
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */

	COMPILE::SWF
	public class Application extends org.apache.flex.core.Application
	{
		// does nothing different for SWF side
	}

	COMPILE::JS
	public class Application extends ApplicationBase implements IStrand, IParent, IEventDispatcher
	{
        /**
         * FalconJX will inject html into the index.html file.  Surround with
         * "inject_html" tag as follows:
         *
         * <inject_html>
         * <script src="https://code.createjs.com/easeljs-0.8.1.min.js"></script>
		 * <script src="https://code.createjs.com/tweenjs-0.6.2.min.js"></script>
         * </inject_html>
         */
		public function Application()
		{
			super();
		}

        private var stage:Stage;

        /**
		 * @private
         * @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement
         * @flexjsignorecoercion HTMLBodyElement
         * @flexjsignorecoercion HTMLCanvasElement
         * @flexjsignorecoercion createjs.Stage
         */
		public function start():void
        {
            var body:HTMLBodyElement;
            var canvas:HTMLCanvasElement;

            // For createjs, the application is the same as the canvas
            // and it provides convenient access to the stage.

            element = document.createElement('canvas') as WrappedHTMLElement;
            element.flexjs_wrapper = this;
            canvas = element as HTMLCanvasElement;
            canvas.id = 'flexjsCanvas';
            canvas.width = 700;
            canvas.height = 500;

            body = document.getElementsByTagName('body')[0] as HTMLBodyElement;
            body.appendChild(this.element);

            stage = new createjs.Stage('flexjsCanvas');

			MXMLDataInterpreter.generateMXMLInstances(this, null, MXMLDescriptor);

            dispatchEvent('initialize');

			for (var index:int in beads) {
				addBead(beads[index]);
			}

			dispatchEvent(new org.apache.flex.events.Event("beadsAdded"));

            initialView.applicationModel = this.model;
            addElement(initialView);

            dispatchEvent('viewChanged');

            stage.update();

			dispatchEvent('applicationComplete');
        }

		/**
		 *  The org.apache.flex.core.IValuesImpl that will
		 *  determine the default values and other values
		 *  for the application.  The most common choice
		 *  is org.apache.flex.core.SimpleCSSValuesImpl.
		 *
		 *  @see org.apache.flex.core.SimpleCSSValuesImpl
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function set valuesImpl(value:IValuesImpl):void
		{
			ValuesManager.valuesImpl = value;
			ValuesManager.valuesImpl.init(this);
		}

		/**
		 *  The initial view.
		 *
		 *  @see org.apache.flex.core.ViewBase
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		[Bindable("__NoChangeEvent__")]
		public var initialView:IApplicationView;

		/**
		 *  The data model (for the initial view).
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		[Bindable("__NoChangeEvent__")]
		private var _model:Object;

		/**
		 *  The data model (for the initial view).
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		[Bindable("__NoChangeEvent__")]
		override public function get model():Object
		{
			return _model;
		}

		/**
		 *  @private
		 */
		[Bindable("__NoChangeEvent__")]
		override public function set model(value:Object):void
		{
			_model = value;
		}

		/**
		 *  The controller.  The controller typically watches
		 *  the UI for events and updates the model accordingly.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public var controller:Object;

		/**
		 *  An array of data that describes the MXML attributes
		 *  and tags in an MXML document.  This data is usually
		 *  decoded by an MXMLDataInterpreter
		 *
		 *  @see org.apache.flex.utils.MXMLDataInterpreter
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get MXMLDescriptor():Array
		{
			return null;
		}

		/**
		 *  An method called by the compiler's generated
		 *  code to kick off the setting of MXML attribute
		 *  values and instantiation of child tags.
		 *
		 *  The call has to be made in the generated code
		 *  in order to ensure that the constructors have
		 *  completed first.
		 *
		 *  @param data The encoded data representing the
		 *  MXML attributes.
		 *
		 *  @see org.apache.flex.utils.MXMLDataInterpreter
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function generateMXMLAttributes(data:Array):void
		{
			MXMLDataInterpreter.generateMXMLProperties(this, data);
		}

		/**
		 *  The array property that is used to add additional
		 *  beads to an MXML tag.  From ActionScript, just
		 *  call addBead directly.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public var beads:Array;

		/**
		 *  @copy org.apache.flex.core.IParent#addElement()
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
         *  @flexjsignorecoercion createjs.DisplayObject
		 */
		public function addElement(c:Object, dispatchEvent:Boolean = true):void
		{
			stage.addChild(c.element as DisplayObject);
			c.addedToParent();
		}

		/**
		 *  @copy org.apache.flex.core.IParent#addElementAt()
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
         *  @flexjsignorecoercion createjs.DisplayObject
		 */
		public function addElementAt(c:Object, index:int, dispatchEvent:Boolean = true):void
		{
			stage.addChildAt(c.element as DisplayObject, index);
			c.addedToParent();
		}

		/**
		 *  @copy org.apache.flex.core.IParent#getElementAt()
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
         *  @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement
		 */
		public function getElementAt(index:int):Object
		{
			var c:WrappedHTMLElement = stage.getChildAt(index) as WrappedHTMLElement;
			return c.flexjs_wrapper;
		}

		/**
		 *  @copy org.apache.flex.core.IParent#getElementIndex()
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
         *  @flexjsignorecoercion createjs.DisplayObject
		 */
		public function getElementIndex(c:Object):int
		{
			return stage.getChildIndex(c.element as DisplayObject)
		}

		/**
		 *  @copy org.apache.flex.core.IParent#removeElement()
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function removeElement(c:Object, dispatchEvent:Boolean = true):void
		{
			stage.removeChild(c.element as DisplayObject);
		}

		/**
		 *  @copy org.apache.flex.core.IParent#numElements
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get numElements():int
		{
			return stage.numChildren();
		}
	}
}

////////////////////////////////////////////////////////////////////////////////
//
//  Licensed to the Apache Software Foundation (ASF) under one or more
//  contributor license agreements.  See the NOTICE file distributed with
//  this work for additional information regarding copyright ownership.
//  The ASF licenses this file to You under the Apache License, Version 2.0
//  (the "License"); you may not use this file except in compliance with
//  the License.  You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
//  Unless required by applicable law or agreed to in writing, software
//  distributed under the License is distributed on an "AS IS" BASIS,
//  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
//  See the License for the specific language governing permissions and
//  limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package org.apache.flex.createjs
{
	import org.apache.flex.core.ApplicationBase;
	import org.apache.flex.core.IApplicationView;
	import org.apache.flex.core.IParent;
	import org.apache.flex.core.IStrand;
	import org.apache.flex.core.IValuesImpl;
	import org.apache.flex.core.ValuesManager;
	import org.apache.flex.events.Event;
	import org.apache.flex.events.IEventDispatcher;
    import org.apache.flex.utils.MXMLDataInterpreter;

    COMPILE::JS
    {
        import org.apache.flex.core.WrappedHTMLElement;
        import createjs.DisplayObject;
        import createjs.Stage;
    }

	//--------------------------------------
	//  Events
	//--------------------------------------

	/**
	 *  Dispatched at startup. Attributes and sub-instances of
	 *  the MXML document have been created and assigned.
	 *  The component lifecycle is different
	 *  than the Flex SDK.  There is no creationComplete event.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	[Event(name="initialize", type="org.apache.flex.events.Event")]

	/**
	 *  Dispatched at startup before the instances get created.
	 *  Beads can call preventDefault and defer initialization.
	 *  This event will be dispatched on every frame until no
	 *  listeners call preventDefault(), then the initialize()
	 *  method will be called.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	[Event(name="preinitialize", type="org.apache.flex.events.Event")]

	/**
	 *  Dispatched at startup after the initial view has been
	 *  put on the display list. This event is sent before
	 *  applicationComplete is dispatched.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	[Event(name="viewChanged", type="org.apache.flex.events.Event")]

	/**
	 *  Dispatched at startup after the initial view has been
	 *  put on the display list.
	 *
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */
	[Event(name="applicationComplete", type="org.apache.flex.events.Event")]
	/**
	 *  The Application class is the main class and entry point for a FlexJS
	 *  application.  This Application class is different than the
	 *  Flex SDK's mx:Application or spark:Application in that it does not contain
	 *  user interface elements.  Those UI elements go in the views (ViewBase).  This
	 *  Application class expects there to be a main model, a controller, and
	 *  an initial view.
	 *
     * This is the CreateJS Application class which must be used in place of the normal
	 * FlexJS Application. CreateJS uses the HTML5 <canvas>, rather than the HTML DOM. This
	 * class sets up the canvas and injects the necessary HTML elements into the index.html
	 * file to bootstrap CreateJS.
	 *
	 *  @see ViewBase
	 *  @langversion 3.0
	 *  @playerversion Flash 10.2
	 *  @playerversion AIR 2.6
	 *  @productversion FlexJS 0.0
	 */

	COMPILE::SWF
	public class Application extends org.apache.flex.core.Application
	{
		// does nothing different for SWF side
	}

	COMPILE::JS
	public class Application extends ApplicationBase implements IStrand, IParent, IEventDispatcher
	{
        /**
         * FalconJX will inject html into the index.html file.  Surround with
         * "inject_html" tag as follows:
         *
         * <inject_html>
         * <script src="https://code.createjs.com/easeljs-0.8.1.min.js"></script>
		 * <script src="https://code.createjs.com/tweenjs-0.6.2.min.js"></script>
         * </inject_html>
         */
		public function Application()
		{
			super();
		}

        private var stage:Stage;

        /**
		 * @private
         * @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement
         * @flexjsignorecoercion HTMLBodyElement
         * @flexjsignorecoercion HTMLCanvasElement
         * @flexjsignorecoercion createjs.Stage
         */
		public function start():void
        {
            var body:HTMLBodyElement;
            var canvas:HTMLCanvasElement;

            // For createjs, the application is the same as the canvas
            // and it provides convenient access to the stage.

            element = document.createElement('canvas') as WrappedHTMLElement;
            element.flexjs_wrapper = this;
            canvas = element as HTMLCanvasElement;
            canvas.id = 'flexjsCanvas';
            canvas.width = 700;
            canvas.height = 500;

            body = document.getElementsByTagName('body')[0] as HTMLBodyElement;
            body.appendChild(this.element);

            stage = new createjs.Stage('flexjsCanvas');

			MXMLDataInterpreter.generateMXMLInstances(this, null, MXMLDescriptor);

            dispatchEvent('initialize');

			for (var index:int in beads) {
				addBead(beads[index]);
			}

			dispatchEvent(new org.apache.flex.events.Event("beadsAdded"));

            initialView.applicationModel = this.model;
            addElement(initialView);

            dispatchEvent('viewChanged');

            stage.update();

			dispatchEvent('applicationComplete');
        }

		/**
		 *  The org.apache.flex.core.IValuesImpl that will
		 *  determine the default values and other values
		 *  for the application.  The most common choice
		 *  is org.apache.flex.core.SimpleCSSValuesImpl.
		 *
		 *  @see org.apache.flex.core.SimpleCSSValuesImpl
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function set valuesImpl(value:IValuesImpl):void
		{
			ValuesManager.valuesImpl = value;
			ValuesManager.valuesImpl.init(this);
		}

		/**
		 *  The initial view.
		 *
		 *  @see org.apache.flex.core.ViewBase
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		[Bindable("__NoChangeEvent__")]
		public var initialView:IApplicationView;

		/**
		 *  The data model (for the initial view).
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		[Bindable("__NoChangeEvent__")]
		private var _model:Object;

		/**
		 *  The data model (for the initial view).
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		[Bindable("__NoChangeEvent__")]
		override public function get model():Object
		{
			return _model;
		}

		/**
		 *  @private
		 */
		[Bindable("__NoChangeEvent__")]
		override public function set model(value:Object):void
		{
			_model = value;
		}

		/**
		 *  The controller.  The controller typically watches
		 *  the UI for events and updates the model accordingly.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public var controller:Object;

		/**
		 *  An array of data that describes the MXML attributes
		 *  and tags in an MXML document.  This data is usually
		 *  decoded by an MXMLDataInterpreter
		 *
		 *  @see org.apache.flex.utils.MXMLDataInterpreter
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get MXMLDescriptor():Array
		{
			return null;
		}

		/**
		 *  An method called by the compiler's generated
		 *  code to kick off the setting of MXML attribute
		 *  values and instantiation of child tags.
		 *
		 *  The call has to be made in the generated code
		 *  in order to ensure that the constructors have
		 *  completed first.
		 *
		 *  @param data The encoded data representing the
		 *  MXML attributes.
		 *
		 *  @see org.apache.flex.utils.MXMLDataInterpreter
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function generateMXMLAttributes(data:Array):void
		{
			MXMLDataInterpreter.generateMXMLProperties(this, data);
		}

		/**
		 *  The array property that is used to add additional
		 *  beads to an MXML tag.  From ActionScript, just
		 *  call addBead directly.
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public var beads:Array;

		/**
		 *  @copy org.apache.flex.core.IParent#addElement()
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
         *  @flexjsignorecoercion createjs.DisplayObject
		 */
		public function addElement(c:Object, dispatchEvent:Boolean = true):void
		{
			stage.addChild(c.element as DisplayObject);
			c.addedToParent();
		}

		/**
		 *  @copy org.apache.flex.core.IParent#addElementAt()
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
         *  @flexjsignorecoercion createjs.DisplayObject
		 */
		public function addElementAt(c:Object, index:int, dispatchEvent:Boolean = true):void
		{
			stage.addChildAt(c.element as DisplayObject, index);
			c.addedToParent();
		}

		/**
		 *  @copy org.apache.flex.core.IParent#getElementAt()
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
         *  @flexjsignorecoercion org.apache.flex.core.WrappedHTMLElement
		 */
		public function getElementAt(index:int):Object
		{
			var c:WrappedHTMLElement = stage.getChildAt(index) as WrappedHTMLElement;
			return c.flexjs_wrapper;
		}

		/**
		 *  @copy org.apache.flex.core.IParent#getElementIndex()
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
         *  @flexjsignorecoercion createjs.DisplayObject
		 */
		public function getElementIndex(c:Object):int
		{
			return stage.getChildIndex(c.element as DisplayObject)
		}

		/**
		 *  @copy org.apache.flex.core.IParent#removeElement()
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function removeElement(c:Object, dispatchEvent:Boolean = true):void
		{
			stage.removeChild(c.element as DisplayObject);
		}

		/**
		 *  @copy org.apache.flex.core.IParent#numElements
		 *
		 *  @langversion 3.0
		 *  @playerversion Flash 10.2
		 *  @playerversion AIR 2.6
		 *  @productversion FlexJS 0.0
		 */
		public function get numElements():int
		{
			return stage.numChildren;
		}
	}
}

fix error found by nonfunction test

fix error found by nonfunction test