/* -------------------------------------------------------------------------- */
/* -------------------------- 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) == "#") {            		
            		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.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);    	
    }
};

/* -------------------------------------------------------------------------- */
/* -------------------- cities function and init----------------------------- */
/* -------------------------------------------------------------------------- */

var cities = {

    ROTATION_DELAY: 9000,
    WAIT_DELAY: 100,
    MAX_AGE: (5 * 60 * 1000), //5 minutes

    list: null,
    timeOut: null,
    next: null,
    data: {},
    preloading: {},
    displayIdx: 0,
    imgUrlBase: null, //NETTE_CONST.imgUrlBase,

    init: function() {
        if(typeof NETTE_CONST == 'undefined') {
            return;
        }
        this.imgUrlBase = NETTE_CONST.imgUrlBase;
        /*{* Get list of all areas *}*/
        this.list = $('#cities-map area');
        this.fisherYates(this.list);
        this.showNext();
    },

    /* Fisher-Yates shuf1;3Bfle algorithm,
       taken from here:
         http://sedition.com/perl/javascript-fy.html
    */
    fisherYates: function( myArray ) {
        var i = myArray.length;
        if ( i == 0 ) return false;
        while ( --i ) {
            var j = Math.floor( Math.random() * ( i + 1 ) );
            var tempi = myArray[i];
            var tempj = myArray[j];
            myArray[i] = tempj;
            myArray[j] = tempi;
        }
    },

    preloadCity: function(ajaxUrl) {
        /*{* Ajax preload of top story *}*/
        var forceUpdate = false;
        var oldTs = cities.preloading[ajaxUrl];
        var newTs = (new Date).getTime();
        if(oldTs && ( (newTs - oldTs) < cities.MAX_AGE)) {
            return;
        } else {
            forceUpdate = true;
        }

        cities.preloading[ajaxUrl] = newTs; //true;
	
        if(forceUpdate) {
            mfAjax.action({
                'obj': this,
                'url': ajaxUrl,
                'callback': function(data) {
                    cities.data[ajaxUrl] = data.result;
                }
            });
        }
    },
    show: function(city, options) {

        /*{* Enter critical section - this code should not be running more than once. *}*/
        if (!$('#selected-city div.bg:not(.processing)').addClass('processing').length) {
            /*{* But keep information what city to show as next once we are over *}*/
            this.next = city;
            return;
        }
        this.next = null;

        var title = $(city).attr('x_alt');
        var ajaxUrl = this.getAjaxUrl(city);

        if(typeof cities.data[ajaxUrl] == 'undefined') {
            this.preloadCity(ajaxUrl);
            var me = this;

            $('#selected-city div.bg').removeClass('processing');
            this.timeOut = setTimeout( function() {
                me.show(city, options);
            }, me.WAIT_DELAY);
            return;
        }

        $('#selected-city').hide();
        /*{* Fade out so that we can later fade in *}*/
        $('#selected-city div.bg').fadeTo(0,0);

        /* {* show the contents *} */
        $('#topstory-location').text( $(city).attr('x_alt') );
        $('#topstory-contents').fadeOut( options.fast?'fast':'slow', function (){
            var topStory = cities.data[ajaxUrl];
            if (typeof topStory.image == 'undefined')
            if(topStory == null) {
                return;
            }
            if (typeof topStory.perex == 'undefined') {
                topStory.perex = '';
                topStory.title = '';
            }
            $('#topstory-perex').text(topStory.perex);
            $('#topstory-contents a').text(topStory.title);
            var articleUrl = topStory.url;
            $('#topstory-contents a').attr('href', articleUrl);
            if( (typeof topStory.image == 'undefined')
                || (typeof topStory.image.formats == 'undefined')
                || (typeof topStory.image.formats.art_mega == 'undefined') ) {
                $('#topstory-contents img').css('display', 'none');
            } else {
                var imgUrl = cities.imgUrlBase + topStory.image.formats.art_mega.filename;
                $('#topstory-contents img').attr('src', imgUrl);
                $('#topstory-contents img').attr('width', topStory.image.formats.art_mega.width);
                $('#topstory-contents img').attr('height', topStory.image.formats.art_mega.height);
                $('#topstory-contents img').attr('alt', topStory.image.description);
                $('#topstory-contents img').css('display', 'inline');
            }

            $(this).fadeIn( 'slow' );
        });

        $('#selected-city .text').html( title );
        $('#selected-city').parent('a').attr('href', city.href);

        /*{* Set position using css - the associative array contains multiple properties *}*/
        $('#selected-city').css( this.getPosition(city) ).show();

        var oThis = this;

        $('#selected-city div.bg').fadeTo(700,0.80, function (){
            /*{* Leave critical section *}*/
            $(this).removeClass('processing');
            if (oThis.next) {
                oThis.show(oThis.next, options); //this will jump right in (mouseover on map)
            } else if (options.schedule) {
                oThis.scheduleNext();
            }
        });
    },

    showNext: function(options) {
        this.displayIdx += 1;
        if(this.displayIdx >= this.list.length) {
            this.displayIdx = 0;
        }
        this.showIdx(options);
    },

    showPrevious: function(options) {
        this.displayIdx -= 1;
        if(this.displayIdx < 0) {
            this.displayIdx = this.list.length - 1;
        }
        this.showIdx(options);
    },

    getAjaxUrl: function(city) {
        var url = city.href;
        if (url.match('\\?')) {	    
            url = url + '&action=getTopStory';
        } else {
            url = url + 'topStory';
        }    
        return url;
    },

    showIdx: function(options) {
        if(typeof options == 'undefined') {
            options = { schedule: true };
        }
        var city = this.list[this.displayIdx];
        this.preloadCity(this.getAjaxUrl(city));
        this.show(city, options);
    },

    getPosition: function(city) { 
        var coords = []; 
        jQuery.each( city.coords.split(','), function(){
            coords.push( parseInt( this, 10 ) );
        });
        /*{* use css to set position *}*/
        var position = $('#cities-bg').position();
        var radius = coords[2];
        var newPosition = {
            left: coords[0] + position.left - radius,
            top: coords[1] + position.top - radius
        };
        return newPosition;
    },

    cancelRotate: function() {
        clearTimeout( this.timeOut );
    },

    scheduleNext: function() { 
        clearTimeout( this.timeOut );
        var oThis = this;
        this.timeOut = setTimeout( function() {
            oThis.showNext();
        }, this.ROTATION_DELAY);
    },

    clickBack: function() {
        this.showPrevious({ fast: true});
    },

    clickFwd: function() {
        this.showNext({ fast: true});
    }
};

