/**
 * JSONRequest.js
 *
 * Released under LGPL License.
 * Copyright (c) 1999-2015 Ephox Corp. All rights reserved
 *
 * License: http://www.tinymce.com/license
 * Contributing: http://www.tinymce.com/contributing
 */

/**
 * This class enables you to use JSON-RPC to call backend methods.
 *
 * @class tinymce.util.JSONRequest
 * @example
 * var json = new tinymce.util.JSONRequest({
 *     url: 'somebackend.php'
 * });
 *
 * // Send RPC call 1
 * json.send({
 *     method: 'someMethod1',
 *     params: ['a', 'b'],
 *     success: function(result) {
 *         console.dir(result);
 *     }
 * });
 *
 * // Send RPC call 2
 * json.send({
 *     method: 'someMethod2',
 *     params: ['a', 'b'],
 *     success: function(result) {
 *         console.dir(result);
 *     }
 * });
 */
define("tinymce/util/JSONRequest", [
	"tinymce/util/JSON",
	"tinymce/util/XHR",
	"tinymce/util/Tools"
], function(JSON, XHR, Tools) {
	var extend = Tools.extend;

	function JSONRequest(settings) {
		this.settings = extend({}, settings);
		this.count = 0;
	}

	/**
	 * Simple helper function to send a JSON-RPC request without the need to initialize an object.
	 * Consult the Wiki API documentation for more details on what you can pass to this function.
	 *
	 * @method sendRPC
	 * @static
	 * @param {Object} o Call object where there are three field id, method and params this object should also contain callbacks etc.
	 */
	JSONRequest.sendRPC = function(o) {
		return new JSONRequest().send(o);
	};

	JSONRequest.prototype = {
		/**
		 * Sends a JSON-RPC call. Consult the Wiki API documentation for more details on what you can pass to this function.
		 *
		 * @method send
		 * @param {Object} args Call object where there are three field id, method and params this object should also contain callbacks etc.
		 */
		send: function(args) {
			var ecb = args.error, scb = args.success;

			args = extend(this.settings, args);

			args.success = function(c, x) {
				c = JSON.parse(c);

				if (typeof c == 'undefined') {
					c = {
						error: 'JSON Parse error.'
					};
				}

				if (c.error) {
					ecb.call(args.error_scope || args.scope, c.error, x);
				} else {
					scb.call(args.success_scope || args.scope, c.result);
				}
			};

			args.error = function(ty, x) {
				if (ecb) {
					ecb.call(args.error_scope || args.scope, ty, x);
				}
			};

			args.data = JSON.serialize({
				id: args.id || 'c' + (this.count++),
				method: args.method,
				params: args.params
			});

			// JSON content type for Ruby on rails. Bug: #1883287
			args.content_type = 'application/json';

			XHR.send(args);
		}
	};

	return JSONRequest;
});