//
//  WBModelDiagramPanel.mm
//  MySQLWorkbench
//
//  Created by Alfredo Kojima on 6/Oct/08.
//  Copyright 2008 Sun Microsystems Inc. All rights reserved.
//

#import "sigobjc++.h"
#include "wb_model_diagram_form.h"

#import "WBModelDiagramPanel.h"
#import "MCanvasScrollView.h"
#import "GRTIconCache.h"

#import "WBToolbarManager.h"
#import "WBMiniToolbar.h"


@implementation WBModelDiagramPanel

- (id)initWithId:(NSString*)oid
          formBE:(wb::ModelDiagramForm*)be
{
  self= [super init];
  if (self != nil)
  {
    _formBE= be;
    _formBE->set_frontend_data(self);

    [NSBundle loadNibNamed:@"WBModelDiagram" owner:self];
        
    _identifier= [oid retain];
    _viewer= [[[MCanvasViewer alloc] initWithFrame:NSMakeRect(0, 0, 300, 300)] autorelease];
        
    [_viewer setupQuartz];
    [_viewer setDelegate:self];
    [scrollView setContentCanvas:_viewer];

    [_viewer canvas]->set_user_data(self);
    
    [_viewer registerForDraggedTypes:[NSArray arrayWithObject:@"x-mysql-wb/db.DatabaseObject"]]; 
  }
  return self;
}


- (void)dealloc
{
  [_viewer setDelegate: nil];
  [super dealloc];
}


- (NSView*)topView
{
  return topView;
}


- (NSView*) toolsToolbar
{
  return toolbar;
}


- (id)optionsToolbar
{
  return optionsToolbar;
}


- (void)showOptionsToolbar:(BOOL)flag
{
  if ([optionsToolbar isHidden] != !flag)
  {
    [optionsToolbar setHidden: !flag];
    [optionsToolbar retain];
    [optionsToolbar removeFromSuperview];
    [topView addSubview: optionsToolbar];
    [optionsToolbar release];
/*  
    NSRect rect= [scrollView frame];
    if (flag)
      rect.size.height-= NSHeight([optionsToolbar frame]);
    else
      rect.size.height+= NSHeight([optionsToolbar frame]);
    [scrollView setFrame: rect];
*/
  }
}


- (void)setSidebar:(WBModelSidebarController*)sidebar
{
  mSidebar= sidebar;
}

- (WBModelSidebarController*)sidebar
{
  return mSidebar;
}


- (MCanvasViewer*)canvasViewer
{
  return _viewer;
}


- (mdc::CanvasView*)canvas
{
  return [_viewer canvas];
}


- (NSString*)identifier
{
  return _identifier;
}


- (NSString*)title
{
  return [NSString stringWithUTF8String:_formBE->get_title().c_str()];
}


- (void)searchString:(NSString*)text
{
  if (!_formBE->search_and_focus_object([text UTF8String]))
    NSBeep();
}


- (NSImage*)tabIcon
{
  return [NSImage imageNamed:@"workbench.physical.Diagram.16x16.png"];
}


static NSPoint loadCursorHotspot(const std::string &path)
{
  gsize size;
  guint8 *buffer;
  
  if (g_file_get_contents(path.c_str(), (gchar**)&buffer, &size, NULL))
  {
    if (buffer[0] != 0 || buffer[1] != 0 || buffer[2] != 2 || buffer[3] != 0)
    {
      g_free(buffer);
      return NSMakePoint(0.0, 0.0);
    }
    int xspot= buffer[6+4]|buffer[6+5]<<8;
    int yspot= buffer[6+6]|buffer[6+7]<<8;
    g_free(buffer);
    return NSMakePoint(xspot, yspot);
  } 
  return NSMakePoint(0.0, 0.0);
}


- (void)updateCursor
{
  std::string cursorName= _formBE->get_cursor();
  NSCursor *cursor= nil;
  
  if (!cursorName.empty())
  {
    NSImage *image= [[GRTIconCache sharedIconCache] imageForFileName:[NSString stringWithFormat:@"%s.cur", cursorName.c_str()]];
    
    NSString *path= [[NSBundle mainBundle] pathForResource:[NSString stringWithUTF8String:cursorName.c_str()]
                                                    ofType:@"cur" inDirectory:@""];
    
    if (path)
      cursor= [[NSCursor alloc] initWithImage:image hotSpot:loadCursorHotspot([path fileSystemRepresentation])];
  }
  [_viewer setCursor:cursor];
  [cursor release];
}


- (bec::UIForm*)formBE
{
  return _formBE;
}


- (BOOL)isClosed
{
  return _formBE->is_closed();
}


- (void)willClose
{
  _formBE->set_closed(true);
}

- (void)didOpen
{
  _formBE->set_closed(false);
}


- (void)canvasToolChanged:(mdc::CanvasView*)canvas
{
  BOOL flag;
  flag= [[WBToolbarManager defaultManager] refreshToolOptionsToolbar: optionsToolbar];
  [self showOptionsToolbar:flag];
  
  [self updateCursor];
}


- (BOOL)canvasMouseDown:(mdc::MouseButton)button
               location:(NSPoint)pos
                  state:(mdc::EventState)state
{
  _formBE->handle_mouse_button(button, true, pos.x, pos.y, state);  
  return YES;
}

- (BOOL)canvasMouseUp:(mdc::MouseButton)button
             location:(NSPoint)pos
                state:(mdc::EventState)state
{
  _formBE->handle_mouse_button(button, false, pos.x, pos.y, state);
  return YES;
}

- (BOOL)canvasMouseMoved:(NSPoint)pos
                   state:(mdc::EventState)state
{
  _formBE->handle_mouse_move(pos.x, pos.y, state);
  
  return YES;
}


- (BOOL)canvasKeyDown:(mdc::KeyInfo)key state:(mdc::EventState)state
{
  _formBE->handle_key(key, true, state);
  return YES;
}


- (BOOL)canvasKeyUp:(mdc::KeyInfo)key state:(mdc::EventState)state
{
  _formBE->handle_key(key, false, state);
  return YES;
}



// drag drop
- (NSDragOperation)canvasDraggingEntered:(id < NSDraggingInfo >)sender
{
  if ([[[sender draggingPasteboard] types] containsObject:@"x-mysql-wb/db.DatabaseObject"])
    return NSDragOperationGeneric;
  
  //return _formBE->accepts_drop(int x, int y, const std::string &type, const std::string &text);;
  return NSDragOperationNone;
}


- (BOOL)canvasPerformDragOperation:(id < NSDraggingInfo >)sender
{  
  NSPasteboard *pboard= [sender draggingPasteboard];
  NSString *data= [pboard stringForType:@"x-mysql-wb/db.DatabaseObject"];
  NSPoint pos= [_viewer convertPointFromBase:[sender draggingLocation]];

  return _formBE->perform_drop(pos.x, pos.y, "x-mysql-wb/db.DatabaseObject", [data UTF8String]);
}

//void handle_key(const mdc::KeyInfo &key, bool press, mdc::EventState state);

@end
