package {
    import flash.display.*;
    import flash.events.*;
    import flash.media.*;
    import flash.text.*;
    import flash.geom.*
    import flash.errors.*;
    import flash.filters.*;
    import flash.utils.*;
    import flash.net.*;

    public class CameraFramework extends Sprite
    {
        private var camera:Camera = null;               ///< カメラ
        public var video:Video = null;                  ///< ビデオ
        public var bgShape:Shape = new Shape();         ///< 外枠用
        public var bd:BitmapData;                       ///< BMPデータ
        public var bdTmp:BitmapData;                    ///< テンポラリビットマップデータ
        public var label:TextField = new TextField();   ///< ラベル

        /**
         * コンストラクタ
         * @param screenWidth SWFの幅
         * @param screenHeight SWFの高さ
         * @param videoWidth ビデオの幅
         * @param videoHeight ビデオの高さ
         */
        public function CameraFramework( screenWidth:int, screenHeight:int, videoWidth:int, videoHeight:int )
        {
            // filterの作成
            var filter:Array = new Array;
            filter.push( new DropShadowFilter() );

            // 背景色用オブジェクト作成
            addChild(bgShape);
            drawBgColor(0x333333);

            // BMPデータの作成
            var bmp:Bitmap
            bd = new BitmapData( videoWidth, videoHeight, false, 0xffffff);
            bmp = new Bitmap(bd);
            bmp.filters = filter;
            bmp.x = (screenWidth - videoWidth)/2;
            bmp.y = (screenHeight - videoHeight)/2;
            addChild(bmp);

            bdTmp = new BitmapData( videoWidth, videoHeight, false, 0xffffff);

            //ラベル
            label.autoSize=TextFieldAutoSize.LEFT;
            label.text = "WebCamera Framework";
            label.filters = filter;
            label.textColor = 0xffffff;
            label.x = 2;
            label.y = screenHeight - label.textHeight - 10;
            addChild(label);

            //カメラの取得
            camera=Camera.getCamera();

            if (camera!=null) {
                //イベントリスナーの追加
                camera.addEventListener(StatusEvent.STATUS,statusHandler);
                //ビデオの生成
                video = new Video( videoWidth, videoHeight );
                video.attachCamera(camera);
            } else {
                label.text="カメラを利用できません";
            }

            // メインループ追加
            addEventListener(Event.ENTER_FRAME, tick);
        }

        /// 状態イベントの処理
        private function statusHandler(evt:StatusEvent):void {
            if (camera.muted){
                label.text="カメラを利用できません";
            }
        }

        /// メインループ
        private function tick( event:Event ):void
        {
            if(video == null || camera == null){
                return;
            }

            if( camera.muted == true ){
                // カメラがアクセス禁止されている
                return;
            }

            // bdTmpにビデオデータを転送            
            bdTmp.draw(video);

            // 画面描画
            draw();
        }

        /// 背景色の描画
        public function drawBgColor(color:uint):void {
            bgShape.graphics.lineStyle(0,color);
            bgShape.graphics.beginFill(color);
            bgShape.graphics.drawRect(0,0,360,320);
            bgShape.graphics.endFill();
        }

        /**
         * この関数がoverrideされ、カメラの描画処理を決定する
         */
        public function draw():void {
            for( var y:int = 0; y < bdTmp.height; ++y ){
                for( var x:int = 0; x < bdTmp.width; ++x ){
                    var color:uint = bdTmp.getPixel(x , y);
                    bd.setPixel(x, y, color);
                }
            }
        }

        /**
         * 指定されているURLのウェブサイトを開く
         * @param openURL 開くURL
         */
        private function openWebsite(openURL:String):void {
            var variables:URLVariables = new URLVariables();
            var request:URLRequest = new URLRequest(openURL);

            try {
                navigateToURL(request);
            }
            catch (e:Error) {
                // handle error here
            }
        }

    }
}