/**
 * 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_NODE_RENDER_OBJECT_H_
#define CORE_RENDER_NODE_RENDER_OBJECT_H_

#include <functional>
#include <map>
#include <set>
#include <string>

#include "core/render/node/factory/render_object_interface.h"

#define JSON_OBJECT_MARK_CHAR '{'
#define JSON_ARRAY_MARK_CHAR '['

#define convert_render_object_to_long(render) ((jlong)((intptr_t)render))

#define convert_long_to_render_object(ptr) ((RenderObject *)((intptr_t)ptr))

namespace WeexCore {

class RenderObject;

class RenderPage;

typedef enum StyleType {
  kTypeStyle,
  kTypeLayout,
  kTypeMargin,
  kTypePadding,
  kTypeBorder
} StyleType;

class RenderObject : public IRenderObject {
  friend class RenderPage;

 public:
  void LayoutBeforeImpl();

  void LayoutAfterImpl();

  void CopyFrom(RenderObject *src);

  void MapInsertOrAssign(std::map<std::string, std::string> *targetMap,
                         const std::string &key, const std::string &value);

  bool ViewInit();

  virtual std::map<std::string, std::string> *GetDefaultStyle() {
    return nullptr;
  }

  virtual std::map<std::string, std::string> *GetDefaultAttr() {
    return nullptr;
  }

 protected:
  bool UpdateStyleInternal(const std::string key, const std::string value,
                           float fallback, std::function<void(float)> functor);

 public:
  RenderObject();

  ~RenderObject();

  void BindMeasureFunc();

  void OnLayoutBefore();

  void OnLayoutAfter(float width, float height);

  virtual StyleType ApplyStyle(const std::string &key, const std::string &value,
                               const bool updating);

  void ApplyDefaultStyle();

  void ApplyDefaultAttr();

  Index IndexOf(const RenderObject *render);

  virtual int AddRenderObject(int index, RenderObject *child);

  float GetViewPortWidth();

  const std::string GetAttr(const std::string &key);

  const std::string GetStyle(const std::string &key);

  RenderPage *GetRenderPage();

  virtual void UpdateAttr(std::string key, std::string value);

  virtual StyleType UpdateStyle(std::string key, std::string value);

  bool IsAppendTree();

  RenderObject *GetChild(const Index &index);

  void RemoveRenderObject(RenderObject *child);

  void AddAttr(std::string key, std::string value);

  StyleType AddStyle(std::string key, std::string value);

  void AddEvent(std::string event);

  void RemoveEvent(const std::string &event);

 public:
  inline void set_parent_render(RenderObject *render) {
    this->parent_render_ = render;
  }

  inline RenderObject *parent_render() { return this->parent_render_; }

  inline std::map<std::string, std::string> *styles() const {
    return this->styles_;
  }

  inline std::map<std::string, std::string> *attributes() const {
    return this->attributes_;
  }

  inline std::set<std::string> *events() const { return this->events_; }

  inline void set_is_root_render() { this->is_root_render_ = true; }

  inline bool is_root_render() { return this->is_root_render_; }

  inline bool is_sticky() { return this->is_sticky_; }

 private:
  RenderObject *parent_render_;
  std::map<std::string, std::string> *styles_;
  std::map<std::string, std::string> *attributes_;
  std::set<std::string> *events_;
  bool is_root_render_;
  bool is_sticky_ = false;
};
}  // namespace WeexCore
#endif  // CORE_RENDER_NODE_RENDER_OBJECT_H_
