//
//  MFGRTTreeView.mm
//  MySQLWorkbench
//
//  Created by Alfredo Kojima on 11/Feb/09.
//  Copyright 2009 Sun Microsystems Inc. All rights reserved.
//

#import "MFGRTTreeView.h"

#import "MFView.h"
#include "mforms/mforms.h"

#import "NSString_extras.h"
#import "GRTTreeDataSource.h"
#import "MTextImageCell.h"

@implementation MFGRTTreeViewImpl


- (id)initWithObject:(mforms::GRTTreeView*)object
{
  self= [super initWithFrame:NSMakeRect(0, 0, 50, 50)];
  if (self)
  {
    NSRect rect;
    mOwner= object;
    mOwner->set_data(self);
    mOutline= [[[NSOutlineView alloc] initWithFrame:rect] autorelease];
    [mOutline setDoubleAction: @selector(rowDoubleClicked:)];
    [mOutline setTarget: self];
    [mOutline setIndentationPerLevel: 16.0];
    [mOutline setIndentationMarkerFollowsCell:NO];
    
    rect.origin= NSMakePoint(0, 0);
    rect.size= [NSScrollView contentSizeForFrameSize:[self frame].size
                          hasHorizontalScroller:NO
                            hasVerticalScroller:YES
                                     borderType:NSBezelBorder];
    [self setDocumentView: mOutline];
    [self setHasVerticalScroller: YES];    
  }
  return self;
}


- (void)rowDoubleClicked:(id)sender
{
  bec::NodeId node= [mDataSource nodeIdForItem:[mOutline itemAtRow: [mOutline clickedRow]]];
  
  NSTableColumn *column= [[mOutline tableColumns] objectAtIndex: [mOutline clickedColumn]];

  mOwner->row_activate_callback(node, [[column identifier] integerValue]);
}


- (void)setTreeModel:(bec::TreeModel*)model
{
  [mDataSource autorelease];
  mDataSource= [[GRTTreeDataSource alloc] initWithTreeModel:model];
  [mOutline setDataSource: mDataSource];
  [mOutline setDelegate: mDataSource];

  [mOutline reloadData];
}


- (void)setWidth:(float)width ofColumn:(int)modelColumn
{
  [[mOutline tableColumnWithIdentifier: [NSString stringWithFormat:@"%i", modelColumn]] setWidth: width];
}


- (int)addColumnWithType:(mforms::GRTTreeColumnType)type modelIndex:(int)modelColumn name:(NSString*)name editable:(BOOL)editable
{
  NSTableColumn *column= nil;
  switch (type)
  {
    case mforms::StringGRTColumnType:
      column= [[[NSTableColumn alloc] initWithIdentifier:[NSString stringWithFormat:@"%i", modelColumn]] autorelease];
      [column setDataCell: [[[NSTextFieldCell alloc] initTextCell:@""] autorelease]];
      break;
    case mforms::IconGRTColumnType:
      
    case mforms::IconStringGRTColumnType:
      column= [[[NSTableColumn alloc] initWithIdentifier:[NSString stringWithFormat:@"%i", modelColumn]] autorelease];
      [column setDataCell: [[[MTextImageCell alloc] initTextCell:@""] autorelease]];
      break;
    case mforms::IntegerGRTColumnType:
      column= [[[NSTableColumn alloc] initWithIdentifier:[NSString stringWithFormat:@"%i", modelColumn]] autorelease];
      [column setDataCell: [[[NSTextFieldCell alloc] initTextCell:@""] autorelease]];
      break;
    case mforms::CheckGRTColumnType:
    {
      NSButtonCell *cell;
      column= [[[NSTableColumn alloc] initWithIdentifier:[NSString stringWithFormat:@"%i", modelColumn]] autorelease];
      [column setDataCell: cell= [[[NSButtonCell alloc] initTextCell:@""] autorelease]];
      [cell setButtonType: NSSwitchButton];
      break;
    }/*
    case mforms::IconGRTColumnType:
      column= [[[NSTableColumn alloc] initWithIdentifier:[NSString stringWithFormat:@"%i", modelColumn]] autorelease];
      [column setDataCell: [[[NSImageCell alloc] initImageCell:nil] autorelease]];
      break;*/
  }
  if (column)
  {
    [[column dataCell] setEditable:editable];
    [[column headerCell] setTitle: name];
    [mOutline addTableColumn: column];
    if ([[mOutline tableColumns] count] == 1)
      [mOutline setOutlineTableColumn: column];
    [column setResizingMask: NSTableColumnAutoresizingMask|NSTableColumnUserResizingMask];

    return [[mOutline tableColumns] count] - 1;
  }
  return -1;
}


