var Fse; if (!Fse) Fse = {};

if (!Fse.Util) Fse.Util = {};

Fse.Util.addClass = function ( sElement, sClass ) {
	Spry.Utils.addClassName( sElement, sClass );
};

Fse.Util.removeClass = function( sElement, sClass ) {
	Spry.Utils.removeClassName( sElement, sClass );
};

Fse.Util.updateURL = function( sURL, oNewParameters ) {

	for( var sParam in oNewParameters ) {
		var sValue = oNewParameters[sParam];
		var sQueryStringParam = sParam + "=" + encodeURIComponent( sValue );
		
		var reParamSearch = new RegExp( sParam + "=", "i" );
		if( sURL.search( reParamSearch ) >= 0 ) {
			var rParam = new RegExp ( sParam + "=[^&]*", "i" );
			sURL = sURL.replace( rParam, sQueryStringParam );
		} else {
			if( sURL.length > 0 ) {
				sURL = sURL + "&" + sQueryStringParam;		
			} else {
				sURL = sQueryStringParam;
			}
		}
	}

	return sURL;
};


Fse.Util.makeHref = function( sNewQueryString, sParametersToSuppress ) {

	var sURL = window.location.pathname;
	var sQueryString = window.location.search.replace( /.*\?/, "" );
	
	
	var aParts = sNewQueryString.split( "&" );
	for( var iPartIdx = 0; iPartIdx < aParts.length; iPartIdx++ ) {
		
		var sQueryStringParam = aParts[iPartIdx];
		var aParsed = sQueryStringParam.split( "=" );
		var sParam = aParsed[0];
		var sValue = aParsed[1];

		var reParamSearch = new RegExp( sParam + "=", "i" );
		if( sQueryString.search( reParamSearch ) >= 0 ) {
			var rParam = new RegExp ( sParam + "=[^&]*", "i" );
			sQueryString = sQueryString.replace( rParam, sQueryStringParam );
		} else {
			if( sQueryString.length > 0 ) {
				sQueryString = sQueryString + "&" + sQueryStringParam;		
			} else {
				sQueryString = sQueryStringParam;
			}
		}
		
	}
	
	if( sParametersToSuppress ) {
		
		var aParameters = sParametersToSuppress.split( "," );
		var oParametersToSuppress = {}
		for( var pIdx = 0; pIdx < aParameters.length; pIdx++ ) {
			oParametersToSuppress[aParameters[pIdx].toLowerCase()] = true;						
		}
		
		var sNewQueryString = "";
		var aQueryStringParameters = sQueryString.split( "&" );
		for( var qIdx = 0; qIdx < aQueryStringParameters.length; qIdx++ ) {
			var aParts = aQueryStringParameters[qIdx].split( "=" );
			if( ! oParametersToSuppress[aParts[0].toLowerCase()]) {
				if( sNewQueryString != "" ) {
					sNewQueryString = sNewQueryString + "&";
				}
				sNewQueryString = sNewQueryString + aQueryStringParameters[qIdx];
			}
		}
		sQueryString = sNewQueryString;
	}

	var sLocation = sURL;
	if( sQueryString.length > 0 ) {
		sLocation = sLocation + "?" + sQueryString;
	}

	return sLocation;

};

Fse.Util.hasSVG = function() {
	var bHasSVG = false;
	if( window.ActiveXObject ){
		try {
			var xoSVG = new window.ActiveXObject( "Adobe.SVGCtl.3" );
			bHasSVG = true;
		} catch ( x ) {
			bHasSVG = false;
		}
	} else {
		bHasSVG = ( navigator.mimeTypes["image/svg"] ||
       				navigator.mimeTypes["image/svg+xml"] ||
       				navigator.mimeTypes["image/svg-xml"] );
	}	
	return bHasSVG;
};


Fse.trace = false;

Fse.PageManager = function( dataURL, dataSetName, options ){

    this._dataSetNames = {
        "Index" : dataSetName + "Index",
        "Data" : dataSetName,
        "Paging" : dataSetName + "Paging"
    };

    this._sortData = { 
        sortBy:undefined, 
        sortMode:"ascending" 
    };
    
    this._filters = {};
    
    this._dataURL = dataURL
    
    var pageSize = 25;

    this._pagingData = {
	    pageOffset:0,
		pageSize:pageSize,
		pageStop:pageSize, 
		rowCount:0,
		pageNumber:0,
		pageCount:0 
	};
	
	if( options != undefined ) {
    	this._applyOptions( options );
	}

    window[ this._dataSetNames["Index"]]
        = new Spry.Data.JSONDataSet( this.getIndexURL(), { useCache: false });
    window[ this._dataSetNames["Data"]] 
        = new Spry.Data.JSONDataSet( this.getDataURL(), { useCache: false });
        
    this._buildPagingDataSet();        

    var indexDataSet = this.getIndexDataSet();
    indexDataSet.addObserver( this );
    
    var dataDataSet = this.getDataDataSet();
    dataDataSet.addObserver( this );
    this._loadIndex();
};

