// Copyright 2014 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef COBALT_RENDER_TREE_COLOR_RGBA_H_
#define COBALT_RENDER_TREE_COLOR_RGBA_H_

#include "base/logging.h"

namespace cobalt {
namespace render_tree {

// Note: this does not handle infinities or nans.
inline float clamp(float input, float min, float max) {
#if defined(STARBOARD)
  if (SB_UNLIKELY(input < min)) return min;
  if (SB_UNLIKELY(input > max)) return max;
#else
  if (input < min) return min;
  if (input > max) return max;
#endif
  return input;
}

// Used to specify a color in the RGB (plus alpha) space.
// This color format is referenced by many render_tree objects in order to
// specify a color.
struct ColorRGBA {
 public:
  ColorRGBA() : r_(0), g_(0), b_(0), a_(0) {}

  ColorRGBA(float red, float green, float blue) {
    CheckRange(red);
    r_ = red;
    CheckRange(green);
    g_ = green;
    CheckRange(blue);
    b_ = blue;
    a_ = 1.0f;
  }

  ColorRGBA(float red, float green, float blue, float alpha) {
    CheckRange(red);
    r_ = red;
    CheckRange(green);
    g_ = green;
    CheckRange(blue);
    b_ = blue;
    CheckRange(alpha);
    a_ = alpha;
  }

  // Decodes the color value from 32-bit integer (4 channels, 8 bits each).
  // Note that alpha channel is mandatory, so opaque colors should be encoded
  // as 0xrrggbbff.
  explicit ColorRGBA(uint32_t rgba) {
    a_ = (rgba & 0xff) / 255.0f;
    rgba >>= 8;
    b_ = (rgba & 0xff) / 255.0f;
    rgba >>= 8;
    g_ = (rgba & 0xff) / 255.0f;
    rgba >>= 8;
    r_ = (rgba & 0xff) / 255.0f;
  }

  void set_r(float value) {
    CheckRange(value);
    r_ = value;
  }
  void set_g(float value) {
    CheckRange(value);
    g_ = value;
  }
  void set_b(float value) {
    CheckRange(value);
    b_ = value;
  }
  void set_a(float value) {
    CheckRange(value);
    a_ = value;
  }

  // These functions clamp the color channel values between 0.0f and 1.0f.
  float r() const { return clamp(r_, 0.0f, 1.0f); }
  float g() const { return clamp(g_, 0.0f, 1.0f); }
  float b() const { return clamp(b_, 0.0f, 1.0f); }
  float a() const { return clamp(a_, 0.0f, 1.0f); }

  uint8_t rgb8_r() const { return static_cast<uint8_t>(r() * 255); }

  uint8_t rgb8_g() const { return static_cast<uint8_t>(g() * 255); }

  uint8_t rgb8_b() const { return static_cast<uint8_t>(b() * 255); }

  uint8_t rgb8_a() const { return static_cast<uint8_t>(a() * 255); }

  ColorRGBA& operator=(const ColorRGBA& other) {
    r_ = other.r_;
    g_ = other.g_;
    b_ = other.b_;
    a_ = other.a_;
    return *this;
  }

  ColorRGBA& operator-=(const ColorRGBA& other) {
    r_ -= other.r_;
    g_ -= other.g_;
    b_ -= other.b_;
    a_ -= other.a_;
    return *this;
  }

  ColorRGBA& operator+=(const ColorRGBA& other) {
    r_ += other.r_;
    g_ += other.g_;
    b_ += other.b_;
    a_ += other.a_;
    return *this;
  }

  ColorRGBA& operator+=(const float f) {
    r_ += f;
    b_ += f;
    g_ += f;
    a_ += f;
    return *this;
  }

  ColorRGBA& operator-=(const float f) {
    r_ -= f;
    b_ -= f;
    g_ -= f;
    a_ -= f;
    return *this;
  }

  ColorRGBA& operator*=(const float f) {
    r_ *= f;
    b_ *= f;
    g_ *= f;
    a_ *= f;
    return *this;
  }

  ColorRGBA& operator/=(const float f) {
    float one_over_f(1.0f / f);
    *this *= one_over_f;
    return *this;
  }

  bool HasAlpha() const { return (a_ < 1.0f); }

 private:
  void CheckRange(float value) const {
    DCHECK_LE(0.0f, value);
    DCHECK_GE(1.0f, value);
  }

  float r_, g_, b_, a_;
};

inline bool operator==(const ColorRGBA& lhs, const ColorRGBA& rhs) {
  return lhs.r() == rhs.r() && lhs.g() == rhs.g() && lhs.b() == rhs.b() &&
         lhs.a() == rhs.a();
}

inline bool operator!=(const ColorRGBA& lhs, const ColorRGBA& rhs) {
  return !(lhs == rhs);
}

inline ColorRGBA operator-(const ColorRGBA& lhs, const ColorRGBA& rhs) {
  ColorRGBA color(lhs);
  color -= rhs;
  return color;
}

inline ColorRGBA operator+(const ColorRGBA& lhs, const ColorRGBA& rhs) {
  ColorRGBA color(lhs);
  color += rhs;
  return color;
}

inline ColorRGBA operator+(const ColorRGBA& lhs, const float rhs) {
  ColorRGBA color(lhs);
  color += rhs;
  return color;
}

inline ColorRGBA operator-(const ColorRGBA& lhs, const float rhs) {
  ColorRGBA color(lhs);
  color -= rhs;
  return color;
}

inline ColorRGBA operator*(const ColorRGBA& lhs, const float rhs) {
  ColorRGBA color(lhs);
  color *= rhs;
  return color;
}

inline ColorRGBA operator/(const ColorRGBA& lhs, const float rhs) {
  ColorRGBA color(lhs);
  color /= rhs;
  return color;
}

// Used by tests.
inline std::ostream& operator<<(std::ostream& stream, const ColorRGBA& color) {
  return stream << "rgba(" << color.r() << ", " << color.g() << ", "
                << color.b() << ", " << color.a() << ")";
}

}  // namespace render_tree
}  // namespace cobalt

#endif  // COBALT_RENDER_TREE_COLOR_RGBA_H_