/*{* Executed on document ready *}*/
$(function() {
    $('#cities-map area').each( function() {
        $(this).attr('x_alt', this.alt);
        $(this).removeAttr('alt');
    });

    $('#cities-map area').mouseover( function(){
        cities.cancelRotate();
        cities.show(this, { fast: true});
    });

    $('#selected-city').mouseout( function(){
        $(this).hide();
        cities.scheduleNext();
    });

    $('#cities-map area').mouseout( function(){
        if(this == cities.next) {
            cities.scheduleNext();
        }
    });

    $('#topstory-history').mouseout( function() {
        cities.scheduleNext();
    });

    $('#topstory-history').mouseover( function() {
        cities.cancelRotate(true);
    });

    cities.init();
});
/* -------------------------------------------------------------------------- */
/* -------------------------- 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({
	
	mfSelectAllOption: function() {
		return $(this).find('option').each(function() {
			$(this).attr("selected", true); 
		});
	},
	  
	mfCopyOption: function(idTo) {
		$(this).find('option:selected').each(function() {			  		  		 
			if($('#' + idTo + ' option[value=' + $(this).val() + ']').size() == 0) {
				$(this).appendTo('#' + idTo);
			}
		});
		return true;
	},
	  
	mfRemoveOption: function() {
		$(this).find('option:selected').remove();
	}
});
