/*
* FauxCanvas
* Visit http://createjs.com/ for documentation, updates and examples.
*
* Copyright (c) 2014 gskinner.com, inc.
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

(function () {
	"use strict";

	/**
	 * Can be passed to a Stage in place of a Canvas element in order to eliminate the browser-specific cost of drawing graphics to screen, and thereby isolate the time spent in EaselJS.
	 * Still rough, and may be missing methods or properties that are necessary for certain features in EaselJS.
	 * 
	 * <b>Note:</b> You should disable DOM events with `myStage.enableDOMEvents(false)` to prevent errors generated by mouse events.
	 * @class FauxCanvas
	 * @param {Number} [width=300] The value for width property of the FauxCanvas instance.
	 * @param {Number} [height=150] The value for height property of the FauxCanvas instance.
	 * @param {Boolean} [replaceInternal=false] If true, FauxCanvas will be used for all EaselJS caches and offscreen canvases.
	 * @constructor
	 **/
	var FauxCanvas = function (width, height, replaceInternal) {
		this.initialize(width, height, replaceInternal);
	};
	var p = FauxCanvas.prototype;
	p.constructor = FauxCanvas;
	
	FauxCanvas.PROPERTIES = [
		// all browsers:
		"canvas","fillStyle","font","globalAlpha","globalCompositeOperation","lineCap","lineDashOffset","lineJoin","lineWidth","miterLimit","shadowBlur","shadowColor","shadowOffsetX","shadowOffsetY","strokeStyle","textAlign","textBaseline",
		// gecko / mozilla:
		"mozCurrentTransform","mozCurrentTransformInverse","mozDash","mozDashOffset","mozFillRule","mozImageSmoothingEnabled","mozTextStyle",
		// webkit:
		"webkitLineDash", "webkitLineDashOffset"
		];
	FauxCanvas.METHODS = [
		// all browsers:
		"arc","arcTo","beginPath","bezierCurveTo","clearRect","clip","closePath","createImageData","createLinearGradient","createPattern","createRadialGradient","drawCustomFocusRing","drawImage","drawSystemFocusRing","fill","fillRect","fillText","getImageData","getLineDash","isPointInPath","isPointInStroke","lineTo","measureText","moveTo","putImageData","quadraticCurveTo","rect","restore","rotate","save","scale","scrollPathIntoView","setLineDash","setTransform","stroke","strokeRect","strokeText","transform","translate",
		// gecko / mozilla:
		"asyncDrawXULElement","drawWindow","getFillStyle_multi","getImageData_explicit","getStrokeStyle_multi","mozDrawText","mozMeasureText","mozPathText","mozTextAlongPath","setFillStyle_multi","setStrokeStyle_multi",
		// webkit:
		"clearShadow","drawImageFromRect","setAlpha","setCompositeOperation","setLineWidth","setLineCap","setLineJoin","setMiterLimit","setStrokeColor","setFillColor","setShadow",
		// canvas:
		"addEventListener","removeEventListener"
		];

// initialization:
	/**
	 * Initialization method.
	 * @method initialize
	 * @protected
	 **/
	p.initialize = function (width, height, replaceInternal) {
		var methods = FauxCanvas.METHODS;
		for (var i= 0, l=methods.length; i<l; i++) {
			this[methods[i]] = function() {};
		}
		
		var props = FauxCanvas.PROPERTIES;
		for (i= 0, l=props.length; i<l; i++) {
			this[props[i]] = null;
		}
		
		this.width = width||300;
		this.height = height||150;
		
		if (replaceInternal) {
			createjs = createjs||{};
			createjs.createCanvas = function() {
				return new FauxCanvas();
			}
		}
	};

// public properties:

// private properties:

// public methods:
	
	/**
	 * Enables or disables logging by overriding (or restoring) the getContext method on the target canvas to return
	 * the FauxCanvas instance as a proxy for the "2d" context.
	 * @method setEnabled
	 * @param {Boolean} val True or false.
	 **/
	p.getContext = function(type) {
		if (type == "2d") { return this; }
		throw("Context not supported: "+type);
	};

// private methods:

	window.FauxCanvas = FauxCanvas;
})();
