<commit_before>package jkanvas.painter.pod;

import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RectangularShape;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import jkanvas.Camera;
import jkanvas.KanvasContext;
import jkanvas.animation.AnimationList;
import jkanvas.painter.CachedRenderpass;
import jkanvas.painter.Renderpass;
import jkanvas.painter.RenderpassPainter;

/**
 * A thin wrapper around a render pass. Thin wrapper do ignore each other
 * allowing to stack them on top of each other.
 * 
 * @author Joschi <<EMAIL>>
 * @param <T> The innermost wrapped type.
 */
public abstract class Renderpod<T extends Renderpass> extends CachedRenderpass {

  /** The render pass in a list for easier handling. */
  private final List<Renderpass> list;
  /**
   * The decorated render pass or <code>null</code> if another wrapper was
   * handed in.
   */
  private final T pass;

  private final CachedRenderpass cache;
  /** Another wrapper if render pass is <code>null</code>. */
  private final Renderpod<T> wrapper;

  private boolean active = true;

  /**
   * Creates a thin wrapper around the given render pass. You may set the offset
   * of the render pass via {@link #setChildOffset(double, double)} after the
   * initialization.
   * 
   * @param wrap The render pass to wrap.
   */
  public Renderpod(final T wrap) {
    if(wrap instanceof Renderpod) {
      wrapper = (Renderpod<T>) Objects.requireNonNull(wrap);
      cache = wrapper.hasCache() ? wrapper : null;
      pass = null;
    } else {
      pass = Objects.requireNonNull(wrap);
      cache = wrap instanceof CachedRenderpass ? (CachedRenderpass) wrap : null;
      wrapper = null;
    }
    list = Collections.singletonList((Renderpass) wrap);
    list.get(0).setParent(this);
  }

  /**
   * Creates a thin wrapper around the given render pass. You may set the offset
   * of the render pass via {@link #setChildOffset(double, double)} after the
   * initialization.
   * 
   * @param wrap The wrapper to wrap.
   */
  public Renderpod(final Renderpod<T> wrap) {
    wrapper = Objects.requireNonNull(wrap);
    wrapper.setParent(this);
    cache = wrap.hasCache() ? wrap : null;
    list = Collections.singletonList((Renderpass) wrapper);
    pass = null;
  }

  public boolean isActive() {
    return active;
  }

  public void setActive(final boolean active) {
    this.active = active;
    invalidateCache();
  }

  @Override
  public boolean hasCache() {
    return cache != null;
  }

  /**
   * Getter.
   * 
   * @return Gets the innermost wrapped render pass.
   */
  public T unwrap() {
    Renderpod<T> p = this;
    while(p.wrapper != null) {
      p = p.wrapper;
    }
    return p.pass;
  }

  /**
   * Getter.
   * 
   * @return The x offset of the inner render pass in relation to the parent of
   *         this render pod.
   */
  public double unwrapOffsetX() {
    double x = 0;
    Renderpod<T> p = this;
    while(p.wrapper != null) {
      p = p.wrapper;
      x += p.getOffsetX();
    }
    final Renderpass rp = p.list.get(0);
    final Renderpass pass = list.get(0);
    x += rp.getOffsetX() - pass.getOffsetX();
    return x + getOffsetX();
  }

  /**
   * Getter.
   * 
   * @return The y offset of the inner render pass in relation to the parent of
   *         this render pod.
   */
  public double unwrapOffsetY() {
    double y = 0;
    Renderpod<T> p = this;
    while(p.wrapper != null) {
      p = p.wrapper;
      y += p.getOffsetY();
    }
    final Renderpass rp = p.list.get(0);
    final Renderpass pass = list.get(0);
    y += rp.getOffsetY() - pass.getOffsetY();
    return y + getOffsetY();
  }

  /**
   * Computes the bounding box of the inner render pass in relation to the
   * parent of this render pod.
   * 
   * @param bbox The bounding box to store the result in.
   */
  public void unwrapBoundingBox(final RectangularShape bbox) {
    unwrap().getBoundingBox(bbox);
  }

  /**
   * Getter.
   * 
   * @return The parent pod or <code>null</code> if this is the final pod.
   */
  public Renderpod<T> getChildPod() {
    return wrapper;
  }

  /**
   * Sets the offset of the wrapped render pass.
   * 
   * @param x The x offset.
   * @param y The y offset.
   */
  protected final void setChildOffset(final double x, final double y) {
    final Renderpass pass = list.get(0);
    pass.setOffset(x, y);
  }

