/****************************************************************************
 * This file is part of the project AqDiagram.
 * AqDiagram (c) by 2023 Martin Preuss, all rights reserved.
 *
 * The license for this file can be found in the file COPYING which you
 * should have received along with this file.
 ****************************************************************************/

#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#include "o_hlayout.h"
#include "o_layout.h"

#include <gwenhywfar/debug.h>


/* ------------------------------------------------------------------------------------------------
 * forward declarations
 * ------------------------------------------------------------------------------------------------
 */

static int _layout(AQDG_OBJECT *object);
static int _calcContentWidth(AQDG_OBJECT *object);
static int _calcContentHeight(AQDG_OBJECT *object);



/* ------------------------------------------------------------------------------------------------
 * implementations
 * ------------------------------------------------------------------------------------------------
 */

AQDG_OBJECT *AQDG_HLayoutObject_new(AQDG_OBJECT *parent, uint32_t options)
{
  AQDG_OBJECT *object;

  object=AQDG_Object_new();
  AQDG_Object_SetName(object, "HLayoutObject");
  AQDG_Object_SetOptions(object, options);

  AQDG_Object_SetLayoutFn(object, _layout);
  AQDG_Object_SetGetDefaultWidthFn(object, _calcContentWidth);
  AQDG_Object_SetGetDefaultHeightFn(object, _calcContentHeight);

  if (parent)
    AQDG_Object_Tree2_AddChild(parent, object);
  return object;
}



int _layout(AQDG_OBJECT *object)
{
  int num;

  num=AQDG_LayoutObject_CountDirectChildren(object);
  if (num) {
    AQDG_PLACEMENT_LAYOUT_ELEMENT *elements;

    AQDG_LayoutObject_SetChildrenWidths(object);
    elements=AQDG_LayoutObject_Children2ElementsX(object, num);
    if (elements) {
      AQDG_Placement_LayoutAndStretch(elements, num,
                                      AQDG_Object_GetWidth(object),
                                      AQDG_Object_GetBorderLeft(object),
                                      AQDG_Object_GetBorderRight(object),
                                      AQDG_Object_GetHSpacing(object));
      AQDG_LayoutObject_ChildrenFromElementsX(object, elements, num);
      free(elements);
    }

    AQDG_LayoutObject_SetChildrenHeights(object);
    elements=AQDG_LayoutObject_Children2ElementsY(object, num);
    if (elements) {
      AQDG_Placement_LayoutSecondaryAxis(elements, num,
                                         AQDG_Object_GetHeight(object),
                                         AQDG_Object_GetBorderTop(object),
                                         AQDG_Object_GetBorderBottom(object));
      AQDG_LayoutObject_ChildrenFromElementsY(object, elements, num);
      free(elements);
    }
    AQDG_LayoutObject_LayoutChildren(object);
  }

  return 0;
}



int _calcContentWidth(AQDG_OBJECT *object)
{
  AQDG_OBJECT *child;
  int v;
  int spacing;

  v=AQDG_Object_GetBorderLeft(object);
  spacing=AQDG_Object_GetHSpacing(object);
  child=AQDG_Object_Tree2_GetFirstChild(object);
  while(child) {
    v+=AQDG_Object_GetDefaultWidth(child);
    child=AQDG_Object_Tree2_GetNext(child);
    if (child)
      v+=spacing;
  }
  v+=AQDG_Object_GetBorderRight(object);

  return v;
}



int _calcContentHeight(AQDG_OBJECT *object)
{
  AQDG_OBJECT *child;
  int v;

  v=AQDG_Object_GetBorderTop(object);
  child=AQDG_Object_Tree2_GetFirstChild(object);
  while(child) {
    int i;

    i=AQDG_Object_GetDefaultHeight(child);
    v=(i>v)?i:v;
    child=AQDG_Object_Tree2_GetNext(child);
  }
  v+=AQDG_Object_GetBorderBottom(object);

  return v;
}




