/**
 * @requires {Cobalt.Core}
 * @requires {jQuery}
 * @requires {liveQuery}
 *
 * 
 * Provides dom searching and manipulation services
 * @constructor
 */
Cobalt.Core.JQueryDomService = function(specificVersion)
{
    if (!jQuery && !specificVersion) { throw new Error("JQueryDomService requires jQuery library to be loaded"); }

    this.domQuery = !specificVersion ? Cobalt.Core.JQueryFactory.getLatest() :
        Cobalt.Core.JQueryFactory.getSpecificVersion(specificVersion.major, specificVersion.minor, specificVersion.build);

	this.domQueryLegacy = Cobalt.Core.JQueryFactory.getLegacy();
    this.domCache = new Array();
    var jqueryVersion = this.domQuery().jquery;
    var jqueryMinorVersion = jqueryVersion.substr(jqueryVersion.indexOf("1.")+2);

    if (jqueryMinorVersion.charAt(0) < 4) { throw new Error("JQueryDomService requires jQuery library 1.4 or greater to be loaded"); }
};
/**
 *
 * @param {String} id
 * @return {HTMLElement}
 */
Cobalt.Core.JQueryDomService.prototype.getElementById = function(id)
{
    return document.getElementById(id);
};
/**
 * Attach a handler for the given dom element on the event
 * example:
 *    service.listen(newCategoryElement, "click", onNewCategorySeleced, this);
 *
 * @param {Object} anchor could be null
 * @param {String} eventName
 * @param {Function} handler
 * @param {Object} data
 */
Cobalt.Core.JQueryDomService.prototype.listen = function(anchor, eventName, handler, data)
{
    anchor = (!anchor) ? document : anchor;
    this.domQuery(anchor).bind(eventName, data, handler);   
};

Cobalt.Core.JQueryDomService.prototype.removeListeners = function(anchor, eventName)
{
    anchor = (!anchor) ? document : anchor;
    this.domQuery(anchor).unbind(eventName);
    this.domQuery(anchor).unbind(eventName);
};

/**
 * Triggers an event on the anchor object
 * example:
 *    app.raise(anyAnchor, eventName, anyData);
 *
 * @param {Object} anchor nullable, if null, then broadcast an event
 * @param {String} eventName
 * @param {Object} data
 */
Cobalt.Core.JQueryDomService.prototype.raise = function(anchor, eventName, data)
{
    anchor = (!anchor) ? document : anchor;
    this.domQuery(anchor).trigger({
            type:eventName,
            customData:data
        });
};
/**
 * Works with xml and Html element. Returns attributeName if attributeValue not set
 * @param {DomElement} element
 * @param {String} attributeName
 * @param {String} attributeValue
 */
Cobalt.Core.JQueryDomService.prototype.attr = function(element, attributeName, attributeValue)
{
    if((attributeName === "checked"||attributeName === "disabled"||attributeName === "selected") && attributeValue===''){
            return this.domQuery(element).attr(attributeName, false);
    }
	if(attributeValue || attributeValue==="")	return this.domQuery(element).attr(attributeName, attributeValue);
	
	else	return this.domQuery(element).attr(attributeName);
};
/**
 *
 * @param {DomElement} element
 * @param {String} replacementHtmlString
 */
Cobalt.Core.JQueryDomService.prototype.html = function(element, replacementHtmlString)
{
    return this.domQuery(element).html(replacementHtmlString).show();
};
/**
 *
 * @param {DomElement} element
 * @param {String} replacementWith String
 */
Cobalt.Core.JQueryDomService.prototype.replaceWith = function(element, replacementWithString)
{
    return this.domQuery(element).replaceWith(replacementWithString);
};

/**
 *
 * @param {DomElement} element
 * @return {String}
 */
Cobalt.Core.JQueryDomService.prototype.text = function(element, param)
{
    return this.domQuery(element).text(param);
};
/**
 * iterate through child elements and execute the func
 * @param {DomElement Collection} elements
 * @param {Function} func
 */
Cobalt.Core.JQueryDomService.prototype.each = function(elements, func)
{
    this.domQuery(elements).each(func);
};
Cobalt.Core.JQueryDomService.prototype.load = function(elements, func)
{
    this.domQuery(elements).load(func);
};
Cobalt.Core.JQueryDomService.prototype.error = function(elements, func)
{
    this.domQuery(elements).error(func);
};
/**
 *
 * @param {String} elementQuery
 * @param {String} event
 * @param {Function} handler
 */
