<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical"
    backgroundGradientColors="[#EFEFEF,#CFCFCF]"
    xmlns:local="*" viewSourceURL="srcview/index.html">

    <mx:Script>
        <![CDATA[
            import mx.core.Container;
            import mx.events.DragEvent;
            import mx.collections.ArrayCollection;
            import mx.core.UIComponent;
            import mx.managers.DragManager;
            import mx.core.DragSource;

            import mx.controls.Label;

            /* initialise le déplacement
            *    1. création d'un object DragSource pour stocker les données déplacées
            *    2. initialisation du déplacement par le DragManager
            */
            private function drag( e:MouseEvent):void
            {
                var dgData:DragSource = new DragSource();
                var dgText:String = (e.target.parent as Label).text ;

                dgData.addData( dgText  , "lettre" );
                dgData.addData( getLetterPosition(dgText) , "position" );

                DragManager.doDrag( UIComponent(e.target.parent) , dgData, e );
            }

            /*  vérification du droit de dépot des données
            *    » vérifie si l'objet DragSource contient les
            */
            private function isDropable( e:DragEvent ):void
            {
                // référence du champ de texte contenu par le composant Cible
                var cibleText:Label = Container(e.target).getChildAt(0) as Label ;

                var dgData:DragSource = e.dragSource ;

                // si le chp de texte cible n'est pas le chap source lui même
                // ET si le champ cible est vide ( pas d'écrasement )
                if ( e.dragInitiator != cibleText && cibleText.text == "" )
                    if ( dgData.hasFormat("lettre") && dgData.hasFormat("position") )
                        DragManager.acceptDragDrop( UIComponent( e.target ) );
            }

            /*  ajout de la lettre déposé
            *    1. affiche le texte dans le Canva cible
            *    2. vérifie si la lettre a été déposé au bon endroit
            *    3. vide le texte du composant source
            */
            private function addLettre( e:DragEvent ):void
            {
                // récupération des données
                var dropLetter:String = String( e.dragSource.dataForFormat("lettre") );
                var dropPosition:uint = uint( e.dragSource.dataForFormat("position") );

                // référence du champ de texte contenu par le composant Cible
                var cibleText:Label = Container(e.target).getChildAt(0) as Label ;

                // remplit le champ texte cible avec la lettre déposée
                cibleText.text = dropLetter ;

                // si la lettre est déposé dans un Canvas cible : test si elle est déposé à la bonne position
                if ( e.target is DropableCanvas )
                    if ( DropableCanvas(e.target).dropData.position == dropPosition )
                        cibleText.setStyle( "color" , 0x00FF00 );

            }

            /*
            *    renvoie la position originale d'un caractère
            */
            private function getLetterPosition( l:String ):uint
            {
                for ( var i:uint; i < lettres.length; i++ ){
                    if  ( lettres[i].lettre == l )
                        return lettres[i].position;
                }

                return lettres.length + 1;
            }

            // renvoit le tableau trié ( désordre )
            private function randomize( t:Array ):Array
            {
                var rdT:Array = t.slice(0, t.length  );
                return rdT.sort();
            }

            /* si le déplacement a réussi et que la cible est différente de la source
            *    » vide le champ source
            */

            private function onDragComplete( e:DragEvent ):void
            {
                trace ( 'complete  :' + e.target +  ' / ' + e.dragInitiator );
                if ( e.action == DragManager.MOVE )
                    Label( e.target ).text = "";
            }
        ]]>
    </mx:Script>

    <!--  Mot initial-->
    <mx:Array id="lettres">
        <mx:Object lettre="B" position="1" />
        <mx:Object lettre="R" position="2" />
        <mx:Object lettre="A" position="3" />
        <mx:Object lettre="V" position="4" />
        <mx:Object lettre="O" position="5" />
    </mx:Array>

    <!-- Composants graphiques -->
    <mx:HBox>

        <!-- Les lettres sont affichées dans des Labels insérés dans des Canvas
            un repeater est utilisé pour créer les items
        -->
        <mx:Repeater id="rpSrc" dataProvider="{randomize(lettres)}">
            <mx:Canvas width="60" height="80" backgroundColor="#EFEFEF"
                borderColor="#CCCCCC" borderStyle="solid"
                dragEnter="isDropable(event)"
                dragDrop="addLettre( event )"
                >
<!--                -->
                <mx:Label id="l" fontSize="32" text="{rpSrc.currentItem.lettre}"
                    horizontalCenter="0" verticalCenter="0"
                    mouseDown="drag( event )"
                    dragComplete="onDragComplete( event )"
                    />
            </mx:Canvas>
        </mx:Repeater>
    </mx:HBox>

    <mx:HBox>
        <!-- repeater pour les champs cibles
            » dans ce cas ce sont des DropableCanvas : ils permettent de stocker la bonne réponse dans chaque Canvas cible
        -->
        <mx:Repeater id="rpCibles" dataProvider="{lettres}">
            <local:DropableCanvas width="60" height="80" backgroundColor="#EFEFEF"
                borderColor="#CCCCCC" borderStyle="solid"
                dropData="{lettres[rpCibles.currentIndex]}"
                dragEnter="isDropable(event)"
                dragDrop="addLettre( event )"
                >
                <mx:Label id="cibleLabel" fontSize="32"
                    horizontalCenter="0" verticalCenter="0"
                    mouseDown="drag( event )"
                    dragComplete="onDragComplete( event )"
                    />
            </local:DropableCanvas>
        </mx:Repeater>
    </mx:HBox>

</mx:Application>