Fse.PageManager.prototype.constructor = Fse.PageManager;

Fse.PageManager.prototype._applyOptions = function( options ) {
    for( key in options ) {
        if( key == "sort" ) {
            this._applySortOptions( options[key] );
        } else if ( key == "filter" ) {
            this._applyFilterOptions( options[key]);
        }
    }
};

Fse.PageManager.prototype._applyFilterOptions = function( filterOptions ) {
    for( key in filterOptions ) {
        this.setFilter( key, filterOptions[key]);
    }
};


Fse.PageManager.prototype._applySortOptions = function( sortOptions ) {
    for( key in sortOptions ) {
        if( key == "sortBy" ) {
            this._sortData.sortBy = sortOptions[key];
        }
        if( key == "sortMode" ) {
            this._sortData.sortMode = sortOptions[key];
        }
    }
};

Fse.PageManager.prototype._loadIndex = function() {
    var indexDataSet = this.getIndexDataSet();
    indexDataSet.setURL( this.getIndexURL() );
    indexDataSet.loadData();
};

Fse.PageManager.prototype._buildPagingDataSet = function() {

    window[ this._dataSetNames["Paging"]] 
        = new Spry.Data.DataSet();

    var pagingDataArray = [ this._pagingData ];
    pagingDataArray[0].ds_RowID = 0;

    var pagingDataHash = [];
    pagingDataHash[0] = pagingDataArray[0];
        
    var pagingDataSet = this.getPagingDataSet();        
    pagingDataSet.data = pagingDataArray;
    pagingDataSet.dataHash = pagingDataHash;
    
};

Fse.PageManager.prototype.getPagingDataSet = function() {
    return window[this._dataSetNames["Paging"]];    
};

Fse.PageManager.prototype.getDataDataSet = function() {
    return window[this._dataSetNames["Data"]];    
};

Fse.PageManager.prototype.getIndexDataSet = function() {
    return window[this._dataSetNames["Index"]];    
};


Fse.PageManager.prototype.onLoadError = function( dataSet, data ) {
    if( Fse.trace ) {
    	Spry.Debug.reportError( data.xhRequest.statusText );
    }
};

Fse.PageManager.prototype.onPostLoad = function( dataSet, data ) {

    if( dataSet == this.getIndexDataSet() ) {
        if( Fse.trace ) {
            Spry.Debug.trace( this.getIndexURL() );
        }

    	this._pagingData.pageOffset = 0;
    	this._pagingData.pageStop = this._pagingData.pageSize;
    
    	this._pagingData.rowCount = dataSet.getData().length;
    	
    	this._pagingData.pageNumber = 1;
    	this._pagingData.pageCount = Math.round( this._pagingData.rowCount / this._pagingData.pageSize );
    	if( this._pagingData.pageCount * this._pagingData.pageSize < this._pagingData.rowCount ) {
    		this._pagingData.pageCount++;
    	}
    	
    	if( this._pagingData.pageCount > 0 ) {
    		this._pagingData.pageNumber = 1;
    	} else {
    		this._pagingData.pageNumber = 0;
    	}
    
    	this._updatePage();
    } else if ( dataSet == this.getDataDataSet() ) {
        if( Fse.trace ) {
            Spry.Debug.trace( this.getDataURL() );
        }
    }
};

Fse.PageManager.prototype._buildSortParameters = function() {
    if( this._sortData.sortBy != undefined ) {
    	return "sortBy=" + this._sortData.sortBy + "&sortOrder=" + this._sortData.sortMode;
    } else {
        return "";
    }
};

Fse.PageManager.prototype._buildFilterParameters = function() {
    var filterParameters = "";
    var filterCount = 0;
    for( filterName in this._filters ) {
        if( filterCount > 0 ) {
            filterParameters = filterParameters + "&";
        }
        filterParameters = filterParameters + filterName + "=" + this._filters[filterName];
        filterCount++;
    }
    return filterParameters;
};

