// Display tooltip with specified content.
//
// Requirements:
//	jquery.qtip-2.0.js, jquery.qtip.tips.js from common_tools, jquery.qtip.css from common_layout
// Syntax:
//  SmartTip.create(target, content, buttons, options)
// Parameters
// 	target:		Element (elements) you want to apply a tooltip.
// 	content:
// 		string: content will be set to that string.
// 		array:  array of options like {text: 'some content', title: 'some title', button: 'close'}, where the button
// 						is a close-button string, set it to true(recomended) if you want to use default img style close-button
// 		callback:
//					 	Use 'this.content' inside your callback function to access to content.
//
//  buttons:  List of buttons with callbacks. [{_('OK'): function(){ //do something } }]
// 	options: 	Overrides Smart.defaults for more options look at http://craigsworks.com/projects/qtip_new/
//
// Examples:
//		var fooBar = function(){this.content.append('add some content')}
//		custom_options = {
// 			events: {
//				hide: function(){
//					// do_something
//				}
//			}
// 		}
// 		SmartTip.create("div[id^='page_assign_holder']", fooBar, custom_options);
//
//		custom_options = {
//			show: 'mouseover',
//			hide: {
//				event: "mousedown mouseup mouseleave"
//			}
// 		}
//		SmartTip.create("#some_id", 'content', custom_options);
//    SmartTip.create("#some_id", {text: 'content', title: {text: 'bar', button: 'close'}}, custom_options);
//
//  Buttons Usage:
//    Buttons can be set like in jQuery Dialog:
//			Like an array:
//				[{'text': _('OK'), 'click': function(){}}, {'text': _('Cancel'), 'click': function(){}}]
//			Like a hash:
//				{'OK', function(){}}
//    SmartTip.create("#some_id", 'content', [{'text': 'OK', 'click': function(){alert('yo')}}], {});
//		Buttons are optional, but if you set buttons you must send options too !
//
//  Setting Title:
//		The content is set by 'content' param but to set title you must set options['content']['title']
//    	example: options = {content: title:{ text: 'title!', button: true}}
//		Use close button without any title.
//    	example: options = {content: title:{ text: true, button: true}}
//
//	More Docs for custom options:
//	http://craigsworks.com/projects/qtip_new/
//	http://craigsworks.com/projects/qtip_new/tutorials/advanced/
//	Default qtip options : http://craigsworks.com/projects/qtip_new/tutorials/advanced/#override

// Check qTip library is present
if (!$j.fn.qtip) {
	throw new Error('This plugin requires the qTip library.', '');
}

var SmartTip = {
	create: function(target, content, buttons, options) {
		var renderCallback;
		var contentCallback;

		// content is set by 'content' param but remember ['content']['title'] if is defined.
		if (options !== undefined && options['content'] !== undefined && options['content']['title'] !== undefined) {
			options['content']['text'] = ' ';
			if (options['content']['title']['text'] === undefined) {
				options['content']['title']['text'] = ' ';
			}
		}

		// buttons are optional, but if you set buttons you must send options too !
		if (options === undefined && $j.isObject(buttons)) {
			options = buttons;
			buttons = undefined;
		}

		var merged_options = $j.extend({}, SmartTip.defaults, options);

		if (!(content === undefined)) {
			if ((merged_options['events'] === undefined)) {
				merged_options['events'] = {}
			}

			//set render callback if is set
			if (merged_options['events'] && typeof(merged_options['events']['render']) == 'function') {
				renderCallback = merged_options['events']['render'];
			}

			//set content by content param type
			if (content['text'] || content['url']) {
				merged_options['content'] = content;
			}
			else if (typeof(content) == 'function') {
				contentCallback = content;
			}
			else if (typeof(content) == 'string') {
				merged_options['content']['text'] = content;
			}
		}

		// set finally render callback
		merged_options['events']['render'] = function(event, api) {
			// call content callback if is set.
			if ((contentCallback !== undefined)) {
				contentCallback.call({content: api.elements.content, api: api});
			}

			function addButton(api, footer, tag, callback) {
				if(typeof tag==="string") {
					var name = tag;
					tag = $j("<input type='submit'>");
					tag.attr({'name': name, 'value': name});
				}
				footer.append(tag);
				tag.click($j.proxy(callback, api));
			}

			// set footer with buttons.
			if (!(buttons === undefined)) {
				var footer = $j("<div>").attr({'class': "ui-tooltip-buttons ui-tooltip-footer"});
				api.elements.wrapper.append(footer);

				if (buttons instanceof Array) {
					for (var i = 0; i < buttons.length; i++) {
						if ( buttons[i]['text'] !== undefined && buttons[i]['click'] !== undefined ) {
							addButton(api, footer, buttons[i]['text'], buttons[i]['click']);
						}
					}
				}
				else {
					for (var button in buttons) {
						addButton(api, footer, button, buttons[button]);
					}
				}
			}
			// IE hack. Need to update content this way for width recalculate.
			api.set('content.text', api.elements.content.html());
			api.reposition();

			// enter key hide the tooltip.
			api.elements.content.find("input:text").keydown(function(event) {
				if (event.keyCode == 13) {
					api.hide();
				}
			})

			// call merged_options['events']['render'] if is set.
			if ((renderCallback !== undefined)) {
				renderCallback.call({content: api.elements.content, api: api});
			}
		};

		var tip = $j(target).qtip(merged_options);
		SmartTip.api = tip.qtip();
		return this;
	},
	defaults: {
		content: {
			text: "SmartTip"
		},
		style: {
			classes: "ui-tooltip-plain",
			tip: {
				corner:true,
				border: 1,
				height: 15,
				width: 15
			}
		},
		show: {
			ready: false,
			delay: 0,
			solo: true,
			event: "mouseup"
		},
		hide: {
			event: "unfocus"
		},
		position: {
			target: "mouse",
			at: "right center",
			my: "left center",
			adjust: {
				x: 20,
				screen: true,
				mouse: false,
				resize: true
			}
		},
		prerender: false
	},
	update: function(content) {
		SmartTip.api.set('content.text', content);
	}
};

/**
 * QTip Extension - additional api methods: back, front
 * qtip('back') - move qtip to back (reduce z-index)
 * qtip('front') - move qtip to front (revert original z-index)
 */

$j.fn.qtip.plugins.front_back = function(qTip) {
	$j.extend(qTip, {
		back: function() {
			qTip.elements.tooltip.css('z-index', function(i, value) {
				value = parseInt(value);
				if (value > $j.fn.qtip.zindex) {
					return value - $j.fn.qtip.zindex + 10; // 10 is enough for dynamic layout to see the element
				} else {
					return value;
				}
			});
		},
		front: function() {
			qTip.elements.tooltip.css('z-index', function(i, value) {
				value = parseInt(value);
				if (value < $j.fn.qtip.zindex) {
					return value + $j.fn.qtip.zindex - 10; // 10 is enough for dynamic layout to see the element
				} else {
					return value;
				}
			});
		}
	});
};
$j.fn.qtip.plugins.front_back.initialize = 'render';


