/**
 * Harmony
 * Copyright (c) 2008 Maxime Bouroumeau-Fuseau
 *
 * 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.
 *
 * @author Maxime Bouroumeau-Fuseau
 * @copyright 2008 (c) Maxime Bouroumeau-Fuseau
 * @license http://www.opensource.org/licenses/mit-license.php
 * @link http://www.harmony-framework.com
 */
 
/**
 * Connects to the Harmony web service to do remote conversion
 */
var HarmonyWebService = new Class({
	
	/**
	 * Creates a "widget" to test Harmony
	 */
	Tester: new Class({
		Implements: Events,
	
		/**
		 * Available conversion buttons
		 */
		buttons: {
			'php2js': 'PHP to Javascript',
			'hx2php': 'Harmony XML to PHP',
			'hx2js': 'Harmony XML to Javascript',
			'hx2css': 'Harmony XML to CSS'
		},
		
		/**
		 * Constructor
		 *
		 * @param HarmonyWebService service
		 * @param Element container
		 * @param Object buttons OPTIONAL (see the buttons property) Default all available buttons
		 */
		initialize: function(service, container)
		{
			// the HarmonyWebService instance
			this.service = service;
			
			// main container
			this.container = container;
			this.container.addClass('harmony-tester');
			
			// containers
			this.textareaContainer = new Element('div', {'class': 'harmony-tester-textareas'}).inject(this.container);
			this.buttonsContainer = new Element('div', {'class': 'harmony-tester-buttons'}).inject(this.container);
			
			// textareas
			this.input = new Element('textarea', {
				'class': 'harmony-tester-textarea harmony-tester-textarea-input',
				'wrap': 'off'
			}).inject(this.textareaContainer);
			this.output = new Element('textarea', {
				'class': 'harmony-tester-textarea harmony-tester-textarea-output',
				'wrap': 'off'
			}).inject(this.textareaContainer);
			
			// creates buttons
			this.buttonElements = {};
			var tester = this;
			var buttons = arguments.length > 2 ? arguments[2] : this.buttons;
			$each(buttons, function(label, method) {
				tester.buttonElements[method] = new Element('input', {
					'type': 'button',
					'value': label,
					'class': 'harmony-tester-button',
					'events': {'click': function() { tester.convert(method); }}
				}).inject(tester.buttonsContainer);
			});
		},
		
		/**
		 * Converts code from the input textarea using the specified method
		 *
		 * @param string method
		 */
		convert: function(method)
		{
			var callback = arguments.length > 1 ? arguments[1] : null;
			this.service.convert(this.input.value, function(result) {
				this.output.value = result;
				this.fireEvent('conversionComplete', [result]);
				if (callback != null) {
					callback(result);
				}
			}.bind(this), method);
		},
		
		/**
		 * Clears both the input and the output textarea
		 */
		clear: function() {
			this.input.value = '';
			this.output.value = '';
			this.fireEvent('clear');
		},
		
		/**
		 * Loads some content from a url inside the input textarea
		 */
		load: function(url) {
			var callback = arguments.length > 1 ? arguments[1] : null;
			var tester = this;
			var request = new Request({
				'url': url, 
				onComplete: function(responseText) {
					tester.input.value = responseText;
					tester.output.value = '';
					this.fireEvent('loadComplete', [responseText]);
					if (callback != null) {
						callback(responseText);
					}
				}
			}).send();
		}
	}),
	
	/**
	 * Constructor
	 *
	 * @param string url OPTIONAL The url of the service
	 */
	initialize: function()
	{
		if (arguments.length > 0) {
			this.url = arguments[0];
		} else {
			this.url = 'http://www.harmony-framework.com/webservice/';
		}
	},

	/**
	 * Converts any data
	 * The callback should take one argument, which will be the
	 * conversion result.
	 *
	 * @param string data
	 * @param function callback The function that will be called when the conversion is finished
	 * @param string method OPTIONAL The conversion method to use (default is php2js)
	 */
	convert: function(data, callback)
	{
		var method = arguments.length > 2 ? arguments[2] : this.PHP_JS;
		var url = this.url + method;
		var request = new Request({'url': url});
		
		request.addEvent('onComplete', function(responseText) {
			callback(responseText);
		});
		
		request.send(data);
	},
	
	/**
	 * Creates a tester widget for this service
	 */
	createTester: function(container)
	{
		return new this.Tester(this, $(container));
	}
	
});

// available conversion methods
HarmonyWebService.PHP_JS = 'php2js';
HarmonyWebService.HX_PHP = 'hx2js';
HarmonyWebService.HX_JS = 'hx2js';
HarmonyWebService.HX_CSS = 'hx2css';
