/* -------------------------------------------------------------------------- */
/* -------------------------- ajax function --------------------------------- */
/* -------------------------------------------------------------------------- */

var mfAjax = 
{
    numberOfRequests: 0,

    reqs: {firstOnly:{}, lastOnly:{}},
    requestId: 0,
    
    action: function (data)
    {
        var request = {
            type: 'post',
            url: null,            
            data: null,
            dataType: 'json',
            success: mfAjax.handler,
            error: mfAjax.handleError,
            complete: mfAjax.complete,
            cache: false,
            // our options
            mfType: '',
            mfTypeId: '',
            mfRequestId: ++mfAjax.requestId,
            mfCallbacks: []
        };

        if (typeof(data.obj) == 'object') {
        }
        if (typeof(data.url) != 'undefined') {
            request.url = data.url;
        } else {
            request.url = data.obj.href;   
        }
        if (typeof(data.data) != 'undefined') {
            request.data = data.data;
        }

        // special request?
        if (typeof(data.type) != 'undefined') {
            switch (data.type) {
            case 'lastOnly':
                request.mfType = 'lastOnly';
            break;
            case 'firstOnly':
                request.mfType = 'firstOnly';
            break;
            default:
                alert('Bad request type!');
                return;
            }
            if (typeof(data.id) != 'undefined')
                request.mfTypeId = data.id;
            else
                request.mfTypeId = request.url;
        }
        // callbacks
        if (typeof(data.callback) != 'undefined') {
            if (typeof(data.callback) == 'function') {
                request.mfCallbacks = [data.callback];
            } else {
                request.mfCallbacks = data.callback;
            }
        }

        if (typeof(data.data) != 'undefined') {
            request.data = data.data;
        }
        if (typeof(data.dataExtra) == 'object') {

            for (var i in data.dataExtra) {
            	if (i.substring(0,1) == "#") {
            	   
            		if ($("#" + data.dataExtra[i]).attr('multiple') == true) {
            			if ($("#" + data.dataExtra[i]).attr('type') == "select-multiple") {
           				
	            			$("#" + data.dataExtra[i] + " option").each( function () {
	            				data.data[i.substring(1) + "[" + $(this).val() + "]"] = $(this).attr('selected') == true ? 1 : '';
	            			})
	            		} else {
            		
	            			if ($("#" + data.dataExtra[i]).val()) {
	            				data.data[i.substring(1) + "[]"] = $("#" + data.dataExtra[i]).val();
							}
						}            		
            		} else {
            			data.data[i.substring(1)] = $("#" + data.dataExtra[i]).val();
            		}
            	}                
            }
        }
        mfAjax.sendRequest(request);
        return false;
    },

    sendRequest: function (request)
    {
        // check firstOnly
        if (request.mfType=='firstOnly' && mfAjax.reqs.firstOnly[request.mfTypeId]){
            //debug('Aborting req. because firstOnly');
            return;
        }
        // create request
        var xhr = jQuery.ajax(request);
        // debug('Sending req. id: '+request.mfRequestId);
        // check lastOnly
        if (request.mfType=='lastOnly') {
            if (mfAjax.reqs.lastOnly[request.mfTypeId]) {
                //debug('Aborting previous req. because lastOnly');
                mfAjax.reqs.lastOnly[request.mfTypeId].abort();
                mfAjax.endRequest();
            }
            mfAjax.reqs.lastOnly[request.mfTypeId] = xhr;
        }
        if (request.mfType=='firstOnly') {
            mfAjax.reqs.firstOnly[request.mfTypeId] = xhr;
        }
        ++ mfAjax.numberOfRequests;
        mfAjax.showCounter();
        $("#ajax_loading").show();
    },

    complete: function (XMLHttpRequest, textStatus) {
      // this; // the options for this ajax request
      // debug('Received id: '+this.mfRequestId);
    },

    handler: function (data, textStatus)
    {
        // check and clean last/first registry
        if (this.mfType=='lastOnly') {
            if (!mfAjax.reqs.lastOnly[this.mfTypeId])
                return;
            delete mfAjax.reqs.lastOnly[this.mfTypeId];
        }
        if (this.mfType=='firstOnly') {
            delete mfAjax.reqs.firstOnly[this.mfTypeId];
        }

        mfAjax.endRequest();

        // JS callbacks
        for (var i=0; i<this.mfCallbacks.length; ++i) {
            this.mfCallbacks[i](data);
        }

    	if (data.handler) {
    		var handlerFunction = new Function('data', data.handler + '(data);');
    		handlerFunction(data);
    	} else {
            if (data.snippet) {
                for (var i in data.snippet) {
                	mfAjax.setSnippet(i, data.snippet[i]);
                }
            } 
            if (data.select) {
            	for (var i in data.select) {
            		mfAjax.setSelect(i, data.select[i].options, data.select[i].selected);
            	}        	
            }      
            if (data.text) {
            	for (var i in data.text) {
            		mfAjax.setValue(i, data.text[i]);            			
            	}
            }
            if (data.show) {
            	mfAjax.setByFunction(data.show, 'show');
            }
            if (data.hide) {
            	mfAjax.setByFunction(data.hide, 'hide');
            }
            if (data.toggle) {
            	mfAjax.setByFunction(data.toggle, 'toggle');
            }
            if (data.remove) {
            	mfAjax.setByFunction(data.remove, 'remove');
            }
            if (data.alert) {
            	for (var i in data.alert) {
            		alert(data.alert[i]);
            	}
            }
            if (data.callback) {
                eval( data.callback.join('') );
            }
    	}
    },
    
    handleError: function (XMLHttpRequest, textStatus, errorThrown)
    {
        mfAjax.endRequest();
        // alert(textStatus);
    },

    endRequest: function ()
    {
        if (--mfAjax.numberOfRequests == 0) {
            $("#ajax_loading").hide();
        }
        mfAjax.showCounter();
    },

    showCounter: function ()
    {
        /*
        var dbg = ' lo:';
        for (i in mfAjax.reqs.lastOnly)
            dbg += i+' ';
        dbg += 'fo:';
        for (i in mfAjax.reqs.firstOnly)
            dbg += i+' ';
        $("#id_counter").text(mfAjax.numberOfRequests + dbg);
        */
        $("#id_counter").text(mfAjax.numberOfRequests);
    },
    
    setSnippet: function (snippetId, snippetHtml) 
    {
    	$("#" + snippetId).html(snippetHtml);	
    },
    
    setSelect: function (selectId, selectOptions, selectSelected)
    {
		if (selectOptions) {
			$("#" + selectId + " option").remove();
			for (var k in selectOptions) {
				var newOption = document.createElement('option');
				newOption.value = k;
				newOption.appendChild(document.createTextNode(selectOptions[k]));
				$("#" + selectId).append(newOption);
			}
			if (selectSelected) {
				$("#" + selectId).val(selectSelected);
			}
		}    	
    },
    
    setValue: function (objId, objValue) 
    {
    	$("#" + objId).val(objValue);    	
    },
    
    setByFunction: function (obj, fun)
    {
    	if (obj && typeof(obj) != "object") {
    		obj = new Array(obj);
    	}
    	
    	for (var i in obj) {
    		if (fun == "show") {
    			$(obj[i]).show();
    		} else if (fun == "hide") {
    			$(obj[i]).hide();
    		} else if (fun == "toggle") {
    			$(obj[i]).toggle();
    		} else if (fun == "remove") {
    			$(obj[i]).remove();
    		}
    		
    	}
    }
    
};

