#import "FiltersController.h"
#import "ExtendedTableColumn.h"
#import "SwitchTableView.h"

@implementation FiltersController

- (void) dealloc
{
	RELEASE(categories);
	[super dealloc];
}

- (id) init
{
	if( (self = [super init]) )
		{
			categories = [NSMutableArray new];
			return self;
		}
	return nil;
}

- (void) awakeFromNib
{
	[self _setupTable];
	
	[dateFromPopup removeAllItems];
	[dateToPopup removeAllItems];
	
	[[NSNotificationCenter defaultCenter] addObserver: self
	                                         selector: @selector(_updateDates:) 
	                                             name: @"Dates Changed"
	                                           object: nil];
	                                           
	[[NSNotificationCenter defaultCenter] addObserver: self
	                                         selector: @selector(_updateCategories:)
	                                             name: @"Categories Changed"
	                                           object: nil]; 

  [[NSNotificationCenter defaultCenter] addObserver: self
                                           selector: @selector(_updateSelections:)
                                               name: @"Selections Changed" 
                                             object: nil];
}


// Action methods
//******************


- (void) includeAll: (id) sender
{
	int i;
	
	for( i=0; i < [categories count]; i++ )
		{
			[[categories objectAtIndex: i] setObject: [NSNumber numberWithBool: YES] forKey: @"include"];
		}
	[categoryTable reloadData];
	[self _filtersChanged: self];
}

- (void) excludeAll: (id) sender
{
  int i;
  
  for( i=0; i < [categories count]; i++ )   
		{
			[[categories objectAtIndex: i] setObject: [NSNumber numberWithBool: NO] forKey: @"include"];
		}
	[categoryTable reloadData];
	[self _filtersChanged: self];
}


// NSTableViewDataSource protocol methods
//****************************************


- (int) numberOfRowsInTableView: (NSTableView *) view
{  
	return [categories count];
}

- (id)            tableView: (NSTableView *) view  
  objectValueForTableColumn: (NSTableColumn *) column
                        row: (int) row
{
	if( [[column identifier] isEqualToString: @"name"] )
		{  
			return [[categories objectAtIndex: row] objectForKey: @"name"];
		}
	return nil;
}


// SwitchTableViewDataSource protocol methods
//********************************************


- (int)    tableView: (NSTableView *)aTableView 
 stateForTableColumn: (NSTableColumn *)aTableColumn
                 row: (int)rowIndex
{
	if( [[aTableColumn identifier] isEqualToString: @"include"] )
		{
			return [[[categories objectAtIndex: rowIndex] objectForKey: @"include"] intValue];
		}
	return 0;
}
                 
- (void)   tableView: (NSTableView *)aTableView
            setState: (int) aState      
      forTableColumn: (NSTableColumn *)aTableColumn
                 row: (int)rowIndex
{
	if( [[aTableColumn identifier] isEqualToString: @"include"] )
		{
			[[categories objectAtIndex: rowIndex] setObject: [NSNumber numberWithInt: aState] forKey: @"include"];
			[self _filtersChanged: self];
		}
}


// Private methods and functions
//*******************************


- (void) _setupTable
{  
	ExtendedTableColumn *category, *include;  
	NSButtonCell *cell;  
	
	category = AUTORELEASE([[NSTableColumn alloc] initWithIdentifier: @"name"]);  
	[category setEditable: NO];  
	[category setResizable: NO];
	[category setWidth: 102]; 
	 
	include = AUTORELEASE([[ExtendedTableColumn alloc] initWithIdentifier: @"include"]);  
	[include setShouldUseAndSetState: YES];  
	[include setShouldUseMouse: YES];  
	[include setEditable: NO];
	[include setResizable: NO];  
	[include setWidth: 40];

	cell = AUTORELEASE([[NSButtonCell alloc] init]);  
	[cell setButtonType: NSSwitchButton];  
	[cell setImagePosition: NSImageOnly];  
	[include setDataCell: cell];  

	categoryTable = [[SwitchTableView alloc] init];  
	[categoryTable setDataSource: self];  
	[categoryTable setDelegate: self];  
	[categoryTable addTableColumn: category];  
	[categoryTable addTableColumn: include];
	[categoryTable setAllowsMultipleSelection: NO];  
	[categoryTable setAllowsColumnSelection: NO];  
	[categoryTable setDrawsGrid: NO];  
	[categoryTable setRowHeight: [[NSFont systemFontOfSize: [NSFont systemFontSize]] boundingRectForFont].size.height+5];  

	[categoryTableSV setDocumentView: categoryTable];  
	[categoryTableSV setHasHorizontalScroller: NO];  
	[categoryTableSV setHasVerticalScroller: YES];  
	[categoryTableSV setBorderType: NSBezelBorder];
}

