(function($) {

    $.fn.jsonGrid = function(settings) {
	//
	//init code
	jQuery.fn.dataTableExt.oSort['uk_date-asc']  = function(a,b) {
	    var ukDatea = a.split('/');
	    var ukDateb = b.split('/');

	    var x = (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1;
	    var y = (ukDateb[2] + ukDateb[1] + ukDateb[0]) * 1;

	    return ((x < y) ? -1 : ((x > y) ?  1 : 0));
	};

	jQuery.fn.dataTableExt.oSort['uk_date-desc'] = function(a,b) {
	    var ukDatea = a.split('/');
	    var ukDateb = b.split('/');

	    var x = (ukDatea[2] + ukDatea[1] + ukDatea[0]) * 1;
	    var y = (ukDateb[2] + ukDateb[1] + ukDateb[0]) * 1;

	    return ((x < y) ? 1 : ((x > y) ?  -1 : 0));
	};

	$.fn.dataTableExt.oApi.fnGetAllNodes = function ( oSettings )
	{
	    /* Note the use of a DataTables 'private' function thought the 'oApi' object */
	    var anNodes = this.oApi._fnGetTrNodes( oSettings );

	    /* Fire back the array to the caller */
	    return anNodes;
	}

	var that = this;

	//
	//Private vars
	var config = {
	    'data': {}
	};
	var oData = {};

	var publicMethods = {};

	//
	//private functions
	var genId = function(){
	    return "gen_" + Math.floor(Math.random() * 100000000);
	}
	var formatData = function(data){
	    var items = [];
	    var cols = [];


	    //
	    //get cols
	    var rowInx = 0;
	    var itemInx = 0;

	    if(config.cols){
		rowInx = 0;
		for(var rkey in data){

		    itemInx = 0;
		    var row = data[rkey];
		    oData[rowInx] = row;

		    //
		    //get key from defined cols
		    for(var ckey in config.cols){
			if(!items[rowInx]){
			    items[rowInx] = [];
			}

			//
			//get row data
			items[rowInx][itemInx] = row[ckey];

			//
			//get cols
			if(rowInx == 0){

			    if(config.cols[ckey]["sClass"]){
				config.cols[ckey]["sClass"] += " " + ckey;
			    }else{
				config.cols[ckey]["sClass"] = ckey;
			    }

			    cols[itemInx] = config.cols[ckey];
			}

			itemInx++;
		    }

		    rowInx++;
		}

	    }else{
		rowInx = 0;
		for(var rkey in data){

		    itemInx = 0;
		    var row = data[rkey];
		    oData[rowInx] = row;

		    for(var ikey in row){

			if(!items[rowInx]){
			    items[rowInx] = [];
			}

			//
			//get row data
			items[rowInx][itemInx] = row[ikey];

			//
			//get cols
			if(rowInx == 0){
			    cols[itemInx] = {
				"sTitle": ikey,
				"sClass": ikey
			    }
			}

			itemInx++;
		    }

		    rowInx++;
		}
	    }

	    return {
		"items"	: items,
		"cols"	: cols
	    }
	}


	//
	//Public methods
	publicMethods.headerText = function(cid, txt){

	}

	//
	//run widget
	if (settings) {
	    $.extend(config, settings)
	}

	this.each(function() {

	    var widget = $(this);

	    var tableId = "datatable";
	    if(config.id){
		tableId = config.id;
	    }else{
		tableId = genId();
	    }



	    //
	    //wrap widget
	    widget.wrap('<div class="jsonGrid_wrapper"></div>');
	    widget.html( '<table cellpadding="0" cellspacing="0" border="0" class="display" id="' +tableId+ '"></table>' );
			
	    if(config.data){
		var widgetTable = widget.find("#" + tableId);

		//
		//formatData
		var data = formatData(config.data);

		//
		//base options and overides
		var baseOpts = {
		    "aoColumns": data.cols,
		    "aaData": data.items,
		    "fnHeaderCallback": function( nHead, aasData, iStart, iEnd, aiDisplay ) {
			if(resizeCols && $.isFunction(resizeCols)){
			    resizeCols();
			}
		    }
		};
		if(config.opts){
		    $.extend(baseOpts, config.opts);
		}

		//
		//process table
		widgetTable.dataTable(baseOpts);


		//
		//remove autowidths
		var resizeCols  = function(){
		    widget.find(".dataTables_scrollHead").removeAttr("style").find("*").removeAttr("style");
		    widget.find(".dataTables_scrollHead table").width(widget.find(".dataTables_scrollBody table").width()+2);

		    var wTot = 0;
		    var nCols = widget.find(".dataTables_scrollHead tr:first-child th").length;

		    for(var inx=0; inx < nCols; inx++){
			var w = widget.find(".dataTables_scrollBody tr:first-child td").eq(inx).width();

			widget.find(".dataTables_scrollHead th").eq(inx).width(w);

			wTot += w;
		    }

		}
		resizeCols();

		//
		//bind events
		var parentWin = widget.parents(".window");
		if(parentWin){
		    parentWin.bind('winResize', function() {
			resizeCols();
		    });
		}

		//
		//row click event
		var trNodes = widgetTable.fnGetAllNodes();
		for(var trk in trNodes){
		    var tro = $(trNodes[trk]);

		    tro.click(function(e){
			//
			//remove all selected
			for(var trk in trNodes){
			    var tro = $(trNodes[trk]);
			    tro.removeClass("selected");
			}

			//
			//add selected class to this specific tr
			$(this).addClass("selected");

			//
			//if has a callback send it
			if(config.rowClick){
			    var aPos = widgetTable.fnGetPosition(this);
			    var aData = oData[aPos];

			    config.rowClick($(this), aData);
			}
		    });
		}


		widgetTable.find(".dataTables_scrollBody tbody").click(function(e){

		    var ot = $(e.originalTarget);

		    //
		    //remove all selected
		    widget.find("tbody tr").removeClass("selected");
		    //
		    //add selected class to this specific tr
		    $(this).addClass("selected");
		    //
		    //if has a callback send it
		    if(config.rowClick){
			var aPos = widgetTable.fnGetPosition(this);
			var aData = oData[aPos];

			con(aData);

			config.rowClick($(this), aData);
		    }
		});
	    }
	});

	var returnAugmentedSelf = $.extend(this, publicMethods);
	return returnAugmentedSelf;
    };

})(jQuery);