Cobalt.Core.JQueryDomService.prototype.listenLive = function(elementQuery, event, handler, context)
{
    if (typeof(context) === "undefined")
    {
        this.domQuery(elementQuery, document).live(event, handler);
    }
    else
    {
        this.domQuery(context).delegate(elementQuery, event, handler);
    }
};
/**
 * @param {String} attributeName
 * @param {String} attributeValue if this is null or undefined, all elements having attributeName will be returned
 * @return {Array<DomElements>} array of DomElements
 */
Cobalt.Core.JQueryDomService.prototype.getElementsByAttribute = function(attributeName, attributeValue)
{
    if (attributeValue)
    {
        return this.domQuery("["+ attributeName + "~='" + attributeValue + "']");
    }
    else
    {
                                             
        return  this.domQuery("["+ attributeName +"]");
    }
};
/**
 *
 * @param {String} Raw XML data
 * @return Serialised XML data
 */
Cobalt.Core.JQueryDomService.prototype.getXmlElementTextValue = function(xmlElement)
{
    if (!xmlElement.firstChild) { return ""; }
    return xmlElement.firstChild.nodeValue;
};
/**
 *
 * @param {DomElement} element
 * @param {String} parameter
 * @return true or false
 */
Cobalt.Core.JQueryDomService.prototype.is = function(element, param)
{
    return this.domQuery(element).is(param);
};
/**
 *
 * @param {DomElement} element
 * @param {String} or {Number} parameter
 */
Cobalt.Core.JQueryDomService.prototype.show = function(element, param)
{
    return this.domQuery(element).show(param);
};
/**
 *
 * @param {DomElement} element
 * @param {String} or {Number} parameter
 */
Cobalt.Core.JQueryDomService.prototype.hide = function(element, param)
{
    return this.domQuery(element).hide(param);
};
Cobalt.Core.JQueryDomService.prototype.animate = function(element, properties, duration, effect, callback)
{
    return this.domQuery(element).animate(properties, duration, effect, callback);
};
Cobalt.Core.JQueryDomService.prototype.slideUp = function(element, callback, options)
{
    var defaults = {
        duration:"slow",
        easing:"easeInQuad",
        complete: callback
    };
    var opts = this.domQuery.extend(defaults, options);
    return this.domQuery(element).slideUp(opts);
};
Cobalt.Core.JQueryDomService.prototype.slideDown = function(element, callback, options)
{
    var defaults = {
        duration:"slow",
        easing:"easeOutQuad",
        complete: callback
    };
    var opts = this.domQuery.extend(defaults, options);
    return this.domQuery(element).slideDown(opts);
};
Cobalt.Core.JQueryDomService.prototype.slideToggle = function(element, callback, options)
{
    var defaults = {
        duration:"fast",
        easing:"easeOutQuad",
        complete: callback
    };
    var opts = this.domQuery.extend(defaults, options);
    return this.domQuery(element).slideToggle(opts);
};

Cobalt.Core.JQueryDomService.prototype.fadeIn = function(element, duration, callback)
{
    return this.domQuery(element).fadeIn(duration, callback);
};
Cobalt.Core.JQueryDomService.prototype.fadeOut = function(element, duration, callback)
{
    return this.domQuery(element).fadeOut(duration, callback);
};
/**
 *
 * @param {DomElement} element
 * @param {String} parameter
 */
Cobalt.Core.JQueryDomService.prototype.find = function(element, param)
{
    return this.domQuery(element).find(param);
};
Cobalt.Core.JQueryDomService.prototype.children = function(element, param)
{
    return this.domQuery(element).children(param);
};
Cobalt.Core.JQueryDomService.prototype.parents = function(element, param)
{
    return this.domQuery(element).parents(param);
};
Cobalt.Core.JQueryDomService.prototype.closest = function(element, param)
{
    return this.domQuery(element).closest(param);
};
Cobalt.Core.JQueryDomService.prototype.prependTo = function(element, param)
{
    return this.domQuery(element).prependTo(param);
};
Cobalt.Core.JQueryDomService.prototype.length = function(element)
{
    return this.domQuery(element).length;
};
Cobalt.Core.JQueryDomService.prototype.size = function(element)
{
    return this.domQuery(element).size();
};
Cobalt.Core.JQueryDomService.prototype.get = function(element, param)
{
    return this.domQuery(element).get(param);
};
Cobalt.Core.JQueryDomService.prototype.width = function(element, param)
{
    return this.domQuery(element).width(param);
};
Cobalt.Core.JQueryDomService.prototype.outerWidth = function(element, param)
{
    return this.domQuery(element).outerWidth(param);
};

