<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" creationComplete="startWebcam()" viewSourceURL="srcview/index.html">
    
    <mx:Script>
        <![CDATA[
            // Date :            5 Février 2008
            // Auteur :         Mickael Ruellan pour Flex-info.fr
            // Ressources :     http://tinkerlog.com/2007/11/03/webcam-snapshots-with-flex3/
            //                    http://codemoiunmouton.wordpress.com/2007/11/11/randomwin-10/
            //                     http://www.kaourantin.net/2005/10/more-fun-with-image-formats-in-as3.html
            //                     http://www.kaourantin.net/source/JPEGEncoder.as
            //                    http://dynamicflash.com/goodies/base64/
        
            import mx.formatters.DateFormatter;
            import flash.net.navigateToURL;
            import com.dynamicflash.util.Base64;
            import mx.controls.Alert;
            import mx.events.ListEvent;
            import mx.collections.ArrayCollection;
            
            private var webcam:Camera;
            private var imageName:String = '';
            
            public function startWebcam():void {
                try {
                    // Récupère et paramètre la webcam (c'est à ce moment que Flash va demander à l'utilisateur d'autoriser ou non l'accès à la webcam)
                    webcam = Camera.getCamera();
                    webcam.setQuality(65538, 0);
                    webcam.setMode(320, 240, 25, false);
                    // Affiche le flux de la webcam dans l'objet videoDisplay
                    videoDisplay.attachCamera(webcam);
                    // Mise à zéro du catalogue, et activation du bouton pour prendre des photos
                    catalog.dataProvider = new ArrayCollection;
                    takeBtn.enabled = true;
                } catch (e:*) {
                    Alert.show("La webcam n'a pas été détectée", "Erreur");
                    return;
                }
            }
            
            public function takeSnapshot():void{
                // Création d'une nouvelle image Bitmap
                var snapshot:BitmapData = new BitmapData(320, 240, true);
                var snapshotbitmap:Bitmap = new Bitmap(snapshot);
                // Copie de l'image actuelle de la webcam vers la nouvelle image
                snapshot.draw(videoDisplay);
                // Ajout de la nouvelle image au catalogue
                (catalog.dataProvider as ArrayCollection).addItem({source: snapshotbitmap});                
                // Selectionne le dernier élément du catalogue et l'affiche
                catalog.selectedIndex = (catalog.dataProvider as ArrayCollection).length;
                select();
            }
            
            public function select():void {
                // Copie de l'image sélectionnée vers l'aperçu
                if(catalog.selectedItem) {
                    // on fait une copie de l'image sinon elle disparait de la vignette du catalogue
                    selectedSnapshot.source = new Bitmap((catalog.selectedItem.source as Bitmap).bitmapData);
                    downloadBtn.enabled = true;
                } else {
                    downloadBtn.enabled = false;
                }
            }
            
            private function uploadSnapshot():void {
                if(selectedSnapshot.source) {
                    // On créé une nouvelle instance d'encodeur JPEG
                    // La librairie JPEGEncoder provient de www.kaourantin.net
                    // Elle a été transformée pour être compilable sous Flex 2
                    var jpgEncoder:JPEGEncoder = new JPEGEncoder(75);
                    // On encode les données bitmap de l'image et on récupère un ByteArray
                    var jpgBytes:ByteArray = jpgEncoder.encode((selectedSnapshot.source as Bitmap).bitmapData);
                    uploadPhoto(jpgBytes);
                }
            }

            private function uploadPhoto(imageData:ByteArray):void {
                // On créé une requête de chargement de l'image vers le serveur
                var request:URLRequest = new URLRequest("upload.php");
                var vars:URLVariables = new URLVariables();
                // On passe en paramètre le ByteArray récupérer de la conversion JPEG au format Base64
                // L'encodage en Base64 permet de transformer le ByteArray en une chaine de caractères qui sera décodée dans le script php
                vars.imagedata = Base64.encodeByteArray(imageData);
                vars.imagename = getNewImageName();
                request.method = "POST";
                var loader:URLLoader = new URLLoader();
                loader.addEventListener(Event.COMPLETE, uploadPhotoHandler);
                request.data = vars;
                // On envoit la requête
                loader.load(request);
            }
            
            private function getNewImageName():String {
                // determine le nom de l'image à envoyer (1 seule image possible par seconde avec ce code !)
                var formatter:DateFormatter = new DateFormatter();
                formatter.formatString = 'YYYY-MM-DD_J:NN:SS';
                imageName = 'myWebcamImage_' + formatter.format(new Date) + '.jpg';
                return imageName;
            }
            
            private function uploadPhotoHandler(e:Event):void {
                // lorsqu'on a fini de charger on va télécharger l'image
                // A noter qu'on aurait aussi pu faire un seul script PHP pour l'envoi/téléchargement de photo du style : 
                // navigateToURL(request) avec request une requete contenant en paramètre l'image, et en modifiant le script php pour qu'il
                // renvoit ce qu'on vient d'uploader directement...
                downloadPhoto(imageName);
            }
            
            private function downloadPhoto(photo:String):void {
                var request:URLRequest = new URLRequest('download.php');
                var vars:URLVariables = new URLVariables();
                // on met en parametre le nom de la photo qu'on vient d'envoyer
                vars.photo = photo;
                request.method = "POST";
                request.data = vars;
                // on suit le lien dans la même fenêtre (_self) de manière à éviter le fonctionnement des anti popups...
                // Le header du script PHP va indiiquer qu'il s'agit d'une image en téléchargement et le navigateur va normalement proposer
                // de télécharger cette image sans changer de page pour autant
                navigateToURL(request,'_self');
            }
            
        ]]>
    </mx:Script>
    
    <mx:VBox paddingTop="50" paddingLeft="50" paddingRight="50" paddingBottom="50" horizontalAlign="center" verticalGap="20">
        <mx:HBox width="100%" horizontalAlign="center" horizontalGap="50">
            <mx:VBox horizontalAlign="center">
                <mx:VideoDisplay width="320" height="240" id="videoDisplay"/>
                <mx:Button label="Take Snapshot" id="takeBtn" enabled="false" click="takeSnapshot()"/>
            </mx:VBox>
            <mx:VBox horizontalAlign="center">
                <mx:Image width="320" height="240" id="selectedSnapshot"/>
                <mx:Button label="Download Image" id="downloadBtn" enabled="false" click="uploadSnapshot()"/>
            </mx:VBox>
        </mx:HBox>
        <mx:TileList width="100%" height="200" id="catalog" itemRenderer="MyItemRenderer" change="select()" rowHeight="48" columnWidth="64" />
    </mx:VBox>
    
</mx:Application>