// Copyright 2015 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.

#import "ios/web/public/ui/page_display_state.h"

#include <cmath>

#if !defined(__has_feature) || !__has_feature(objc_arc)
#error "This file requires ARC support."
#endif

namespace web {

namespace {
// Serialiation keys.
NSString* const kContentOffsetKey = @"contentOffset";
NSString* const kContentInsetKey = @"contentInset";
NSString* const kMinZoomKey = @"minZoom";
NSString* const kMaxZoomKey = @"maxZoom";
NSString* const kZoomKey = @"zoom";
// Invalid consts.
const CGPoint kInvalidContentOffset = {NAN, NAN};
const UIEdgeInsets kInvalidContentInset = {NAN, NAN, NAN, NAN};
// Equality checkers.  Return true if both values are NAN or equivalent.
inline bool StateValuesAreEqual(CGFloat value1, CGFloat value2) {
  return std::isnan(value1) ? std::isnan(value2) : value1 == value2;
}
inline bool StateContentOffsetsAreEqual(const CGPoint& offset1,
                                        const CGPoint& offset2) {
  return StateValuesAreEqual(offset1.x, offset2.x) &&
         StateValuesAreEqual(offset1.y, offset2.y);
}
inline bool StateContentInsetsAreEqual(const UIEdgeInsets& inset1,
                                       const UIEdgeInsets& inset2) {
  return StateValuesAreEqual(inset1.top, inset2.top) &&
         StateValuesAreEqual(inset1.left, inset2.left) &&
         StateValuesAreEqual(inset1.bottom, inset2.bottom) &&
         StateValuesAreEqual(inset1.right, inset2.right);
}
// Validity checker util functions.
inline bool IsContentOffsetValid(const CGPoint& content_offset) {
  return !std::isnan(content_offset.x) && !std::isnan(content_offset.y);
}
inline bool IsContentInsetValid(const UIEdgeInsets& content_inset) {
  return !std::isnan(content_inset.top) && !std::isnan(content_inset.left) &&
         !std::isnan(content_inset.bottom) && !std::isnan(content_inset.right);
}
// Returns the CGFloat stored under |key| in |serialization|, or NAN if it is
// not set.
inline CGFloat GetFloatValue(NSString* key, NSDictionary* serialization) {
  NSNumber* value = serialization[key];
  return value ? [value doubleValue] : NAN;
}
// Returns the contentOffset stored in |serialization|, or a NAN offset if it is
// not set.
inline CGPoint GetContentOffset(NSDictionary* serialization) {
  NSValue* value = serialization[kContentOffsetKey];
  if (value)
    return [value CGPointValue];
  return kInvalidContentOffset;
}
// Returns the contentInset stored in |serialization|, or a NAN inset if it is
// not set.
inline UIEdgeInsets GetContentInset(NSDictionary* serialization) {
  NSValue* value = serialization[kContentInsetKey];
  if (value)
    return [value UIEdgeInsetsValue];
  // Return an invalid inset if neither the new nor legacy keys were contained.
  return kInvalidContentInset;
}
}  // namespace

PageScrollState::PageScrollState()
    : content_offset_(kInvalidContentOffset),
      content_inset_(kInvalidContentInset) {}

PageScrollState::PageScrollState(const CGPoint& content_offset,
                                 const UIEdgeInsets& content_inset)
    : content_offset_(content_offset), content_inset_(content_inset) {}

PageScrollState::~PageScrollState() = default;

bool PageScrollState::IsValid() const {
  return IsContentOffsetValid(content_offset_) &&
         IsContentInsetValid(content_inset_);
}

CGPoint PageScrollState::GetEffectiveContentOffsetForContentInset(
    UIEdgeInsets content_inset) const {
  return CGPointMake(
      content_offset_.x + content_inset_.left - content_inset.left,
      content_offset_.y + content_inset_.top - content_inset.top);
}

bool PageScrollState::operator==(const PageScrollState& other) const {
  return StateContentOffsetsAreEqual(content_offset_, other.content_offset_) &&
         StateContentInsetsAreEqual(content_inset_, other.content_inset_);
}

bool PageScrollState::operator!=(const PageScrollState& other) const {
  return !(*this == other);
}

PageZoomState::PageZoomState()
    : minimum_zoom_scale_(NAN), maximum_zoom_scale_(NAN), zoom_scale_(NAN) {}

PageZoomState::PageZoomState(CGFloat minimum_zoom_scale,
                             CGFloat maximum_zoom_scale,
                             CGFloat zoom_scale)
    : minimum_zoom_scale_(minimum_zoom_scale),
      maximum_zoom_scale_(maximum_zoom_scale),
      zoom_scale_(zoom_scale) {}

PageZoomState::~PageZoomState() {}

bool PageZoomState::IsValid() const {
  return (!std::isnan(minimum_zoom_scale_) &&
          !std::isnan(maximum_zoom_scale_) && !std::isnan(zoom_scale_) &&
          zoom_scale_ >= minimum_zoom_scale_ &&
          zoom_scale_ <= maximum_zoom_scale_);
}

bool PageZoomState::operator==(const PageZoomState& other) const {
  return StateValuesAreEqual(minimum_zoom_scale_, other.minimum_zoom_scale_) &&
         StateValuesAreEqual(maximum_zoom_scale_, other.maximum_zoom_scale_) &&
         StateValuesAreEqual(zoom_scale_, other.zoom_scale_);
}

bool PageZoomState::operator!=(const PageZoomState& other) const {
  return !(*this == other);
}

PageDisplayState::PageDisplayState() {}

PageDisplayState::PageDisplayState(const PageScrollState& scroll_state,
                                   const PageZoomState& zoom_state)
    : scroll_state_(scroll_state), zoom_state_(zoom_state) {}

PageDisplayState::PageDisplayState(const CGPoint& content_offset,
                                   const UIEdgeInsets& content_inset,
                                   CGFloat minimum_zoom_scale,
                                   CGFloat maximum_zoom_scale,
                                   CGFloat zoom_scale)
    : scroll_state_(content_offset, content_inset),
      zoom_state_(minimum_zoom_scale, maximum_zoom_scale, zoom_scale) {}

PageDisplayState::PageDisplayState(NSDictionary* serialization)
    : PageDisplayState(GetContentOffset(serialization),
                       GetContentInset(serialization),
                       GetFloatValue(kMinZoomKey, serialization),
                       GetFloatValue(kMaxZoomKey, serialization),
                       GetFloatValue(kZoomKey, serialization)) {}

PageDisplayState::~PageDisplayState() {}

bool PageDisplayState::IsValid() const {
  return scroll_state_.IsValid() && zoom_state_.IsValid();
}

bool PageDisplayState::operator==(const PageDisplayState& other) const {
  return scroll_state_ == other.scroll_state_ &&
         zoom_state_ == other.zoom_state_;
}

bool PageDisplayState::operator!=(const PageDisplayState& other) const {
  return !(*this == other);
}

NSDictionary* PageDisplayState::GetSerialization() const {
  return @{
    kContentOffsetKey :
        [NSValue valueWithCGPoint:scroll_state_.content_offset()],
    kContentInsetKey :
        [NSValue valueWithUIEdgeInsets:scroll_state_.content_inset()],
    kMinZoomKey : @(zoom_state_.minimum_zoom_scale()),
    kMaxZoomKey : @(zoom_state_.maximum_zoom_scale()),
    kZoomKey : @(zoom_state_.zoom_scale())
  };
}

NSString* PageDisplayState::GetDescription() const {
  NSString* const kPageScrollStateDescriptionFormat =
      @"{ contentOffset:%@, contentInset:%@, zoomScaleRange:(%0.2f, %0.2f), "
      @"zoomScale:%0.2f }";
  return [NSString
      stringWithFormat:kPageScrollStateDescriptionFormat,
                       NSStringFromCGPoint(scroll_state_.content_offset()),
                       NSStringFromUIEdgeInsets(scroll_state_.content_inset()),
                       zoom_state_.minimum_zoom_scale(),
                       zoom_state_.maximum_zoom_scale(),
                       zoom_state_.zoom_scale()];
}

}  // namespace web
