/**

* @version		$Id: plugin.js 49 2009-05-28 10:02:46Z happynoodleboy $

* @package      JCE

* @copyright    Copyright (C) 2005 - 2009 Ryan Demmer. All rights reserved.

* @author		Ryan Demmer

* @license      GNU/GPL

* JCE is free software. This version may have been modified pursuant

* to the GNU General Public License, and as distributed it includes or

* is derivative of works licensed under the GNU General Public License or

* other free or open source software licenses.

*/



/*

Class: Plugin

	Base plugin class for creating a JCE plugin object.



Arguments:

	options - optional, an object containing options.



Options:

	site - the base site url.

	plugin - the plugin name

	lang - the language code, eg: en.

	params - parameter object.



Example:

	var advlink = new Plugin('advlink', {params: {'key': 'value'}});

*/

var Plugin = new Class({	

	// Dialog box default

	_dialog 		: [],

	// Arbitrary variable

	_vars 			: null,

	// Current plugin

	_plugin			: null,

	getOptions : function(){

		return {

			site 	: tinyMCEPopup.editor.documentBaseURI.getURI(true),

			lang 	: 'en',

			params 	: {},

			alerts 	: null

		}

	},

	initialize : function(plugin, options){

		this.setOptions(this.getOptions(), options);		

		this._plugin = plugin;



		// fallback for no plugin set

		if(!this._plugin){

			var q = string.query(document.location.href);

			this._plugin = q['plugin'];

		}

		// show any alert dialogs

		this.showAlerts();

		// initialize tooltips

		this.initToolTip();

	},

	/*

	 * Return site url option

	 * @param {String} The site url variable

	*/

	getSite : function(){

		return this.options.site;	

	},

	/*

	 * Store a custom plugin parameter

	 * Example: 'animals', ['dog', 'cat', 'mouse']

	 * @param {string} The parameter key/name

	 * @param {string/array/object} The value

	*/

	setParam : function(p, v){

		this.options.params[p] = v;

	},

	/*

	 * Store custom plugin parameters

	 * Example: {'animals': ['dog', 'cat', 'mouse']}

	 * @param {Object} The parameters object

	*/

	setParams : function(p){

		for(n in p){

			this.setParam(n, p[n]);

		}

	},

	/*

	 * Return a custom plugin parameter

	 * @param {string} The parameter key/name

	*/

	getParam : function(p){

		return this.options.params[p] || false;

	},

	/*

	 * Set the plugin as current

	 * @param {string} The plugin name

	*/

	setPlugin : function(p){

		this._plugin = p;

	},

	/*

	 * Return the current plugin

	 * @return {string} The plugin name

	*/

	getPlugin : function(){

		return this._plugin;	

	},

	/*

	 * Return a full resource url

	 * @param {string} The url type, eg: img, plugin

	 * @return {string} The url

	*/

	getUrl : function( type ){

		if( type == 'plugins' ){

			type = 'tiny_mce/plugins/' + this.getPlugin();

		}

		return string.path(this.options.site, 'plugins/editors/jce/' + type);

	},

	/*

	 * Return a full image url

	 * @param {string} The image name

	 * @return {string} The url

	*/

	getImage : function(name){

		var parts 	= name.split('.');

		var path 	= parts[0].replace(/[^a-z0-9-_]/i, '');

		var file 	= parts[1].replace(/[^a-z0-9-_]/i, '');

		var ext 	= parts[2].replace(/[^a-z0-9-_]/i, '');

		

		return this.getUrl(path) + '/img/' + file + '.' + ext;

	},

	/*

	 * Resolve a TinyMCE language string

	 * @param {string} The variable name

	 * @param {string} The default translation

	 * @return {string} The language string

	*/

	getLang : function(s, dv){

		return tinyMCEPopup.getLang(s, dv);

	},

	/*

	 * Loads a TinyMCE plugin or theme dialog language file. Requires asset.js

	 * @param {string} The variable name

	 * @param {string} The default translation

	 * @return {string} The language string

	*/

	loadLanguage : function(name){

		var path = '', parts = '', file = '';

		if(name){

			parts 	= name.split('.');

			path 	= parts[0].replace(/[^a-z0-9-_]/i, '');

			file 	= parts[1].replace(/[^a-z0-9-_]/i, '');

			path 	= path + '/' + file + '/';

		}

		var u = this.options.site + 'plugins/editors/jce/tiny_mce/' + path + 'langs/' + this.options.lang + '_dlg.js';

		new Asset.javascript(u);

	},

	setVars: function(vars){

		this._vars = vars;

	},

	getVars: function(){

		return this._vars;

	},

	/*

	* Add a dialog object

	* @param {String} The dialog name

	* @param {String} The dialog object

	*/

	addDialog : function(name, dialog){

		this._dialog[name] = dialog;

	},

	/*

	* Get a dialog object

	* @param {String} The dialog name

	* @return the dialog object

	*/

	getDialog : function(name){

		return this._dialog[name] || '';

	},

	/*

	* Remove a dialog object

	* Shortcut for closing a dialog too

	* @param {String} The dialog name

	*/

	removeDialog : function(name){

		if(typeof this._dialog[name].close() != 'undefined'){

			this._dialog[name].close();	

		}

		delete this._dialog[name];

	},

	/*

	 * Open help window for current language

	*/

	openHelp : function(type){

		if(!type) type = 'standard';

		tinyMCE.activeEditor.windowManager.open({

			url : tinyMCEPopup.getParam('site_url') + 'index.php?option=com_jce&task=help&lang='+ this.options.lang +'&plugin='+ this._plugin +'&type='+ type +'&file=help',

			width : 640,

		    height : 480,

		    resizable : "yes",

            inline : "yes",

        	close_previous : "no"

		});

	},

	iframe : function(fn, cb){

		new IFrame({

			auto: true,

			action: fn,

			onComplete: function(o){

				if(o.error){

					alert(o.error);

				}else{

					r = o.result || {error: false};

					if(cb){

						cb.pass(r, this)();	

					}else{

						return r;	

					}

				}	

			}

		});

	},

	_encode : function(s){

		s = s.replace(new RegExp('"', 'g'), '\\"');

		s = s.replace(new RegExp("'", 'g'), "\\'");

		

		return s;

	},

	/*

	 * XHR request. Requires Mootools json.js

	 * @param {string} The target function to call

	 * @param {array} An array of arguments

	 * @param {function} The callback function on success

	*/

	xhr : function(fn, args, cb){

		var u = document.location.href;



		if(!/format=raw/.test(u)){

			u += '&format=raw';	

		}



		new Json.Remote(u, {

			autoCancel : true,

			onComplete: function(o){

				if(o.error){

					alert(o.error);	

				}

				r = o.result || {error: false};

				if(cb){

					cb.pass(r, this)();	

				}else{

					return r;	

				}

			}.bind(this),

			onFailure: function(x){

				alert('Request failed with status code: '+ x.status);	

			}

		}).send({'fn': fn, 'args': args});

	},

	/*

	 * Alerts. Requires window.js

	*/

	showAlerts : function(){

		var alerts = this.options.alerts || [];

		if(alerts.length){

			var h = '<dl class="alert">';

			alerts.each(function(a){

				h += '<dt class="' + a['class'] + '">' + a['title'] + '</dt><dd>' + a['text'] + '</dd>';				

			});

			h += '</dl>'

			new Alert(h, {height: 150 + alerts.length * 50});

		}

	},

	initToolTip : function(elms){

		this.tooltip =  new Tips($$('.hastip'), {

			className : 'tooltip',

			fixed: true,

			offsets: {'x': 24, 'y': 24}

		});	

	},

	addToolTip : function(el){

		if($type(el) != 'array'){

			el = [el];	

		}

		el.each(function(e){

			this.tooltip.build(e);				 

		}.bind(this));

	}

});

