// Copyright 2013 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ios/chrome/browser/ui/ui_util.h"

#import <UIKit/UIKit.h>

#include "base/ios/ios_util.h"
#include "base/logging.h"
#import "ios/chrome/browser/ui/uikit_ui_util.h"
#include "ui/gfx/ios/uikit_util.h"

bool IsIPadIdiom() {
  UIUserInterfaceIdiom idiom = [[UIDevice currentDevice] userInterfaceIdiom];
  return idiom == UIUserInterfaceIdiomPad;
}

const CGFloat kPortraitWidth[INTERFACE_IDIOM_COUNT] = {
    320,  // IPHONE_IDIOM
    768   // IPAD_IDIOM
};

bool IsHighResScreen() {
  return [[UIScreen mainScreen] scale] > 1.0;
}

bool IsPortrait() {
  UIInterfaceOrientation orient = GetInterfaceOrientation();
// If building with an SDK prior to iOS 8 don't worry about
// UIInterfaceOrientationUnknown because it wasn't defined.
#if !defined(__IPHONE_8_0) || __IPHONE_OS_VERSION_MAX_ALLOWED < __IPHONE_8_0
  return UIInterfaceOrientationIsPortrait(orient);
#else
  return UIInterfaceOrientationIsPortrait(orient) ||
         orient == UIInterfaceOrientationUnknown;
#endif  // SDK
}

bool IsLandscape() {
  return UIInterfaceOrientationIsLandscape(GetInterfaceOrientation());
}

CGFloat CurrentScreenHeight() {
  CGSize screenSize = [UIScreen mainScreen].bounds.size;
  if (base::ios::IsRunningOnIOS8OrLater()) {
    return screenSize.height;
  } else {
    return IsPortrait() ? screenSize.height : screenSize.width;
  }
}

CGFloat CurrentScreenWidth() {
  CGSize screenSize = [UIScreen mainScreen].bounds.size;
  if (base::ios::IsRunningOnIOS8OrLater()) {
    return screenSize.width;
  } else {
    return IsPortrait() ? screenSize.width : screenSize.height;
  }
}

CGFloat StatusBarHeight() {
  // Checking [UIApplication sharedApplication].statusBarFrame will return the
  // wrong offset when the application is started while in a phone call, so
  // simply return 20 here.
  return 20;
}

CGFloat AlignValueToPixel(CGFloat value) {
  static CGFloat scale = [[UIScreen mainScreen] scale];
  return floor(value * scale) / scale;
}

CGPoint AlignPointToPixel(CGPoint point) {
  return CGPointMake(AlignValueToPixel(point.x), AlignValueToPixel(point.y));
}

CGRect AlignRectToPixel(CGRect rect) {
  rect.origin = AlignPointToPixel(rect.origin);
  return rect;
}

CGRect AlignRectOriginAndSizeToPixels(CGRect rect) {
  rect.origin = AlignPointToPixel(rect.origin);
  rect.size = ui::AlignSizeToUpperPixel(rect.size);
  return rect;
}

CGRect CGRectCopyWithOrigin(CGRect rect, CGFloat x, CGFloat y) {
  return CGRectMake(x, y, rect.size.width, rect.size.height);
}

CGRect CGRectMakeAlignedAndCenteredAt(CGFloat x, CGFloat y, CGFloat width) {
  return AlignRectOriginAndSizeToPixels(
      CGRectMake(x - width / 2.0, y - width / 2.0, width, width));
}

// Based on an original size and a target size applies the transformations.
void CalculateProjection(CGSize originalSize,
                         CGSize desiredTargetSize,
                         ProjectionMode projectionMode,
                         CGSize& targetSize,
                         CGRect& projectTo) {
  targetSize = desiredTargetSize;
  projectTo = CGRectZero;
  if (originalSize.height < 1 || originalSize.width < 1)
    return;
  if (targetSize.height < 1 || targetSize.width < 1)
    return;

  CGFloat aspectRatio = originalSize.width / originalSize.height;
  CGFloat targetAspectRatio = targetSize.width / targetSize.height;
  switch (projectionMode) {
    case ProjectionMode::kFill:
      // Don't preserve the aspect ratio.
      projectTo.size = targetSize;
      break;

    case ProjectionMode::kAspectFill:
      if (targetAspectRatio < aspectRatio) {
        // Clip the x-axis.
        projectTo.size.width = targetSize.height * aspectRatio;
        projectTo.size.height = targetSize.height;
        projectTo.origin.x = (targetSize.width - projectTo.size.width) / 2;
        projectTo.origin.y = 0;
      } else {
        // Clip the y-axis.
        projectTo.size.width = targetSize.width;
        projectTo.size.height = targetSize.width / aspectRatio;
        projectTo.origin.x = 0;
        projectTo.origin.y = (targetSize.height - projectTo.size.height) / 2;
      }
      break;

    case ProjectionMode::kAspectFit:
      if (targetAspectRatio < aspectRatio) {
        projectTo.size.width = targetSize.width;
        projectTo.size.height = projectTo.size.width / aspectRatio;
        targetSize = projectTo.size;
      } else {
        projectTo.size.height = targetSize.height;
        projectTo.size.width = projectTo.size.height * aspectRatio;
        targetSize = projectTo.size;
      }
      break;

    case ProjectionMode::kAspectFillNoClipping:
      if (targetAspectRatio < aspectRatio) {
        targetSize.width = targetSize.height * aspectRatio;
        targetSize.height = targetSize.height;
      } else {
        targetSize.width = targetSize.width;
        targetSize.height = targetSize.width / aspectRatio;
      }
      projectTo.size = targetSize;
      break;
  }

  projectTo = CGRectIntegral(projectTo);
  // There's no CGSizeIntegral, faking one instead.
  CGRect integralRect = CGRectZero;
  integralRect.size = targetSize;
  targetSize = CGRectIntegral(integralRect).size;
}