// jsar.js

//  constructor

window.JSAR = function ( jsarId ) {
    if ( jsarId ) this.jsarId = jsarId;
    JSAR.Instances ++;
    this.instanceId = JSAR.Instances;
    return this;
};

JSAR.prototype.jsarId     = 'jsar_canvas';
JSAR.prototype.basePath   = './';
JSAR.prototype.jsarSWF    = 'jsar.swf';
JSAR.prototype.installSWF = 'inc/expressInstall.swf';
JSAR.prototype.cameraFile = 'assets/camera_para.dat'
JSAR.prototype.markerFiles = [ 'assets/jsarlogo.pat' ]

JSAR.prototype.captureX  = 640;
JSAR.prototype.captureY  = 480;
JSAR.prototype.displayX  = 640;
JSAR.prototype.displayY  = 480;
JSAR.prototype.asyncWait = 1;

JSAR.prototype.flash_wmode      = 'transparent';
JSAR.prototype.flash_quality    = 'low';
JSAR.prototype.flash_scale      = 'noScale';
JSAR.prototype.flash_salign     = 'lt';
JSAR.prototype.flash_menu       = 'false';
JSAR.prototype.flash_allowfullscreen = 'true';
JSAR.prototype.flash_version    = '9.0.0';

JSAR.prototype.markerNoCache = true;
JSAR.prototype.zIndexFlash	 = 0;
JSAR.prototype.zIndexCanvas	 = 1;
JSAR.prototype.zIndexHTML	 = 2;

JSAR.prototype.marker_lineCap       = 'butt';
JSAR.prototype.marker_lineJoin      = 'miter';
JSAR.prototype.marker_lineWidth     = '3';
JSAR.prototype.marker_strokeStyle   = 'red';
JSAR.prototype.marker_colors = [
    'red',      'yellow',   'lime',     'aqua',     
    'blue',     'fuchsia',  'maroon',   'olive',    
    'green',    'teal',     'navy',     'purple',   
    'black',    'gray',     'silver',   'white'
];

JSAR.prototype.marker_scaleX = 0.47;
JSAR.prototype.marker_scaleY = 0.31;

JSAR.prototype.drawMarkerRect = true;
JSAR.prototype.onCameraReady = function () {};
JSAR.prototype.onMarkerReady = function () {};
JSAR.prototype.onDetected    = function () {};
JSAR.prototype.debug_noFlash = false;

// private

JSAR.prototype._swfName;
JSAR.prototype._flashLayer;
JSAR.prototype._canvasLayer;
JSAR.prototype._htmlLayer;
JSAR.prototype._canvas2d;
JSAR.prototype._cameraReady;
JSAR.prototype._markerReady;

// class

JSAR.Instances = 0;

// init

JSAR.prototype.init = function () {
    this._log( 'init' );

    var area = document.getElementById(this.jsarId);
    area.style.width  = this.displayX + 'px';
    area.style.height = this.displayY + 'px';

    this._swfName = '_' + this.jsarId + '_swf_' + this.instanceId;
    this._log( '_swfName='+this._swfName );

    // create object element for flash
    var dummyelem = document.createElement( 'span' );   // dummy
    dummyelem.id = this._swfName;
    area.appendChild( dummyelem );
    var flashvars = {};
    var params = {
        wmode:           this.flash_wmode,
        quality:         this.flash_quality,
        scale:           this.flash_scale,
        salign:          this.flash_salign,
        menu:            this.flash_menu,
        allowfullscreen: this.flash_allowfullscreen,
    };
    var attributes = {};
    var swf_path   = this.basePath + this.jsarSWF;
    var inst_path  = this.basePath + this.installSWF;

	if ( ! this.debug_noFlash ) {
	    swfobject.embedSWF(swf_path, this._swfName, this.displayX, this.displayY,
	        this.flash_version, inst_path, flashvars, params, attributes);  
	}
	var embed = document.getElementById(this._swfName);  

    if ( embed ) {
        embed.style.position = 'absolute';
        embed.style.zIndex   = this.zIndexFlash;
        this._flashLayer = embed
    }

    // create canvas element for drawing
    var canvas = document.createElement( 'canvas' );
    if ( canvas && canvas.getContext ) {
        area.appendChild( canvas );
        canvas.style.position = 'absolute';
        canvas.style.zIndex   = '-1';
        canvas.style.overflow = 'hidden';
        canvas.style.width    = this.displayX + 'px';
        canvas.style.height   = this.displayY + 'px';
        this._canvasLayer = canvas;
        this._canvas2d = canvas.getContext('2d');
    }

    // create div element for html control
    var div = document.createElement( 'div' );
    if ( div ) {
        area.appendChild( div );
        div.style.position = 'absolute';
        div.style.zIndex   = '-1';
        div.style.overflow = 'hidden';
        div.style.width    = this.displayX + 'px';
        div.style.height   = this.displayY + 'px';
        this._htmlLayer = div;
    }

    // next phase
    this.callAsync( 'callInitCamera' );
}

JSAR.prototype._log = function ( mess ) {
	if ( window.console ) {
		// console.log( mess );
	}
};