Plugin.implement(new Events, new Options);

/* IFrame class for pseudo ajax/json stuff */

var IFrame = new Class({

	getOptions : function(){

		return {			

			form: $E('form'),

			frame: 'iframe',

			action: '',

			cleanup : true,

			auto : false,

			onStart: Class.empty,

			onComplete: Class.empty

		};

	},

	initialize : function(options){

		this.setOptions(this.getOptions(), options);

		if (this.options.initialize) this.options.initialize.call(this);

		// Remove existing frame

		this.remove();

		// Create IFrame

		this.frame 	= new Element('iframe', {

			'src': 'about:blank', 

			'name': this.options.frame,

			'id': this.options.frame

		}).setStyle('display', 'none').injectInside($E('form'));

		// Create action

		if(this.options.action){

			this.action = new Element('input', {

				'type' 	: 'hidden',

				'id' 	: this.options.frame + '_action',

				'name'	: 'action',

				'value'	: this.options.action

			}).injectInside($E('form'));

		}

		// Change frame name

		if(window.ie){

			window.frames[this.frame.id].name = this.frame.name;

		}

		this.options.form.setAttribute('target', this.frame.name);

		// Add submit event

		this.options.form.addEvent('submit', function(){

			this.fireEvent('onStart');

		}.bind(this));

		// Add load event

		this.frame.addEvent('load', function(){

			var f 	= $(this.frame);

			var el 	= f.contentWindow.document || f.contentDocument || window.frames[f.id].document;

			if(el.location.href == 'about:blank') return;

			var res = el.body.innerHTML;

			if(res !== ''){

				this.fireEvent('onComplete', Json.evaluate(res, true));

			}

			// Remove existing frame

			if(this.options.cleanup){

				this.remove();

			}

		}.bind(this))

		// Auto submit

		if(this.options.auto){

			this.submit();	

		}

	},

	remove : function(){

		// Remove existing frame

		if($(this.options.frame)){

			$(this.options.frame).remove();	

		}

		// Remove existing action

		if($(this.options.frame + '_action')){

			$(this.options.frame + '_action').remove();

		}

	},

	submit : function(){

		this.fireEvent('onStart');

		this.options.form.submit() || $E('form').submit();

	}

});

IFrame.implement(new Options, new Events);