text: /*globals  $: true, getUserMedia: true, alert:true, ccv:true */
  
  /*! getUserMedia demo - v0.5.0 - 4/21/2012
  * for use with https://github.com/addyosmani/getUserMedia.js
  * Copyright (c) 2012 addyosmani; Licensed MIT */
  
   (function () {
  	'use strict';
  
  	var App = {
  
  		init: function () {
  
  			// The shim requires options to be supplied for it's configuration,
  			// which can be found lower down in this file. Most of the below are
  			// demo specific and should be used for reference within this context
  			// only
  			if ( !!this.options ) {
  
  				this.pos = 0;
  				this.cam = null;
  				this.filter_on = false;
  				this.filter_id = 0;
  				this.canvas = document.getElementById("canvas");
  				this.ctx = this.canvas.getContext("2d");
  				this.img = new Image();
  				this.ctx.clearRect(0, 0, this.options.width, this.options.height);
  				this.image = this.ctx.getImageData(0, 0, this.options.width, this.options.height);
  				this.snapshotBtn = document.getElementById('takeSnapshot');
  				this.detectBtn = document.getElementById('detectFaces');
  				
  				// Initialize getUserMedia with options
  				getUserMedia(this.options, this.success, this.deviceError);
  
  				// Initialize webcam options for fallback
  				window.webcam = this.options;
  
  				// Trigger a snapshot
  				this.addEvent('click', this.snapshotBtn, this.getSnapshot);
  
  				// Trigger face detection (using the glasses option)
  				this.addEvent('click', this.detectBtn, function () {
  					App.drawToCanvas('glasses');
  				});
  
  			} else {
  				alert('No options were supplied to the shim!');
  			}
  		},
  
  		addEvent: function (type, obj, fn) {
  			if (obj.attachEvent) {
  				obj['e' + type + fn] = fn;
  				obj[type + fn] = function () {
  					obj['e' + type + fn](window.event);
  				}
  				obj.attachEvent('on' + type, obj[type + fn]);
  			} else {
  				obj.addEventListener(type, fn, false);
  			}
  		},
  
  		// options contains the configuration information for the shim
  		// it allows us to specify the width and height of the video
  		// output we're working with, the location of the fallback swf,
  		// events that are triggered onCapture and onSave (for the fallback)
  		// and so on.
  		options: {
  			"audio": true,
  			"video": true,
  			el: "webcam",
  
  			extern: null,
  			append: true,
  
  			width: 320, 
  			height: 240, 
  
  			mode: "callback",
  			// callback | save | stream
  			swffile: "../dist/fallback/jscam_canvas_only.swf",
  			quality: 85,
  			context: "",
  
  			debug: function () {},
  			onCapture: function () {
  				window.webcam.save();
  			},
  			onTick: function () {},
  			onSave: function (data) {
  
  				var col = data.split(";"),
  					img = App.image,
  					tmp = null,
  					w = this.width,
  					h = this.height;
  
  				for (var i = 0; i < w; i++) { 
  					tmp = parseInt(col[i], 10);
  					img.data[App.pos + 0] = (tmp >> 16) & 0xff;
  					img.data[App.pos + 1] = (tmp >> 8) & 0xff;
  					img.data[App.pos + 2] = tmp & 0xff;
  					img.data[App.pos + 3] = 0xff;
  					App.pos += 4;
  				}
  
  				if (App.pos >= 4 * w * h) { 
  					App.ctx.putImageData(img, 0, 0);
  					App.pos = 0;
  				}
  
  			},
  			onLoad: function () {}
  		},
  
  		success: function (stream) {
  
  			if (App.options.context === 'webrtc') {
  
  				var video = App.options.videoEl,
  					vendorURL = window.URL || window.webkitURL;
  				video.src = vendorURL ? vendorURL.createObjectURL(stream) : stream;
  
  				video.onerror = function () {
  					stream.stop();
  					streamError();
  				};
  
  			} else{
  				//flash context
  			}
  			
  		},
  
  		deviceError: function (error) {
  			alert('No camera available.');
  			//console.error('An error occurred: [CODE ' + error.code + ']');
  		},
  
  		changeFilter: function () {
  			if (this.filter_on) {
  				this.filter_id = (this.filter_id + 1) & 7;
  			}
  		},
  
  		getSnapshot: function () {
  			// If the current context is WebRTC/getUserMedia (something
  			// passed back from the shim to avoid doing further feature
  			// detection), we handle getting video/images for our canvas 
  			// from our HTML5 <video> element.
  			if (App.options.context === 'webrtc') {
  				var video = document.getElementsByTagName('video')[0]; 
  				App.canvas.width = video.videoWidth;
  				App.canvas.height = video.videoHeight;
  				App.canvas.getContext('2d').drawImage(video, 0, 0);
  
  			// Otherwise, if the context is Flash, we ask the shim to
  			// directly call window.webcam, where our shim is located
  			// and ask it to capture for us.
  			} else if(App.options.context === 'flash'){
  
  				window.webcam.capture();
  				App.changeFilter();
  			}
  			else{
  				alert('No context was supplied to getSnapshot()');
  			}
  		},
  
  		drawToCanvas: function (effect) {
  			var source, glasses, canvas, ctx, pixels, i;
  
  			source = document.querySelector('#canvas');
  			glasses = new Image();
  			glasses.src = "js/glasses/i/glasses.png";
  			canvas = document.querySelector("#output");
  			ctx = canvas.getContext("2d");
  
  			ctx.drawImage(source, 0, 0, 520, 426);
  
  			pixels = ctx.getImageData(0, 0, canvas.width, canvas.height);
  
  			// Hipstergram!
  			if (effect === 'hipster') {
  
  				for (i = 0; i < pixels.data.length; i = i + 4) {
  					pixels.data[i + 0] = pixels.data[i + 0] * 3;
  					pixels.data[i + 1] = pixels.data[i + 1] * 2;
  					pixels.data[i + 2] = pixels.data[i + 2] - 10;
  				}
  
  				ctx.putImageData(pixels, 0, 0);
  
  			}
  
  			// Green Screen
  			else if (effect === 'greenscreen') {
  
  				// Selectors 
  				var rmin = $('#red input.min').val(),
  					gmin = $('#green input.min').val(),
  					bmin = $('#blue input.min').val(),
  					rmax = $('#red input.max').val(),
  					gmax = $('#green input.max').val(),
  					bmax = $('#blue input.max').val(),
  					green = 0, red = 0, blue = 0;
  
  
  				for (i = 0; i < pixels.data.length; i = i + 4) {
  					red = pixels.data[i + 0];
  					green = pixels.data[i + 1];
  					blue = pixels.data[i + 2];
  					alpha = pixels.data[i + 3];
  
  					if (red >= rmin && green >= gmin && blue >= bmin && red <= rmax && green <= gmax && blue <= bmax) {
  						pixels.data[i + 3] = 0;
  					}
  				}
  
  				ctx.putImageData(pixels, 0, 0);
  
  			} else if (effect === 'glasses') {
  
  				var comp = ccv.detect_objects({
  					"canvas": (canvas),
  					"cascade": cascade,
  					"interval": 5,
  					"min_neighbors": 1
  				});
  
  				// Draw glasses on everyone!
  				for (i = 0; i < comp.length; i++) {
  					ctx.drawImage(glasses, comp[i].x, comp[i].y, comp[i].width, comp[i].height);
  				}
  			}
  
  		}
  
  	};
  
  	App.init();
  
  })();
  
  
  