/* -------------------------------------------------------------------------- */
/* -------------------------- other function -------------------------------- */
/* -------------------------------------------------------------------------- */

function formTableCreateElement(formTableId, formTableElements, formNamePrefix, formIdPrefix, formIgnoreRow, formTableLabels)
{
    $("#" + formTableId).append( form_element );
    formTableReCalculateElement(formTableId, formTableElements, formNamePrefix, formIdPrefix, formIgnoreRow, formTableLabels);
    return false;
}

function formTableAddElement(obj, formTableId, formTableElements, formNamePrefix, formIdPrefix, formIgnoreRow, formTableLabels)
{
    $(obj).parents("tr:first").after( form_element );
    formTableReCalculateElement(formTableId, formTableElements, formNamePrefix, formIdPrefix, formIgnoreRow, formTableLabels);
    return false;
}

function formTableRemoveElement(obj, formTableId, formTableElements, formNamePrefix, formIdPrefix, formIgnoreRow, formTableLabels)
{
    $(obj).parents("tr:first").remove();
    formTableReCalculateElement(formTableId, formTableElements, formNamePrefix, formIdPrefix, formIgnoreRow, formTableLabels);
    return false;
}

function formTableReCalculateElement(formTableId, formTableElements, formNamePrefix, formIdPrefix, formIgnoreRow, formTableLabels) 
{
    var trNumber = 0;

	if (typeof(formIgnoreRow) == 'undefined') {
		formIgnoreRow = 0;
	}    
    if (typeof(formTableLabels) == 'object') {
        var tdRegExp = new Object;
        var tdRegExpText = '';
        var tdRegExpResult;
        for (var tdLabel in formTableLabels) {
            tdRegExp[tdLabel] = new RegExp('^' + formTableLabels[tdLabel] + '$');
        }
    }
    
    $("#" + formTableId).find("tr").each( function () 
    {
        if (formIgnoreRow <= 0) {
            trNumber++;
	        for (var trElement in formTableElements) {
	            $(this).find("[name*='" + formNamePrefix + formTableElements[trElement] + "']").each ( function ()
	            {
	                $(this).attr("id", formIdPrefix + formTableElements[trElement] + trNumber);
	                $(this).attr("name", formNamePrefix + formTableElements[trElement] + trNumber + ']');
	            });            
	        }   
	        if (tdRegExp) {
	            $(this).find("td").each( function ()
	            {
	                for (var tdRegExpNum in tdRegExp) {
	                    tdRegExpText = $(this).html();
	                    tdRegExpResult = tdRegExpText.match(tdRegExp[tdRegExpNum]);
	                    
	                    if (tdRegExpResult && typeof(tdRegExpResult) == 'object') {
	                    	if (tdRegExpResult.length < 3) {                    		
	                    		$(this).html( trNumber );                    		
	                    	} else {                 		
	                    		$(this).html( tdRegExpText.replace(tdRegExp[tdRegExpNum], '$1 ' + trNumber) );	
	                    	}
	                    }
	                }
	            });        
	        }
        } else {
        	formIgnoreRow--;
        }
    });    
    return false;
}

/* -------------------------------------------------------------------------- */
/* -------------------------- jquery extends -------------------------------- */
/* -------------------------------------------------------------------------- */

jQuery.fn.extend({
    
    mfSelectAllOptions: function() {
        return $(this).find('option').each( function(){
            $(this).attr('selected', true); 
        });
    },
      
    mfAppendSelectedOptions: function(destSelector) {
        $(this).find('option:selected').each( function(){                            
            if ($(destSelector).find('option[value=' + $(this).val() + ']').length == 0) {
                $(this).appendTo(destSelector);
            }
        });
        return true;
    },

    mfCopySelectedOptions: function(destSelector) {
        $(this).find('option:selected').each( function(){                            
            if ($(destSelector).find('option[value=' + $(this).val() + ']').length == 0) {
                $(this).clone().appendTo(destSelector);
            }
        });
        return true;
    },

    mfRemoveSelectedOptions: function() {
        $(this).find('option:selected').remove();
    }
    
});
