var EventTarget = require('../utils/EventTarget');
var ImageLoader = require('./ImageLoader');
var Texture = require('../textures/Texture');
var Rectangle = require('../core/Rectangle');
var TextureManager = require('../textures/TextureManager');
var _Workaround = require('../_Workaround');

var JsonLoader = function() {
    function JsonLoader(url, crossorigin) {
		EventTarget.call(this);

		/**
		 * The url of the bitmap font data
		 *
		 * @property url
		 * @type String
		 */
		this.url = url;

		/**
		 * Whether the requests should be treated as cross origin
		 *
		 * @property crossorigin
		 * @type Boolean
		 */
		this.crossorigin = crossorigin;

		/**
		 * [read-only] The base url of the bitmap font data
		 *
		 * @property baseUrl
		 * @type String
		 * @readOnly
		 */
		this.baseUrl = url.replace(/[^\/]*$/, '');

		/**
		 * [read-only] Whether the data has loaded yet
		 *
		 * @property loaded
		 * @type Boolean
		 * @readOnly
		 */
		this.loaded = false;
	}

    JsonLoader.prototype.load = function() {
		if(window.XDomainRequest && this.crossorigin)
		{
			this.ajaxRequest = new window.XDomainRequest();

			// XDomainRequest has a few querks. Occasionally it will abort requests
			// A way to avoid this is to make sure ALL callbacks are set even if not used
			// More info here: http://stackoverflow.com/questions/15786966/xdomainrequest-aborts-post-on-ie-9
			this.ajaxRequest.timeout = 3000;

			this.ajaxRequest.onerror = this.onError.bind(this);

			this.ajaxRequest.ontimeout = this.onError.bind(this);

			this.ajaxRequest.onprogress = function() {};

		}
		else if (window.XMLHttpRequest)
		{
			this.ajaxRequest = new window.XMLHttpRequest();
		}
		else
		{
			this.ajaxRequest = new window.ActiveXObject('Microsoft.XMLHTTP');
		}

		this.ajaxRequest.onload = this.onJSONLoaded.bind(this);

		this.ajaxRequest.open('GET',this.url,true);

		this.ajaxRequest.send();
	};

    JsonLoader.prototype.onJSONLoaded = function() {
		if(!this.ajaxRequest.responseText )
		{
			this.onError();
			return;
		}
		
		this.json = JSON.parse(this.ajaxRequest.responseText);

		if(this.json.frames)
		{
			// sprite sheet
			var textureUrl = this.baseUrl + this.json.meta.image;
			var image = new ImageLoader(textureUrl, this.crossorigin);
			var frameData = this.json.frames;

			this.texture = image.texture.baseTexture;
			image.addEventListener('loaded', this.onLoaded.bind(this));

			for (var i in frameData)
			{
				var rect = frameData[i].frame;

				if (rect)
				{
					TextureManager.Texture[i] = new Texture(this.texture, {
						x: rect.x,
						y: rect.y,
						width: rect.w,
						height: rect.h
					});

					TextureManager.Texture[i].crop = new Rectangle(rect.x, rect.y, rect.w, rect.h);

					// check to see ifthe sprite ha been trimmed..
					if (frameData[i].trimmed)
					{				
						var actualSize = frameData[i].sourceSize;
						var realSize = frameData[i].spriteSourceSize;

						TextureManager.Texture[i].trim = new Rectangle(realSize.x, realSize.y, actualSize.w, actualSize.h);
					}
				}
			}

			image.load();

		}
		else if(this.json.bones)
		{
			// spine animation
			var spineJsonParser = new _Workaround.spine.SkeletonJson();
			var skeletonData = spineJsonParser.readSkeletonData(this.json);
			TextureManager.AnimCache[this.url] = skeletonData;
			this.onLoaded();
		}
		else
		{
			this.onLoaded();
		}
	};

    JsonLoader.prototype.onLoaded = function() {
		this.loaded = true;
		this.dispatchEvent({
			type: 'loaded',
			content: this
		});
	};

    JsonLoader.prototype.onError = function() {
		this.dispatchEvent({
			type: 'error',
			content: this
		});
	};

    return JsonLoader;
}();

module.exports = JsonLoader;