// SimpleTableEdit2, fourth table demo
// Like SimpleTableEdit but now editable through its own interface.

{$mode objfpc}
{$modeswitch objectivec1}

program SimpleTableEdit2;
uses
	ctypes, MacOSAll, CocoaAll, TransSkel5, SkelViewUnit;
var
	table: NSTableView;
	tableData: array of AnsiString;
	tableScores: array of Longint;
	
type
  DataSource = objcclass(NSObject)
//    ABtn : NSButton;
  public
// Data source methods
    function numberOfRowsInTableView(tableView: NSTableView): Longint; message 'numberOfRowsInTableView:';
    function tableView_objectValueForTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: Longint): id; message 'tableView:objectValueForTableColumn:row:';
// Table view delegate methods
    procedure tableViewSelectionDidChange(notification: NSNotification); message 'tableViewSelectionDidChange:';
    procedure tableView_setObjectValue_forTableColumn_row(aTableView: NSTableView;
	  anObject: id; aTableColumn: NSTableColumn; rowIndex: Longint);
	   message 'tableView:setObjectValue:forTableColumn:row:';
  end;

function DataSource.numberOfRowsInTableView(tableView: NSTableView): Longint;
begin
	WriteLn('numberOfRowsInTableView');
	result := Length(tableData);
end;

function DataSource.tableView_objectValueForTableColumn_row(tableView: NSTableView; tableColumn: NSTableColumn; row: Longint): id;
var
	ident, s: String;
begin
	result := nil;
	if tableColumn.identifier = nil then
		Exit(tableView_objectValueForTableColumn_row);
	ident := NSStringToString(tableColumn.identifier);
	if row <= High(tableData) then
	if row >= Low(tableData) then
	begin
		if ident = '#' then // Row number
		begin
			Str(row+1, s);
			result := StringToNSString(s);
		end;
		if ident = 'N' then // Name
			result := StringToNSString(tableData[row]);
		if ident = '1' then // Score
		begin
			Str(tableScores[row], s);
			result := StringToNSString(s);
		end;
	end;
end;

// Selection changed.
// All we do about it here is to write a message to the console.
procedure DataSource.tableViewSelectionDidChange(notification: NSNotification);
begin
	WriteLn('Selected row = ', table.selectedRow);
	if table.selectedRow >= 0 then
	begin
		WriteLn('Selected row string = ', tableData[table.selectedRow]);
		WriteLn('Selected row score = ', tableScores[table.selectedRow]);
	end;
end;

// Editing message
procedure DataSource.tableView_setObjectValue_forTableColumn_row(aTableView: NSTableView;
	anObject: id; aTableColumn: NSTableColumn; rowIndex: Longint);
var
	ident, s: String;
	ii: Longint;
begin
//	WriteLn('EDIT at row ', rowIndex);
//	WriteLn('col ', NSStringToString(aTableColumn.identifier));
//	WriteLn(NSStringToString(NSString(anObject)));
	ident := NSStringToString(aTableColumn.identifier);
	if ident = 'N' then
	begin
		tableData[rowIndex] := NSStringToString(NSString(anObject));
	end;
	if ident = '1' then
	begin
		s := NSStringToString(NSString(anObject));
		Val(s, ii);
		tableScores[rowIndex] := ii;
	end;
end;

var
	ds: DataSource;

// Add a row
procedure Plus(s: PChar);
var
	i, ii: Longint;
begin
// Add a row before table.selectedRow, or at the end

// 1. Modify our own data arrays
	if table.selectedRow >= 0 then
	begin
		WriteLn('Add after ', table.selectedRow);
		ii := table.selectedRow;
	end
	else
	begin
		WriteLn('Add after end');
		ii := High(tableData)+1;
	end;

	SetLength(tableData, Length(tableData)+1);
	SetLength(tableScores, Length(tableScores)+1);
	
	for i := High(tableData)-1 downto ii do
	begin
		tableData[i+1] := tableData[i];
		tableScores[i+1] := tableScores[i];
	end;
	tableData[ii] := 'NEW';
	tableScores[ii] := 0;

// 2. Tell the table that things changed
	table.noteNumberOfRowsChanged;
	table.setNeedsDisplay_(true);
end;

// Remove a row
procedure Minus(s: PChar);
var
	i: Longint;
begin
// Delete table.selectedRow

	if table.selectedRow >= 0 then
	begin
// 1. Modify our own data arrays
		WriteLn('Delete ', table.selectedRow);
		
		for i := table.selectedRow to High(tableData)-1 do
		begin
			tableData[i] := tableData[i+1];
			tableScores[i] := tableScores[i+1];
		end;
		SetLength(tableData, Length(tableData)-1);
		SetLength(tableScores, Length(tableScores)-1);
		
// 2. Tell the table that things changed
		table.noteNumberOfRowsChanged;
		table.setNeedsDisplay_(true);
	end
	else
	begin
		SysBeep(1);
		WriteLn('Nothing to delete');
	end;
end;


// Creation! Get window, get items, install handlers
procedure MakeWindow;
var
	w: NSWindow;
	plusButton: NSButton;
	minusButton: NSButton;
begin
	w := SkelGetNewWindow('TableWindow');
	table := NSTableView(SkelGetIndView(w, 'NSTableView', 1));
	
	SetLength(tableData, 2);
	tableData[0] := 'One item';
	tableData[1] := 'Another item';
	SetLength(tableScores, 2);
	tableScores[0] := 100;
	tableScores[1] := 200;
	
	// Create DataSource (which is also delegate object)
	ds := DataSource.alloc;
	// Connect DataSource to table
	table.setDataSource(ds);
	table.setDelegate(ds);
	
	// Get buttons, install action
	plusButton := NSButton(SkelGetViewFromTag(w, 1));
	SkelSetButtonAction(plusButton, @Plus);
	minusButton := NSButton(SkelGetViewFromTag(w, 2));
	SkelSetButtonAction(minusButton, @Minus);
end;

begin
	SkelInit;					{ initialize }
	SkelApple('About SimpleTableEdit', nil); // App menu the easy way
	
	MakeWindow;
	
	SkelMain;					{ loop 'til Quit selected }
	SkelClobber;					{ clean up }
end.