JSAR.prototype.callAsync = function ( name ) {
    var self = this;
    var func = function () { self[name](); }
    window.setTimeout( func, this.asyncWait );
}

JSAR.prototype._movie_name;
JSAR.prototype.getJsarProxy = function () {
    if ( this._movie_name ) return this._movie_name;
    if (navigator.appName.indexOf("Microsoft") != -1) {
        this._movie_name = window[this._swfName]
    } else {
        this._movie_name = document[this._swfName]
    }
    return this._movie_name;
}

JSAR.prototype.callInitCamera = function () {
    var jsarProxy = this.getJsarProxy();
    this._log( 'callInitCamera jsarProxy='+jsarProxy );

    if ( jsarProxy && jsarProxy.initCamera ) {
        var opt = {};
        opt.cameraFile = this.cameraFile;
        opt.captureX  = this.captureX;
        opt.captureY = this.captureY;
        opt.displayX  = this.displayX;
        opt.displayY = this.displayY;
        jsarProxy.initCamera( opt );
        this._cameraReady = true;
        if ( this.onCameraReady ) {
            this.onCameraReady();
        }
    } else {
        this.callAsync( 'callInitCamera' );
    }
}

JSAR.prototype.setMarker = function ( patlist ) {
    if ( patlist ) this.markerFiles = patlist;
    this.callAsync( 'callSetMarker' );
}

JSAR.prototype.callSetMarker = function () {
    var jsarProxy = this.getJsarProxy();
    this._log( 'callSetMarker jsarProxy='+jsarProxy );

	if ( ! this.markerFiles ) this.markerFiles = [];

    if ( jsarProxy && jsarProxy.setMarker ) {
        var list = [];
        for( var i=0; i<this.markerFiles.length; i++ ) {
            list[i] = this.markerFiles[i];           // copy
			if ( this.markerNoCache ) {
	            list[i] += '?'+Math.random();   // random
			}
        }
        jsarProxy.setMarker( list );
        this._markerReady = true;
        if ( this.onMarkerReady ) {
            this.onMarkerReady();
        }
    } else {
        this.callAsync( 'callSetMarker' );
    }
}

JSAR.prototype.startLoop = function () {
    this.callAsync( 'detectLoop' );
}

JSAR.prototype.detectLoop = function () {
    var jsarProxy = this.getJsarProxy();

	// unique global callback function
    var callback = '_' + this.jsarId + '_callback_' + this.instanceId;
    if ( ! window[callback] ) {
        var self = this;
        window[callback] = function ( arg ) {
            self.detectCallback( arg );
        };
    }

    if ( jsarProxy && jsarProxy.detectMarker ) {
        jsarProxy.detectMarker( callback );
    } else {
        this.callAsync( 'detectLoop' );
    }
}

JSAR.prototype._captureStarted;
JSAR.prototype.detectCallback = function ( json ) {
    var result = eval("("+json+")");
    if ( result.detected ) {
        this._log( json );
	}
	this._detectCallback( result );
}

JSAR.prototype._lastDetected;
JSAR.prototype._detectCallback = function ( result ) {
    if ( result.detected ) {
        // change layers on first frame
        if ( ! this._captureStarted ) {
            if ( this._htmlLayer ) this._htmlLayer.style.zIndex = this.zIndexHTML;
            if ( this._canvasLayer ) this._canvasLayer.style.zIndex = this.zIndexCanvas;
            this._captureStarted = true;
        }
    }

    if ( result.detected ) {
	    if ( this.drawMarkerRect ) this.drawRect( result );
		if ( this.onDetected ) this.onDetected( result );
		this._lastDetected = true;
    } else if ( this._lastDetected ) {
	    if ( this.drawMarkerRect ) this.drawRect( result );
		if ( this.onLost ) this.onLost( result );
		this._lastDetected = false;
    }

    this.callAsync( 'detectLoop' );
}

JSAR.prototype.drawRect = function ( result ) {
    if ( ! this._canvas2d ) return;
    var canvas = this._canvas2d;

	if ( this._lastDetected ) this.clear_canvas();
	if ( ! result.markers ) return;
	if ( ! result.markers.length ) return;

    canvas.lineCap     = this.marker_lineCap;
    canvas.lineJoin    = this.marker_lineJoin;
    canvas.lineWidth   = this.marker_lineWidth;
    canvas.strokeStyle = this.marker_strokeStyle;

    for( var i=0; i<result.markers.length; i++ ) {

        var codeid = result.markers[i].codeid;
        canvas.strokeStyle = this.marker_colors[ codeid % this.marker_colors.length ];
        
        var vert = result.markers[i].vertex;
        canvas.beginPath();
        canvas.moveTo( vert[3].x*this.marker_scaleX, vert[3].y*this.marker_scaleY );
        for( var j=0; j<4; j++ ) {
            canvas.lineTo( vert[j].x*this.marker_scaleX, vert[j].y*this.marker_scaleY );
        }
        canvas.stroke();
    }
}

JSAR.prototype.clear_canvas = function () {
    if ( ! this._canvas2d ) return;
    this._canvas2d.clearRect( 0, 0, this.displayX, this.displayY );
}
