/**
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you 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 CORE_RENDER_PAGE_RENDER_PAGE_H_
#define CORE_RENDER_PAGE_RENDER_PAGE_H_

#include <atomic>
#include <cmath>
#include <map>
#include <string>
#include <utility>
#include <vector>

#include "render_page_base.h"
#include "core/css/constants_value.h"

namespace WeexCore {

class RenderAction;
class RenderObject;

class RenderPage: public RenderPageBase {
 private:
  void TraverseTree(RenderObject *render, long index);

  void SendCreateBodyAction(RenderObject *render);

  void SendAddElementAction(RenderObject *child, RenderObject *parent,
                            int index, bool is_recursion,
                            bool will_layout = true);
  void SendAddChildToRichtextAction(RenderObject *child, RenderObject *parent, RenderObject *richtext);

  void SendRemoveElementAction(const std::string &ref);

  void SendRemoveChildFromRichtextAction(const std::string &ref, RenderObject *parent, RenderObject *richtext);

  void SendMoveElementAction(const std::string &ref,
                             const std::string &parent_ref, int index);

  void SendLayoutAction(RenderObject *render, int index);

  void SendUpdateStyleAction(
      RenderObject *render,
      std::vector<std::pair<std::string, std::string>> *style,
      std::vector<std::pair<std::string, std::string>> *margin,
      std::vector<std::pair<std::string, std::string>> *padding,
      std::vector<std::pair<std::string, std::string>> *border);

  void SendUpdateRichtextChildStyleAction(RenderObject *render, std::vector<std::pair<std::string, std::string>> *style, RenderObject *parent, RenderObject *richtext);

  void SendUpdateAttrAction(
      RenderObject *render,
      std::vector<std::pair<std::string, std::string>> *attrs);

 void SendUpdateRichtextChildAttrAction(
                              RenderObject *render,
                              std::vector<std::pair<std::string, std::string>> *attrs, RenderObject *parent, RenderObject *richtext);
  void SendAppendTreeCreateFinish(const std::string &ref);
  
  void LayoutInner();

public:
  explicit RenderPage(const std::string& page_id);

  ~RenderPage();

  void CalculateLayout();

  bool CreateRootRender(RenderObject *root);

  bool AddRenderObject(const std::string &parent_ref, int insert_posiotn,
                       RenderObject *child);

  virtual bool RemoveRenderObject(const std::string &ref) override;

  virtual bool MoveRenderObject(const std::string &ref, const std::string &parent_ref, int index) override;

  virtual bool UpdateStyle(const std::string &ref,
                   std::vector<std::pair<std::string, std::string>> *styles) override;

  virtual bool UpdateAttr(const std::string &ref,
                  std::vector<std::pair<std::string, std::string>> *attrs) override;

  virtual void SetDefaultHeightAndWidthIntoRootRender(
      const float default_width, const float default_height,
      const bool is_width_wrap_content, const bool is_height_wrap_content) override;

  virtual bool AddEvent(const std::string &ref, const std::string &event) override;

  virtual bool RemoveEvent(const std::string &ref, const std::string &event) override;

  virtual bool CreateFinish() override;

  void Batch();

  void LayoutImmediately();

  void SendUpdateAttrAction(RenderObject *render,
                            std::map<std::string, std::string> *attrs);

  virtual RenderObject *GetRenderObject(const std::string &ref) override;

  void SetRootRenderObject(RenderObject *root);
    
  // ****** Render object managing ****** //
  
  void PushRenderToRegisterMap(RenderObject *render);
    
  void RemoveRenderFromRegisterMap(RenderObject *render);

  // ****** Life Cycle ****** //

  void OnRenderPageInit();

  void OnRenderProcessStart();

  void OnRenderProcessExited();

  void OnRenderProcessGone();

  virtual void OnRenderPageClose() override;
  
  // Re-apply raw css styles to page and trigger layout
  virtual bool ReapplyStyles() override;

 public:

  inline bool is_dirty() { return this->is_dirty_.load(); }

  void set_is_dirty(bool dirty);

  inline void set_is_render_container_width_wrap_content(bool wrap) {
    this->is_render_container_width_wrap_content_.store(wrap);
  }

  inline bool is_render_container_width_wrap_content() {
    return this->is_render_container_width_wrap_content_.load();
  }


  virtual float GetViewportWidth() override { return viewport_width_; }
  virtual void SetViewportWidth(float value) override { viewport_width_ = value; };
  virtual bool GetRoundOffDeviation() override { return round_off_deviation_; }
  virtual void SetRoundOffDeviation(bool value) override { round_off_deviation_ = value; }
  virtual float GetDeviceWidth() override { return device_width_; }
  virtual void SetDeviceWidth(float value) override { device_width_ = value; }

  inline float viewport_width() const { return this->viewport_width_; }

  inline void set_viewport_width(float viewport_width) {
    this->viewport_width_ = viewport_width;
  }

  inline float device_width(){
    return this->device_width_;
  }

  inline void set_device_width(float device_width){
    this->device_width_ = device_width;
  }

  inline bool round_off_deviation() const { return this->round_off_deviation_; }

  inline void set_round_off_deviation(bool round_off_deviation) { this->round_off_deviation_ = round_off_deviation; }
  
  inline bool reserve_css_styles() const { return reserve_css_styles_; }
  
  inline void set_reserve_css_styles(bool value) { reserve_css_styles_ = value; }

  inline void set_before_layout_needed(bool v) { is_before_layout_needed_.store(v); }

  inline void set_platform_layout_needed(bool v) { is_platform_layout_needed_.store(v); }

  inline void set_after_layout_needed(bool v) { is_after_layout_needed_.store(v); }

 public:
  static constexpr bool kUseVSync = true;
  std::atomic_bool need_layout_{false};
  std::atomic_bool has_fore_layout_action_{false};

 private:
  RenderObject *render_root_ = nullptr;
  std::pair<float, float> render_page_size_;
  std::map<std::string, RenderObject *> render_object_registers_;
  std::atomic_bool is_dirty_{true};
  std::atomic_bool is_render_container_width_wrap_content_{false};
  std::atomic_bool is_render_container_height_wrap_content_{false};
  std::atomic_bool is_before_layout_needed_{true};
  std::atomic_bool is_platform_layout_needed_{false};
  std::atomic_bool is_after_layout_needed_{true};
  float viewport_width_ = -1;
  float device_width_ = -1;
  bool round_off_deviation_ = kDefaultRoundOffDeviation;
  bool reserve_css_styles_ = false;
};
}  // namespace WeexCore

#endif  // CORE_RENDER_PAGE_RENDER_PAGE_H_
