//
//  cf_view.mm
//  MySQLWorkbench
//
//  Created by Alfredo Kojima on 21/Jan/09.
//  Copyright 2009 Sun Microsystems Inc. All rights reserved.
//

#import "MFView.h"
#import <mforms/mforms.h>


enum ViewFlags
{
  WidthFixedFlag = (1<<8),
  HeightFixedFlag = (1<<9),
  ViewFlagsMask = (WidthFixedFlag|HeightFixedFlag)
};

@class MFCheckBoxImpl;
@implementation NSView(MForms)


- (id)innerView
{
  return self;
}

- (void)setTag:(NSUInteger)tag
{
  NSAssert(0, @"setTag must be overriden");
}

- (void)setFixedFrameSize:(NSSize)size
{
  NSRect frame= [self frame];
  NSUInteger flags= [self tag] & ~ViewFlagsMask;
  
  if (size.width > 0)
  {
    frame.size.width= size.width;
    flags|= WidthFixedFlag;
  }
  if (size.height > 0)
  {
    frame.size.height= size.height;
    flags|= HeightFixedFlag;
  }
  
  [self setTag: flags];
  [self setFrame: frame];
}


- (BOOL)widthIsFixed
{
  return ([self tag] & WidthFixedFlag) != 0;
}


- (BOOL)heightIsFixed
{
  return ([self tag] & HeightFixedFlag) != 0;
}


- (NSSize)minimumSize
{
  return NSMakeSize(0, 0);
}


- (NSSize)preferredSize
{
  NSSize size= [self minimumSize];

  if ([self widthIsFixed])
    size.width= NSWidth([self frame]);
  if ([self heightIsFixed])
    size.height= NSHeight([self frame]);
  return size;
}


- (NSSize)preferredSizeForWidth:(float)width
{
  NSSize size= [self minimumSizeForWidth: [self widthIsFixed] ? NSWidth([self frame]) : width];
  
  if ([self heightIsFixed])
    size.height= NSHeight([self frame]);
  
  return size;  
}


- (NSSize)minimumSizeForWidth:(float)width
{
  return [self minimumSize];
}


- (void)subviewMinimumSizeChanged
{
  if ([[self window] respondsToSelector:@selector(subviewMinimumSizeChanged)])
  {
    // assume this is the toplevel view so just forward to the window
    [(id)[self window] subviewMinimumSizeChanged];
  }
  else
  {
    for (id subview in [self subviews])
      [subview resizeSubviewsWithOldSize: NSMakeSize(0, 0)];
  }
}

@end



static int view_get_x(::mforms::View *self)
{
  id view = self->get_data();
  if (view)
  {
    NSView* widget = view;
    return NSMinX([widget frame]);
  }
  return 0;
}

static int view_get_y(::mforms::View *self)
{
  id view = self->get_data();
  if (view)
  {
    NSView* widget = view;
    return NSMinY([widget frame]);
  }
  return 0;
}

static void view_set_size(::mforms::View *self, int w, int h)
{
  id view = self->get_data();
  if (view)
  {
    [view setFixedFrameSize: NSMakeSize(w,h)];
  }
}

static void view_set_position(::mforms::View *self, int x, int y)
{
  id view = self->get_data();
  if (view)
  {
    [view setFrameOrigin: NSMakePoint(x, y)];
  }
}

static void view_set_enabled(::mforms::View *self, bool flag)
{
  id view = self->get_data();
  if (view)
  {
    [view setEnabled:flag?YES:NO];
  }
}

static int view_get_width(::mforms::View *self)
{
  id view = self->get_data();
  if ( view )
  {
    return NSWidth([view frame]);
  }
  return 0;
}

static int view_get_height(::mforms::View *self)
{
  id view = self->get_data();
  if ( view )
  {
    return NSHeight([view frame]);
  }
  return 0;
}

static int view_get_preferred_width(::mforms::View *self)
{
  id view = self->get_data();
  if ( view )
  {
    return [view preferredSize].width;
  }
  return 0;
}

static int view_get_preferred_height(::mforms::View *self)
{
  id view = self->get_data();
  if ( view )
  {
    return [view preferredSize].height;
  }
  return 0;
}


static void view_show(::mforms::View *self, bool show)
{
  id view = self->get_data();
  
  if ( view && [view isHidden] != !show)
  {
    [view setHidden:!show];

    if ([view respondsToSelector: @selector(superview)])
      [[view superview] subviewMinimumSizeChanged];
  }
}

static bool view_is_shown(::mforms::View *self)
{
  id view = self->get_data();
  if (view)
    return ![view isHidden];
  return false;
}


static void view_set_tooltip(::mforms::View *self, const std::string &text)
{
  id view = self->get_data();
  if (view)
  {
    [view setToolTip: wrap_nsstring(text)];
  }
}


static void view_set_name(mforms::View *self, const std::string&)
{
}


static void view_relayout(mforms::View *self)
{
}

static void view_set_layout_dirty(mforms::View *self)
{
}

void cf_view_init()
{
  ::mforms::ControlFactory *f= ::mforms::ControlFactory::get_instance();
  
  f->_view_impl.get_width            = &view_get_width;
  f->_view_impl.get_height           = &view_get_height;
  f->_view_impl.get_preferred_width  = &view_get_preferred_width;
  f->_view_impl.get_preferred_height = &view_get_preferred_height;
  f->_view_impl.set_size             = &view_set_size;
  
  f->_view_impl.get_x                = &view_get_x;
  f->_view_impl.get_y                = &view_get_y;
  f->_view_impl.set_position         = &view_set_position;
  
  f->_view_impl.show                 = &view_show;
  f->_view_impl.is_shown             = &view_is_shown;
  
  f->_view_impl.set_enabled          = &view_set_enabled;
  f->_view_impl.set_name             = &view_set_name;
  
  f->_view_impl.set_tooltip          = &view_set_tooltip;
  f->_view_impl.relayout             = &view_relayout;
  f->_view_impl.set_layout_dirty     = &view_set_layout_dirty;
}