- (void) _updateSelections: (NSNotification *) aNotification
{
	NSDictionary *filter = [NSDictionary dictionaryWithDictionary: [aNotification object]];
  NSString *category = [NSString string];
	int i, k;
	
	// should autoenabling take care of this?	

	if( [dateToPopup numberOfItems] > 0 )   
		{     
  		[dateToPopup setEnabled: YES];     
			[dateFromPopup setEnabled: YES];   
		}
	else   
		{		
			[dateToPopup setEnabled: NO];
			[dateFromPopup setEnabled: NO];
		}
		
	if( ![[filter objectForKey: @"item"] isEqualToString: @"NONE"] )
		[itemText setStringValue: [filter objectForKey: @"item"]];	
		
	if( ![[filter objectForKey: @"dateFrom"] isEqualToString: @"NONE"] )
		[dateFromPopup selectItemWithTitle: [filter objectForKey: @"dateFrom"]];		
	else
		[dateFromPopup selectItem: [dateFromPopup itemAtIndex: 0]];

	if( ![[filter objectForKey: @"dateTo"] isEqualToString: @"NONE"] )
		[dateToPopup selectItemWithTitle: [filter objectForKey: @"dateTo"]];
	else
		[dateToPopup selectItem: [dateToPopup lastItem]]; 
		 	
	// if the filter is NONE, then select every category

	if( [[filter objectForKey: @"categories"] isEqual: @"NONE"] )
		{
			for( i = 0; i < [categories count]; i++ )
				{
					[[categories objectAtIndex: i] setObject: [NSNumber numberWithBool: YES] forKey: @"include"];
				}
		}
		
	// else, exclude every category
	
	else
		{
			for( i = 0; i < [categories count]; i++ )
				{
					[[categories objectAtIndex: i] setObject: [NSNumber numberWithBool: NO] forKey: @"include"];
				}

			// then set only the the ones in the filter array to be marked as included
	
			for( i = 0; i < [[filter objectForKey: @"categories"] count]; i++ )
				{
					category = [NSString stringWithString: [[filter objectForKey: @"categories"] objectAtIndex: i]];
			
					for( k = 0; k < [categories count]; k++ )
						{
							if( [category isEqualToString:  [[categories objectAtIndex: k] objectForKey: @"name"]] )
								{
									[[categories objectAtIndex: k] setObject: [NSNumber numberWithBool: YES]  forKey: @"include"];
								}
						}			
				}
		}	

	[categoryTable reloadData];
}

- (void) _updateDates: (NSNotification *) aNotification
{
	int i;
	NSArray *arr = [NSArray arrayWithArray: [aNotification object]];

	[dateFromPopup removeAllItems];
	[dateToPopup removeAllItems];

	for( i = 0; i < [arr count]; i++ )
		{
			[dateFromPopup addItemWithTitle: [arr objectAtIndex: i]];
			[dateToPopup addItemWithTitle: [arr objectAtIndex: i]];
		}
}

- (void) _updateCategories: (NSNotification *) aNotification
{
	int i;
	NSArray *arr = [NSArray arrayWithArray: [aNotification object]];

	[categories removeAllObjects];
	
	for( i = 0; i < [arr count]; i++ )
		{
			[categories addObject: [NSMutableDictionary dictionaryWithObjectsAndKeys: 
				[arr objectAtIndex: i], @"name",
				[NSNumber numberWithBool: YES], @"include", nil]];
		}
	[categoryTable reloadData];	
}
                        
- (void) _filtersChanged: (id) sender
{
	NSString *dateFrom, *dateTo, *item;
	NSMutableArray *filteredCategories = [NSMutableArray new];
	NSDictionary *filter;
	int i;

	dateFrom = [NSString string];
	dateTo = [NSString string];
	item = [NSString string];
	
	if( [dateFromPopup selectedItem] != nil )
		dateFrom = [NSString stringWithString: [[dateFromPopup selectedItem] title]];
	else
		dateFrom = @"NONE";
		
	if( [dateToPopup selectedItem] != nil )
		dateTo = [NSString stringWithString: [[dateToPopup selectedItem] title]];
	else
		dateTo = @"NONE";
		
	if( [itemText stringValue] != nil )
		item = [NSString stringWithString: [itemText stringValue]];
	else
		item = @"NONE";
	
	for( i=0; i < [categories count]; i++ )
		{
			if( [[[categories objectAtIndex: i] objectForKey: @"include"] boolValue ] )
				{
					[filteredCategories addObject: [[categories objectAtIndex: i] objectForKey: @"name"]];
				}
		}
	
	NSLog(@"filteredCategories - %@", [filteredCategories description]);

	filter = [NSDictionary dictionaryWithObjectsAndKeys:
		dateFrom, @"dateFrom",
		dateTo, @"dateTo",
		item, @"item",
		filteredCategories, @"categories", nil];
			
	[[NSNotificationCenter defaultCenter] postNotificationName: @"Filters Changed" object: filter];
}            


@end