- (void)refreshNode:(const bec::NodeId&)node
{
  if (node.is_valid())
  {
    [mOutline reloadItem: [mDataSource itemForNodeId:node]];
    [mOutline setNeedsDisplay: YES];
  }
  else
    [mOutline reloadData];
  
  for (int i= 0; i < [mOutline numberOfRows]; i++)
  {
    if ([mOutline isExpandable:[mOutline itemAtRow:i]])
      NSLog(@"item %i is expandable", i);
    else
      NSLog(@"item %i is NOT expandable", i);
  }
}


- (void)setTag:(NSInteger)tag
{
  [mOutline setTag: tag];
}


- (NSInteger)tag
{
  return [mOutline tag];
}



static bool grttreeview_create(mforms::GRTTreeView *self, bool border)
{
  [[[[MFGRTTreeViewImpl alloc] initWithObject: self] autorelease] setBorderType: border ? NSBezelBorder : NSNoBorder];
  return true;
}

static void grttreeview_set_model(mforms::GRTTreeView *self, bec::TreeModel *model)
{
  MFGRTTreeViewImpl* tree = self->get_data();
  
  [tree setTreeModel: model];
}

static void grttreeview_set_allow_multi_select(mforms::GRTTreeView *self, bool flag)
{
  MFGRTTreeViewImpl* tree = self->get_data();
  
  [tree->mOutline setAllowsMultipleSelection: flag];
}

static int grttreeview_add_column(mforms::GRTTreeView *self, mforms::GRTTreeColumnType type, int model_column, const std::string &name)
{
  MFGRTTreeViewImpl* tree = self->get_data();
  
  return [tree addColumnWithType:type modelIndex:model_column name:[NSString stringWithCPPString:name] editable:NO];
}

static int grttreeview_add_column_editable(mforms::GRTTreeView *self, mforms::GRTTreeColumnType type, int model_column, const std::string &name)
{
  MFGRTTreeViewImpl* tree = self->get_data();
  
  return [tree addColumnWithType:type modelIndex:model_column name:[NSString stringWithCPPString:name] editable:YES];
}


static void grttreeview_refresh(mforms::GRTTreeView *self, const bec::NodeId &node)
{
  MFGRTTreeViewImpl* tree = self->get_data();
  
  [tree refreshNode: node];
}

static void grttreeview_set_column_width(mforms::GRTTreeView *self, int model_column, int width)
{
  MFGRTTreeViewImpl* tree = self->get_data();
  
  [tree setWidth: width ofColumn:model_column];
}

static bool grttreeview_get_selected_node(mforms::GRTTreeView *self, bec::NodeId &node)
{
  MFGRTTreeViewImpl* tree = self->get_data();
  NSInteger i= [tree->mOutline selectedRow];

  if (i < 0)
    return false;
  
  node= [tree->mDataSource nodeIdForItem:[tree->mOutline itemAtRow:i]];
  return true;
}

static int grttreeview_get_selection(mforms::GRTTreeView *self, std::vector<bec::NodeId> &nodes)
{
  MFGRTTreeViewImpl* tree = self->get_data();
  NSIndexSet *selection= [tree->mOutline selectedRowIndexes];
  
  for (NSUInteger i= [selection firstIndex]; i != NSNotFound; i= [selection indexGreaterThanIndex:i])
    nodes.push_back([tree->mDataSource nodeIdForItem:[tree->mOutline itemAtRow: i]]);
  
  return nodes.size();
}



void cf_grttreeview_init()
{
  ::mforms::ControlFactory *f = ::mforms::ControlFactory::get_instance();
  
  f->_grttreeview_impl.create= &grttreeview_create;
  f->_grttreeview_impl.set_model= &grttreeview_set_model;
  f->_grttreeview_impl.add_column= &grttreeview_add_column;
  f->_grttreeview_impl.add_column_editable= &grttreeview_add_column_editable;
  f->_grttreeview_impl.refresh= &grttreeview_refresh;
  f->_grttreeview_impl.set_column_width= &grttreeview_set_column_width;
  f->_grttreeview_impl.set_allow_multi_selection= &grttreeview_set_allow_multi_select;
  f->_grttreeview_impl.get_selected_node= &grttreeview_get_selected_node;
  f->_grttreeview_impl.get_selection= &grttreeview_get_selection;
}

@end
