/*
 * Copyright 2009, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *     * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *     * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */


#include "plugin/mac/graphics_utils_mac.h"

namespace o3d {

// Slide a window to a different rect, asynchronously, over a period of time.
void SlideWindowToRect(WindowRef the_window,
                       CGRect destination_rect,
                       double transition_duration_seconds) {
  TransitionWindowOptions options = {0, transition_duration_seconds,
                                     NULL, NULL};
  TransitionWindowWithOptions(the_window,
                              kWindowSlideTransitionEffect,
                              kWindowMoveTransitionAction,
                              &destination_rect, true, &options);
}

// Sets a Carbon window to a custom window level, by creating a new window
// group at that level and adding the window to the group.
void SetWindowLevel(WindowRef window, int level) {
  WindowGroupRef wGroup = NULL;
  WindowGroupAttributes attrs = 0;
  CreateWindowGroup(attrs, &wGroup);
  SetWindowGroupLevel(wGroup, level);
  SetWindowGroup(window, wGroup);
}


// Given a WindowRef and an AGLContext, make the context draw in that window.
// Return Value: true if the window is successfully set, false otherwise.
bool SetWindowForAGLContext(AGLContext context, WindowRef window) {
  return (IsMacOSTenFiveOrHigher()) ?
      aglSetWindowRef(context, window) :
      aglSetDrawable(context, GetWindowPort(window));
}


// Returns whether OS is 10.5 (Leopard) or higher.
bool IsMacOSTenFiveOrHigher() {
  static bool isCached = false, result = false;

  if (!isCached) {
    SInt32 major = 0;
    SInt32 minor = 0;
    // These selectors don't exist pre 10.4 but as we check the error
    // the function will correctly return NO which is the right answer.
    result = ((::Gestalt(gestaltSystemVersionMajor,  &major) == noErr) &&
              (::Gestalt(gestaltSystemVersionMinor,  &minor) == noErr) &&
              ((major > 10) || (major == 10 && minor >= 5)));
    isCached = true;
  }
  return result;
}

// Returns whether OS is 10.6 (Snow Leopard) or higher.
bool IsMacOSTenSixOrHigher() {
  static bool isCached = false, result = false;

  if (!isCached) {
    SInt32 major = 0;
    SInt32 minor = 0;
    // These selectors don't exist pre 10.4 but as we check the error
    // the function will correctly return NO which is the right answer.
    result = ((::Gestalt(gestaltSystemVersionMajor,  &major) == noErr) &&
              (::Gestalt(gestaltSystemVersionMinor,  &minor) == noErr) &&
              ((major > 10) || (major == 10 && minor >= 6)));
    isCached = true;
  }
  return result;
}

Rect CGRect2Rect(const CGRect &inRect) {
  Rect outRect;
  outRect.left = inRect.origin.x;
  outRect.top = inRect.origin.y;
  outRect.right = inRect.origin.x + inRect.size.width;
  outRect.bottom = inRect.origin.y + inRect.size.height;
  return outRect;
}


CGRect Rect2CGRect(const Rect &inRect) {
  CGRect outRect;
  outRect.origin.x = inRect.left;
  outRect.origin.y = inRect.top;
  outRect.size.width = inRect.right - inRect.left;
  outRect.size.height = inRect.bottom - inRect.top;
  return outRect;
}


// Paint a round rect, with the corner radius you specify, either filled or
// stroked.
void PaintRoundedCGRect(CGContextRef context,
                        CGRect rect,
                        float radius,
                        bool fill) {
  CGFloat lx = CGRectGetMinX(rect);
  CGFloat cx = CGRectGetMidX(rect);
  CGFloat rx = CGRectGetMaxX(rect);
  CGFloat by = CGRectGetMinY(rect);
  CGFloat cy = CGRectGetMidY(rect);
  CGFloat ty = CGRectGetMaxY(rect);

  CGContextBeginPath(context);
  CGContextMoveToPoint(context, lx, cy);
  CGContextAddArcToPoint(context, lx, by, cx, by, radius);
  CGContextAddArcToPoint(context, rx, by, rx, cy, radius);
  CGContextAddArcToPoint(context, rx, ty, cx, ty, radius);
  CGContextAddArcToPoint(context, lx, ty, lx, cy, radius);
  CGContextClosePath(context);

  if (fill)
    CGContextFillPath(context);
  else
    CGContextStrokePath(context);
}

}  // namespace o3d