Cobalt.Core.JQueryDomService.prototype.height = function(element, param)
{
    return this.domQuery(element).height(param);
};

Cobalt.Core.JQueryDomService.prototype.outerHeight = function(element, param)
{
    return this.domQuery(element).outerHeight(param);
};

Cobalt.Core.JQueryDomService.prototype.scrollTop = function(element, param)
{
    return this.domQuery(element).scrollTop(param);
};
Cobalt.Core.JQueryDomService.prototype.scrollLeft = function(element, param)
{
    return this.domQuery(element).scrollLeft(param);
};
Cobalt.Core.JQueryDomService.prototype.scrollTo = function(x, y)
{
    return window.scrollTo(x, y);
};
Cobalt.Core.JQueryDomService.prototype.openLocation = function(uri)
{
    window.location = uri;
};
Cobalt.Core.JQueryDomService.prototype.next = function(element, param)
{
    return this.domQuery(element).next(param);
};
Cobalt.Core.JQueryDomService.prototype.prev = function(element, param)
{
    return this.domQuery(element).prev(param);
};
Cobalt.Core.JQueryDomService.prototype.removeClass = function(element, param)
{
    return this.domQuery(element).removeClass(param);
};
Cobalt.Core.JQueryDomService.prototype.removeAttr = function(element, param)
{
    return this.domQuery(element).removeAttr(param);
};
Cobalt.Core.JQueryDomService.prototype.not = function(element, param)
{
    return this.domQuery(element).not(param);
};
Cobalt.Core.JQueryDomService.prototype.addClass = function(element, param)
{
    return this.domQuery(element).addClass(param);
};
Cobalt.Core.JQueryDomService.prototype.hasClass = function(element, param)
{
    return this.domQuery(element).hasClass(param);
};
Cobalt.Core.JQueryDomService.prototype.index = function(element, param)
{
    return this.domQuery(element).index(param);
};

Cobalt.Core.JQueryDomService.prototype.getDomElements = function(element)
{
    return this.domQuery(element);
};
Cobalt.Core.JQueryDomService.prototype.createDomElement = function(element)
{
    return this.domQuery(element)[0];
};
Cobalt.Core.JQueryDomService.prototype.append = function(element, param)
{
    return this.domQuery(element).append(param);
};
Cobalt.Core.JQueryDomService.prototype.wrapAll = function(element, param)
{
    return this.domQuery(element).wrapAll(param);
};

