//
//  CRSciWindow.mm
//  sci4osx_test
//
//  Created by serg on 7/21/08.
//  Copyright 2008 __MyCompanyName__. All rights reserved.
//


#import "CRSciView.h"
#import <Cocoa/Cocoa.h>
#import "CRSciWindow.h"


static OSStatus ApplicationEventHandler (EventHandlerCallRef nextHandlerRef, EventRef event, void *userData)
{
  UInt32 eventKind = GetEventKind(event);
  
  CRSciWindow* sciWindow = reinterpret_cast<CRSciWindow*>( userData );
  WindowRef window = *sciWindow;
  
  switch (eventKind) {
    case kEventAppActivated:
      ActivateWindow(window, TRUE);
      return noErr;
    case kEventAppDeactivated:
      ActivateWindow(window, FALSE);
      return noErr;
      
    default:
      // pass-thru all kEventClassApplication events we're not interested in.
      break;
  }
  return eventNotHandledErr;
}

static OSStatus WindowEventHandler( EventHandlerCallRef inCallRef, EventRef inEvent, void* userData)
{
  CRSciView* sciView = reinterpret_cast<CRSciView*>( userData );
  return sciView->handleWindowEvent(inCallRef, inEvent, userData);
}

CRSciWindow::CRSciWindow()
:
_crWindow(NULL)
{
}

WindowRef CRSciWindow::init()
{
  OSStatus		err;
  WindowAttributes attributes= kWindowLiveResizeAttribute|kWindowCompositingAttribute
  |kWindowNoShadowAttribute|kWindowDoesNotCycleAttribute
  |kWindowStandardHandlerAttribute|kWindowLiveResizeAttribute;
  
  Rect bounds;
  
  bounds.top= 0;
  bounds.left= 0;
  bounds.right= 100;
  bounds.bottom= 100;
  
  err= CreateNewWindow(kPlainWindowClass, attributes, &bounds, &_crWindow);
  require_noerr( err, CantCreateWindow );
  
CantCreateWindow:
  return _crWindow;
}

void CRSciWindow::createEditor(NSWindow* window)
{
  HIRect boundsRect;
  // GOOD and BAD methods off embedding into a window.  This is used
  // to test Window::SetPositionRelative under different situations.
#define GOOD
#ifdef GOOD
#ifdef USE_CONTROL
  ControlRef root;
  GetRootControl(_crWindow, &root);
#else
  HIViewRef root;
  HIViewFindByID(HIViewGetRoot(_crWindow),
                 kHIViewWindowContentID,
                 &root);
#endif
  HIViewGetBounds(root, &boundsRect);
  
#else // BAD like mozilla
  HIViewRef root;
  root = HIViewGetRoot(_crWindow);
  
  Rect cBounds, sBounds;
  GetWindowBounds(window, kWindowContentRgn, &cBounds);
  GetWindowBounds(window, kWindowStructureRgn, &sBounds);
  boundsRect.origin.x = cBounds.left - sBounds.left;
  boundsRect.origin.y = cBounds.top - sBounds.top;
  boundsRect.size.width = cBounds.right - cBounds.left;
  boundsRect.size.height = cBounds.bottom - cBounds.top;
#endif
  
  // get a scintilla control, and add it to it's parent container
  _sciView.create();
  HIViewAddSubview( root, _sciView );
  
  // set the size of scintilla to the size of the container
  HIViewSetFrame( _sciView, &boundsRect );
  
  _sciView.init();
  
  // bind the size of scintilla to the size of it's container window
  const HILayoutInfo kBindToParentLayout = {
    kHILayoutInfoVersionZero,
    { { NULL, kHILayoutBindTop }, { NULL, kHILayoutBindLeft }, { NULL, kHILayoutBindBottom }, { NULL, kHILayoutBindRight } },
    { { NULL, kHILayoutScaleAbsolute, 0 }, { NULL, kHILayoutScaleAbsolute, 0 } },
    { { NULL, kHILayoutPositionTop, 0 }, { NULL, kHILayoutPositionLeft, 0 } }
  };
  HIViewSetLayoutInfo(_sciView, &kBindToParentLayout);
  
  HIViewRender(_sciView);
  
  // setup some event handling
  if (0) {
    static const EventTypeSpec applicationEventTypes[] = {
      { kEventClassApplication, kEventAppActivated },
      { kEventClassApplication, kEventAppDeactivated }
    };		
    EventHandlerUPP ehUPP = NewEventHandlerUPP(ApplicationEventHandler);
    InstallApplicationEventHandler( ehUPP,
                                   sizeof(applicationEventTypes) / sizeof(EventTypeSpec),
                                   applicationEventTypes, this, &_applicationEventHandlerRef );
  }
  
  {
    static const EventTypeSpec windowMouseEvents[] =
    {
      { kEventClassMouse, kEventMouseDown },
    };
    InstallEventHandler (GetWindowEventTarget( _crWindow ), WindowEventHandler,
                         GetEventTypeCount( windowMouseEvents ), windowMouseEvents, &_sciView, &_windowEventHandlerRef );
  }
  
  // show scintilla
  ShowControl( _sciView );
  
  //1SetAutomaticControlDragTrackingEnabledForWindow(_crWindow, true);
  
  //SetWindowActivationScope( _crWindow, kWindowActivationScopeNone);
  
  _ccWindow = window;
  
CantCreateWindow:
CantSetMenuBar:
CantGetNibRef:
  ;//!return err;
}

void CRSciWindow::dispose()
{
  RemoveEventHandler(_windowEventHandlerRef);
  RemoveEventHandler(_applicationEventHandlerRef);
  
  _crWindow = NULL;
  _ccWindow = NULL;
}
