(function( $ ) {
	function odtListViewCreateRowHtml( data, row, r ){
		row.id = data.id + '_tr' + r;
		var tdClass = 'odtLvTd' + ( r % 2 );
		var html = '<tr id="' + row.id + '" class="odtLvTr' + ( r % 2 ) + '">';
		if( data.icons ){
			html = html + '<td class="' + tdClass + '">';
			html = html + '<img src="icons/' + row.icon + '_16.png" class="odtLvI">';
			html = html + '</td>'; 
		}
		for( var c = 0; c < row.cells.length; c++ ){
			var column = data.columns[c];
			var cell = row.cells[c];
			html = html + '<td align="' + column.alignment + '" valign="top" class="' + tdClass + '">';
			if( column.linkForm ){
				if( cell.link ){
					html = html + '<a href="' + column.linkForm + '?Id=' + cell.link + '" tabindex="-1">';
				}
			}
			if( cell.text.length < 1 ){
				html = html + '&nbsp;';
			} else {
				html = html + cell.text;
			} 
			if( column.linkForm ){
				if( cell.link ){
					html = html + '</a>';
				} 
			}		
			html = html + '</td>'; 
		}
		html = html + '</tr>';
		return html;
	}
	function odtListViewCreateTableHtml( data ){
		if( data.rows.length < 1 ){
			return "";
		}		
		var html = '<table id="' + data.id + 'table" class="odtLvTable" cellspacing="0" cellpadding="0">';
		html = html + '<colgroup>';
		if( data.icons ){
			html = html + '<col />'; 
		}
		for( var c = 0; c < data.columns.length; c++ ){
			var column = data.columns[c];
			html = html + '<col />'; 
		} 
		html = html + '</colgroup>';
		html = html + '<thead><tr>';
		if( data.icons ){
			html = html + '<th class="odtLvTh" />'; 
		}
		for( var c = 0; c < data.columns.length; c++ ){
			var column = data.columns[c];
			html = html + '<th align="' + column.alignment + '" valign="top" nowrap class="odtLvTh">' + column.caption + '</th>'; 
		} 
		html = html + '</tr></thead>';
		html = html + '<tbody>';
		for( var r = 0; r < data.rows.length; r++ ){
			var row = data.rows[r];
			html = html + odtListViewCreateRowHtml( data, row, r );
		} 
		html = html + '<tr id="' + data.id + 'Footer" class="odtLvTrF">';
		html = html + '<td class="odtLvTdF" colspan="';
		if( data.icons ){
			html = html + ( data.columns.length +1 );
		} else {
			html = html + data.columns.length;
		}
		html = html + '">';
		html = html + '<a href=\"Csv?ViewId=' + escape( document.forms[0].ViewId.value );
		html = html + '&ListView=' + data.id + '" tabindex="-1" title="Im Excel &ouml;ffnen"><img src="img/excel14.png"></a>';
		if( data.rows.length < data.rowCount ){
			html = html + '  <span id="' + data.id + 'Pager">' + data.rows.length + ' / ' + data.rowCount + '</span>';
		}
		if( data.detailForm ){
			html = html + ' <img id="' + data.id + 'showDetail" src="img/detail.png" title="&Ouml;ffnen (return)" width="13" height="12">';
		}
		if( data.editForm != null ){
			html = html + ' <img id="' + data.id + 'showEdit" src="img/edit.png" title="Bearbeiten (ctrl+e)" width="13" height="12">';
		}
		for( var c = 0; c < data.columns.length; c++ ){
			var column = data.columns[c];
			if( column.linkForm ){
				html = html + ' <img id="' + data.id + 'show' + c + '" src="icons/' + column.linkIcon + '_16.png" title="' + column.linkTitle;
				if( column.linkKey )
					html = html + ' (' + column.linkKey + ')';
				html = html + '" width="13" height="12">';
			}
		} 
		html = html + '</td>';
		html = html + '</tr>';
		html = html + '</tbody>';
		html = html + '</table>'; 
		return html;
	}
	function odtListViewLoadNextPage( data ){
		if( data.isLoading == true )
			return;
		data.isLoading = true;
		var pager = $( '#' + data.id + 'Pager' );
		pager.empty();
		pager.append( '<img src="img/indicator.gif">' );
		$.ajax({
			type: 'get',
			url: 'Ajaxer',
			data: 'ViewId=' + escape( document.forms[0].ViewId.value ) + '&CompId=' + data.id + '&GetNextPageFrom=' + data.rows.length,
			dataType: 'json',
			success: function( respdata ){ 
				pager.empty();
				if( respdata.OK == 'ok' ){
					var html = '';
					for( var r = 0; r < respdata.rows.length; r++ ){
						var row = respdata.rows[r];
						html = html + odtListViewCreateRowHtml( data, row, data.rows.length + r );
					} 
					$('#' + data.id + 'table > tbody > tr').eq( data.rows.length -1 ).after(html);
					for( var r = 0; r < respdata.rows.length; r++ ){
						var row = respdata.rows[r];
						data.rows.push( row );
					}	
		  		} else {
		    		alert('Fehler: unexpected result\n' + respdata );
		  		}
				pager.append( '' + data.rows.length + ' / ' + data.rowCount );
				data.isLoading = false;
			},
			error: function( respdata ){ 
				pager.empty();
		  		alert('Fehler:\n' + respdata.responseText );
				data.isLoading = false;
			}
		});
	}
	function odtListViewRefreshSelectedRow( data ){
		if( data.selectedRowIndex < 0 )
			data.selectedRowIndex = 0;
		if( data.rows.length <= data.selectedRowIndex )
			data.selectedRowIndex = data.rows.length -1;
		data.selectedRow = null;
		if( 0 <= data.selectedRowIndex && data.selectedRowIndex < data.rows.length )
			data.selectedRow = data.rows[ data.selectedRowIndex ];
		$('.odtLvTrSelected').removeClass( 'odtLvTrSelected' );
		if( data.selectedRow != null ){
    		$('#' + data.selectedRow.id ).addClass( 'odtLvTrSelected' );
    		odtEnsureVisible( $('#' + data.selectedRow.id ) );
		}
		if( data.rows.length < data.rowCount ){
			if( data.selectedRowIndex > data.rows.length - 10 ){
				odtListViewLoadNextPage( data );
			}
		} 
	}	
	function odtListViewOpenSelectedDetailForm( data ){
		if( data.selectedRow != null ){
			if( data.detailForm != null ){
				location.href = data.detailForm + '?Id=' + data.selectedRow.objectId;
			}
		}
	}
	function odtListViewOpenSelectedEditForm( data ){
		if( data.selectedRow != null ){
			if( data.editForm != null ){
				location.href = data.editForm + '?Id=' + data.selectedRow.objectId;
			}
		}
	}
	function odtListViewOnEnterKey( event ){
		var data = $(this).data( 'olv' );
		odtListViewOpenSelectedDetailForm( data );
		return false;
	}
	function odtListViewOnClickShowDetail( event ){
		odtListViewOpenSelectedDetailForm( event.data );
		return false;
	}
	function odtListViewOnClickShowEdit( event ){
		odtListViewOpenSelectedEditForm( event.data );
		return false;
	}
	function odtListViewOnEditKey( event ){
		var data = $(this).data( 'olv' );
		odtListViewOpenSelectedEditForm( data );
		return false;
	}
	function odtListViewSelectFirstRow( event ){
		var data = $(this).data( 'olv' );
		data.selectedRowIndex = 0;
		odtListViewRefreshSelectedRow( data );
		return false;
	}
	function odtListViewSelectLastRow( event ){
		var data = $(this).data( 'olv' );
		data.selectedRowIndex = data.rows.length -1;
		odtListViewRefreshSelectedRow( data );
		return false;
	}
	function odtListViewSelectNextRow( event ){
		var data = $(this).data( 'olv' );
		data.selectedRowIndex++;
		odtListViewRefreshSelectedRow( data );
		return false;
	}
	function odtListViewSelectPrevRow( event ){
		var data = $(this).data( 'olv' );
		data.selectedRowIndex--;
		odtListViewRefreshSelectedRow( data );
		return false;
	}
	function odtListViewPageDown( event ){
		var data = $(this).data( 'olv' );
		data.selectedRowIndex += 8;
		odtListViewRefreshSelectedRow( data );
		return false;
	}
	function odtListViewPageUp( event ){
		var data = $(this).data( 'olv' );
		data.selectedRowIndex -= 8;
		odtListViewRefreshSelectedRow( data );
		return false;
	}
	function odtListViewFocusOut(){
		// odtDebugLog( 'focusout' );
		var data = $(this).data( 'olv' );
		$('.odtLvTrSelected').removeClass( 'odtLvTrSelected' );
	}
	function odtListViewFocusIn(){
		// odtDebugLog( 'focus in' );
		var data = $(this).data( 'olv' );
		if( data.selectedRowIndex < 0 ){
			if( data.rows.length == 1 ){
				data.selectedRowIndex = 0;
				odtListViewRefreshSelectedRow( data );
			}
		}
		odtListViewRefreshSelectedRow( data );
	}
	function odtListViewMouseClick( event ){
		var data = $(this).data( 'olv' );
		// odtDebugLog( 'mouseclick' );
		if( event.target.nodeName == 'TD' ){
			var p = event.target.parentNode;
			if( p.nodeName == 'TR' ){
				if( p.id.substring( 0, data.id.length + 3 ) == data.id + '_tr' ){
					var index = parseInt( p.id.substring( data.id.length + 3 ) );
					if( data.selectedRowIndex != index ){
						data.selectedRowIndex = index;
						odtListViewRefreshSelectedRow( data );
					} else {
						odtListViewOpenSelectedDetailForm( data );
						return false;
					}
				}
			}
		}
		return true;
	}
	function odtListViewOnLinkKey( event ){
		var data = $(this).data( 'olv' );
		for( var c = 0; c < data.columns.length; c++ ){
			var column = data.columns[c];
			if( column.linkForm ){
				if( column.linkKey == event.data ){
					if( data.selectedRow != null ){
						if( data.selectedRow.cells[ c ].link ){
							location.href = column.linkForm + '?Id=' + data.selectedRow.cells[ c ].link;
						}
					}
					return false;
				}
			}
		}
		return true;
	}
	function odtListViewOnClickShowLink( event ){
		var showLinkData = event.data;
		if( showLinkData.column.linkForm ){
			if( showLinkData.data.selectedRow != null ){
				if( showLinkData.data.selectedRow.cells[ showLinkData.columnIndex ].link ){
					location.href = showLinkData.column.linkForm + '?Id=' + showLinkData.data.selectedRow.cells[ showLinkData.columnIndex ].link;
				}
			}
		}
	}
	var methods = {
		init : function( options ) {
			var data = $.extend( {
			  'location'         : 'top',
			  'background-color' : 'blue'
			}, options );
			return this.each(function(){
				var $this = $(this);
				if( $this.data( 'olv' ) ){
					$.error( 'odtListView.init reinit not allowed' );
				}
				$this.data( 'olv', data );
				data.id = $this.attr( 'id' );
				data.selectedRowIndex = -1;
				data.isLoading = false;
				$this.attr( 'tabindex', 0 );
				$this.bind( 'focusin', odtListViewFocusIn );
				$this.bind( 'focusout', odtListViewFocusOut );
				//$this.bind( 'blur', function(){ odtDebugLog( 'blur ' + data.selectedRowIndex ); } );
				$this.bind( 'mousedown', odtListViewMouseClick );
				//$this.bind( 'click', odtListViewMouseClick ); doesnt work in ie, focusout/in bevor
				$this.bind( 'keydown', 'down', odtListViewSelectNextRow );
				$this.bind( 'keydown', 'up', odtListViewSelectPrevRow );
				$this.bind( 'keydown', 'pagedown', odtListViewPageDown );
				$this.bind( 'keydown', 'pageup', odtListViewPageUp );
				$this.bind( 'keydown', 'home', odtListViewSelectFirstRow );
				$this.bind( 'keydown', 'end', odtListViewSelectLastRow );
				$this.bind( 'keydown', 'return', odtListViewOnEnterKey );
				$this.addClass( 'odtLv' );
				$this.append( odtListViewCreateTableHtml( data ) );
				$( '#' + data.id + 'showDetail' ).click( data, odtListViewOnClickShowDetail );
				if( data.editForm != null ){
					$this.bind( 'keydown', 'ctrl+e', odtListViewOnEditKey );
					$( '#' + data.id + 'showEdit' ).click( data, odtListViewOnClickShowEdit );
				}
				for( var c = 0; c < data.columns.length; c++ ){
					var column = data.columns[c];
					if( column.linkForm ){
						var showLinkData = {
							columnIndex: c,
							column: column,
							data: data
						};							
						if( column.linkKey )
							$this.bind( 'keydown', column.linkKey, odtListViewOnLinkKey );
						$( '#' + data.id + 'show' + c ).click( showLinkData, odtListViewOnClickShowLink );
					}
				} 
				
			});
		}
    };
    $.fn.odtListView = function( method ) {
    	if ( methods[method] ) {
      		return methods[ method ].apply( this, Array.prototype.slice.call( arguments, 1 ));
    	} else if ( typeof method === 'object' || ! method ) {
      		return methods.init.apply( this, arguments );
    	} else {
      		$.error( 'Method ' +  method + ' does not exist on jQuery.tooltip' );
      		return false;
    	}
    };
})( jQuery );