Fse.PageManager.prototype._getAdditionalParameters = function() {
    var sortParameters = this._buildSortParameters();
    var filterParameters = this._buildFilterParameters();
    
    var additionalParameters = sortParameters;
    if( filterParameters.length > 0 ) {
        if( additionalParameters.length > 0 ) {
            additionalParameters = additionalParameters + "&" + filterParameters;
        } else {
            additionalParameters = filterParameters;
        }
    }
    return additionalParameters;

};

Fse.PageManager.prototype._buildElementParameter = function() {
	var dataIDs = this._getDataIDs( this._pagingData.pageOffset, this._pagingData.pageStop );
	if( dataIDs.length > 0 ) {
	    var elementsParameter = "elements=" + dataIDs.toString();
    	return elementsParameter;
	} else {
	    return "";
	}
};

Fse.PageManager.prototype.getIndexURL = function() {
    var additionalParams = this._getAdditionalParameters();
    var indexURL;
    if( additionalParams.length > 0 ) {
    	indexURL = this._dataURL + "?indexOnly=true&" + additionalParams;
    } else {
        indexURL = this._dataURL + "?indexOnly=true";
    }
    return indexURL;
};

Fse.PageManager.prototype.getDataURL = function() {
    var parameters = this._buildElementParameter();
    var additionalParams = this._getAdditionalParameters();
    if( additionalParams.length > 0 ) {
        if( parameters.length > 0 ) {
            parameters = parameters + "&" + additionalParams;
        } else {
            parameters = additionalParams;
        }
    }
    if( parameters.length > 0 ) {
    	return this._dataURL + "?" + parameters;
    } else {
    	return this._dataURL;
    }
};

Fse.PageManager.prototype._updatePage = function() {
	if( this._pagingData.pageNumber > 0 ) {
		this._pagingData.pageOffset = ( this._pagingData.pageNumber - 1 ) * this._pagingData.pageSize;
		this._pagingData.pageStop = Math.min( this._pagingData.pageOffset + this._pagingData.pageSize, this._pagingData.rowCount );
	} else {
		this._pagingData.pageStop = -1;
		this._pagingData.pageOffset = -1;
	}

    this.getPagingDataSet().loadData();

	this._loadPage();
};


Fse.PageManager.prototype.previousPage = function() {
	if( this._pagingData.pageNumber > 1 ) {
		this._pagingData.pageNumber--;
		this._updatePage();
	}
};

Fse.PageManager.prototype.nextPage = function() {
	if( this._pagingData.pageNumber < this._pagingData.pageCount ) {
		this._pagingData.pageNumber++;
		this._updatePage();
	}
};

Fse.PageManager.prototype.firstPage = function() {
	this._pagingData.pageNumber = 1;
	this._updatePage();
};

Fse.PageManager.prototype.lastPage = function() {
	this._pagingData.pageNumber = this._pagingData.pageCount;
	this._updatePage();
};

Fse.PageManager.prototype._loadPage = function() {
    var dataDataSet = this.getDataDataSet();
    dataDataSet.setURL( this.getDataURL() );
	dataDataSet.loadData();
};

Fse.PageManager.prototype._getDataIDs = function( start, end ) {
    var indexes = [];
    var indexDataSet = this.getIndexDataSet();
    if( indexDataSet.getDataWasLoaded() ) {
        if( indexDataSet.getRowCount( true )) {
            var rows = indexDataSet.getData(true);
    		for( i=0, x = start; x < end; i++, x++ ) {
    		    indexes[i] = rows[x]["id"];
    		}
    	}
    }
	return indexes;
};

Fse.PageManager.prototype.sortBy = function( fieldName ) {
	if( this._sortData.sortBy == fieldName ) {
		if( this._sortData.sortMode  == "descending" ) {
			this._sortData.sortMode = "ascending";
		} else {
			this._sortData.sortMode = "descending";
		}
	} else {
		this._sortData.sortBy = fieldName;
	}
	
	this._loadIndex();
};

Fse.PageManager.prototype.resetFilters = function() {
    this._filters = {};    
};

Fse.PageManager.prototype.setFilter = function( filterName, filterValue ) {
    this._filters[filterName] = filterValue;    
};

Fse.PageManager.prototype.load = function() {
	this._pagingData.pageOffset = 0;
	this._pagingData.pageStop = this._pagingData.pageSize;
	this._pagingData.rowCount = 0;
	this._pagingData.pageNumber = 0;
    this._loadIndex();    
};