  /**
   * Computes the inner bounding box ignoring all other wrap render passes.
   * 
   * @param bbox The bounding box in which can be drawn.
   */
  protected final void getInnerBoundingBox(final Rectangle2D bbox) {
    double x = 0;<commit_msg>access to inner bbox<commit_after>package jkanvas.painter.pod;

import java.awt.Graphics2D;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RectangularShape;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

import jkanvas.Camera;
import jkanvas.KanvasContext;
import jkanvas.animation.AnimationList;
import jkanvas.painter.CachedRenderpass;
import jkanvas.painter.Renderpass;
import jkanvas.painter.RenderpassPainter;

/**
 * A thin wrapper around a render pass. Thin wrapper do ignore each other
 * allowing to stack them on top of each other.
 * 
 * @author Joschi <<EMAIL>>
 * @param <T> The innermost wrapped type.
 */
public abstract class Renderpod<T extends Renderpass> extends CachedRenderpass {

  /** The render pass in a list for easier handling. */
  private final List<Renderpass> list;
  /**
   * The decorated render pass or <code>null</code> if another wrapper was
   * handed in.
   */
  private final T pass;

  private final CachedRenderpass cache;
  /** Another wrapper if render pass is <code>null</code>. */
  private final Renderpod<T> wrapper;

  private boolean active = true;

  /**
   * Creates a thin wrapper around the given render pass. You may set the offset
   * of the render pass via {@link #setChildOffset(double, double)} after the
   * initialization.
   * 
   * @param wrap The render pass to wrap.
   */
  public Renderpod(final T wrap) {
    if(wrap instanceof Renderpod) {
      wrapper = (Renderpod<T>) Objects.requireNonNull(wrap);
      cache = wrapper.hasCache() ? wrapper : null;
      pass = null;
    } else {
      pass = Objects.requireNonNull(wrap);
      cache = wrap instanceof CachedRenderpass ? (CachedRenderpass) wrap : null;
      wrapper = null;
    }
    list = Collections.singletonList((Renderpass) wrap);
    list.get(0).setParent(this);
  }

  /**
   * Creates a thin wrapper around the given render pass. You may set the offset
   * of the render pass via {@link #setChildOffset(double, double)} after the
   * initialization.
   * 
   * @param wrap The wrapper to wrap.
   */
  public Renderpod(final Renderpod<T> wrap) {
    wrapper = Objects.requireNonNull(wrap);
    wrapper.setParent(this);
    cache = wrap.hasCache() ? wrap : null;
    list = Collections.singletonList((Renderpass) wrapper);
    pass = null;
  }

  public boolean isActive() {
    return active;
  }

  public void setActive(final boolean active) {
    this.active = active;
    invalidateCache();
  }

  @Override
  public boolean hasCache() {
    return cache != null;
  }

  /**
   * Getter.
   * 
   * @return Gets the innermost wrapped render pass.
   */
  public T unwrap() {
    Renderpod<T> p = this;
    while(p.wrapper != null) {
      p = p.wrapper;
    }
    return p.pass;
  }

  /**
   * Getter.
   * 
   * @return The x offset of the inner render pass in relation to the parent of
   *         this render pod.
   */
  public double unwrapOffsetX() {
    double x = 0;
    Renderpod<T> p = this;
    while(p.wrapper != null) {
      p = p.wrapper;
      x += p.getOffsetX();
    }
    final Renderpass rp = p.list.get(0);
    final Renderpass pass = list.get(0);
    x += rp.getOffsetX() - pass.getOffsetX();
    return x + getOffsetX();
  }

  /**
   * Getter.
   * 
   * @return The y offset of the inner render pass in relation to the parent of
   *         this render pod.
   */
  public double unwrapOffsetY() {
    double y = 0;
    Renderpod<T> p = this;
    while(p.wrapper != null) {
      p = p.wrapper;
      y += p.getOffsetY();
    }
    final Renderpass rp = p.list.get(0);
    final Renderpass pass = list.get(0);
    y += rp.getOffsetY() - pass.getOffsetY();
    return y + getOffsetY();
  }

  /**
   * Computes the bounding box of the inner render pass in relation to the
   * parent of this render pod.
   * 
   * @param bbox The bounding box to store the result in.
   */
  public void unwrapBoundingBox(final RectangularShape bbox) {
    unwrap().getBoundingBox(bbox);
  }

  /**
   * Getter.
   * 
   * @return The parent pod or <code>null</code> if this is the final pod.
   */
  public Renderpod<T> getChildPod() {
    return wrapper;
  }

  /**
   * Sets the offset of the wrapped render pass.
   * 
   * @param x The x offset.
   * @param y The y offset.
   */
  protected final void setChildOffset(final double x, final double y) {
    final Renderpass pass = list.get(0);
    pass.setOffset(x, y);
  }

  /**
   * Computes the inner bounding box ignoring all other wrap render passes.
   * 
   * @param bbox The bounding box in which can be drawn.
   */
  public final void getInnerBoundingBox(final Rectangle2D bbox) {
    double x = 0;
{'fraction_non_alphanumeric': 0.1084975630430176, 'fraction_numerical': 0.0027548209366391185, 'mean_word_length': 2.790763052208835, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6432578', 'n_tokens_mistral': 3017, 'n_tokens_neox': 2961, 'n_words': 960}