/**
 * 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.
 */

#include "core/render/action/render_action_layout.h"
#include "core/manager/weex_core_manager.h"
#include "core/render/node/render_object.h"

namespace WeexCore {

RenderActionLayout::RenderActionLayout(const std::string &page_id,
                                       const RenderObject *render, int index) {
  this->page_id_ = page_id;
  this->ref_ = render->ref();
  this->index_ = index;
  GetLayoutInfo(render);
}

void RenderActionLayout::ExecuteAction() {
  WeexCoreManager::getInstance()->getPlatformBridge()->callLayout(
      this->page_id_.c_str(), this->ref_.c_str(), this->top_, this->bottom_,
      this->left_, this->right_, this->height_, this->width_, this->index_);
}

void RenderActionLayout::GetLayoutInfo(const WXCoreLayoutNode *node) {
  this->top_ = node->getLayoutPositionTop();
  this->bottom_ = node->getLayoutPositionBottom();
  this->right_ = node->getLayoutPositionRight();
  this->left_ = node->getLayoutPositionLeft();
  this->height_ = node->getLayoutHeight();
  this->width_ = node->getLayoutWidth();
}
}  // namespace WeexCore