Cobalt.Core.JQueryDomService.prototype.parseJSON = function(json)
{
	return this.domQuery.parseJSON(json);
};
Cobalt.Core.JQueryDomService.prototype.parent = function(element, param)
{
    return this.domQuery(element).parent(param);
};
Cobalt.Core.JQueryDomService.prototype.parents = function(element, param)
{
    return this.domQuery(element).parents(param);
};
Cobalt.Core.JQueryDomService.prototype.position = function(element)
{
    return this.domQuery(element).position();
};
Cobalt.Core.JQueryDomService.prototype.offset = function(element)
{
    return this.domQuery(element).offset();
};
Cobalt.Core.JQueryDomService.prototype.addStyle = function(element, param)
{
    return this.domQuery(element).css(param);
};
Cobalt.Core.JQueryDomService.prototype.css = function(element, prop, val)
{
    return this.domQuery(element).css(prop, val);
};
Cobalt.Core.JQueryDomService.prototype.remove = function(element, param)
{
    return this.domQuery(element).remove(param);
};
Cobalt.Core.JQueryDomService.prototype.empty = function(element, param)
{
    return this.domQuery(element).empty(param);
};
Cobalt.Core.JQueryDomService.prototype.detach = function(element, param)
{
    return this.domQuery(element).detach(param);
};
Cobalt.Core.JQueryDomService.prototype.before = function(element, param)
{
    return this.domQuery(element).before(param);
};
Cobalt.Core.JQueryDomService.prototype.innerHTML = function(element, param)
{
    return this.domQuery(element).html(param);

};
Cobalt.Core.JQueryDomService.prototype.val = function(element, param)
{
    return (typeof(param) != "undefined") ? this.domQuery(element).val(param) : this.domQuery(element).val();
};
Cobalt.Core.JQueryDomService.prototype.serialize = function(element)
{
    return this.domQuery(element).serialize();
};
Cobalt.Core.JQueryDomService.prototype.tabs = function(element, param, options)
{
	if(typeof(this.domQuery(element).tabs) != "function") return false;
    return this.domQuery(element).tabs(param, options);
};
Cobalt.Core.JQueryDomService.prototype.datepicker = function(element, param, options, val)
{
   if(typeof(this.domQuery(element).datepicker) != "function") return false;
   return this.domQuery(element).datepicker(param, options, val);
};
Cobalt.Core.JQueryDomService.prototype.dialog = function(element, param, options)
{
   if(typeof(this.domQuery(element).dialog) != "function") return false;
   return this.domQuery(element).dialog(param, options);
};
Cobalt.Core.JQueryDomService.prototype.tablesorter = function(element, options)
{
   if(typeof(this.domQuery(element).tablesorter) != "function") return false;
   return this.domQuery(element).tablesorter(options);
};
Cobalt.Core.JQueryDomService.prototype.carousel = function(element, func)
{
    return this.domQuery(element).jcarousel(func);
};
Cobalt.Core.JQueryDomService.prototype.bind = function(element, eventType, func)
{
    return this.domQuery(element).bind(eventType, func);
};
Cobalt.Core.JQueryDomService.prototype.click = function(element, func)
{
    return this.domQuery(element).click(func);
};
Cobalt.Core.JQueryDomService.prototype.focus = function(element, func)
{
    return this.domQuery(element).focus(func);
};
Cobalt.Core.JQueryDomService.prototype.blur = function(element, func)
{
    if(typeof func === 'undefined'){
         return this.domQuery(element).blur();
    }
    return this.domQuery(element).blur(func);
};
Cobalt.Core.JQueryDomService.prototype.clone = function(element)
{
    return this.domQuery(element).clone().get(0);
};
Cobalt.Core.JQueryDomService.prototype.extend = function(obj1, obj2)
{
    return this.domQuery.extend(true, obj1, obj2);
};
Cobalt.Core.JQueryDomService.prototype.extendNew = function(obj1, obj2, obj3)
{
    return this.domQuery.extend(obj1, obj2, obj3);
};
Cobalt.Core.JQueryDomService.prototype.globalMethod = function(name, callback)
{
    return window[name] = callback;
};
Cobalt.Core.JQueryDomService.prototype.appendTo = function(element, target)
{
    return this.domQuery(element).appendTo(target);
};
Cobalt.Core.JQueryDomService.prototype.data = function(element, key, value)
{
    return this.domQuery.data(element, key, value);
};
Cobalt.Core.JQueryDomService.prototype.submit = function(element, callback)
{

	return this.domQuery(element).submit(function(){		
		if( typeof( callback ) === "function" ){
			callback();
		}
	});
};
Cobalt.Core.JQueryDomService.prototype.browser = function()
{
    return this.domQuery.browser;
};
Cobalt.Core.JQueryDomService.prototype.scroll = function(element, callback)
{
    return this.domQuery(element).scroll(callback);
};
Cobalt.Core.JQueryDomService.prototype.scrollEnd = function(element) {
    var myDom;
    if(typeof(this.domCache[element]) != "undefined"){
       myDom = this.domCache[element];
    } else {
        myDom = this.domQuery(element);
    }
    return myDom[0].scrollHeight - myDom[0].scrollTop - myDom.height() <= 0;
};
Cobalt.Core.JQueryDomService.prototype.getJSON = function(url, data, callback) {
    this.domQuery.getJSON(url, data, callback);
};
Cobalt.Core.JQueryDomService.prototype.addDomCache = function(element) {
    this.domCache[element] = this.domQuery(element);
};
Cobalt.Core.JQueryDomService.prototype.support = function() {
    return this.domQuery.support;
};
Cobalt.Core.JQueryDomService.prototype.toggle = function(element,param) {
    return this.domQuery(element).toggle(param);
};
Cobalt.Core.JQueryDomService.prototype.die = function(element,param) {
    return this.domQuery(element).die(param);
};
Cobalt.Core.JQueryDomService.prototype.delay = function(element,param) {
    return this.domQuery(element).delay(param);
};
Cobalt.Core.JQueryDomService.prototype.trim = function(param) {
    return this.domQuery.trim(param);
};Cobalt.Core.JQueryDomService.prototype.getDomQueryInstance = function() {
    return this.domQuery;
};
Cobalt.Core.JQueryDomService.prototype.insertAfter = function(element,param) {
    return this.domQuery(element).insertAfter(param);
};
