/*
 * 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;
  }

 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_
