#!mojo mojo:sky
<import src="sky:core" as="sky"/>
<script>
 class BeehiveLayoutManager extends sky.LayoutManager {
   function layout(width, height) {
     if (width == null)
       width = this.getIntrinsicWidth().value;
     let autoHeight = false;
     if (height == null) {
       height = 0;
       autoHeight = true;
     }
     this.assumeDimensions(width, height);
     let cellCount = this.node.getProperty('beehive-count');
     let cellDim = width / cellCount;
     let children = this.walkChildren();
     let loop = children.next();
     let x = 0;
     let y = 0;
     while (!loop.done) {
       let child = loop.value;
       if (child.needsLayout) {
         child.layoutManager.layout(cellDim, cellDim);
         // we ignore the size the child reported from layout(), and force it to the cell dimensions
         this.setChildSize(child, cellDim, cellDim);
       } else if (child.descendantNeedsLayout) {
         child.layoutManager.layoutDescendants();
         this.setChildSize(child, cellDim, cellDim);
       }
       this.setChildPosition(child, x * cellDim + (y % 2) * cellDim/2, y * 3/4 * cellDim);
       x += 1;
       if (x > cellCount) {
         y += 1;
         x = 0;
       }
       loop = children.next();
     }
     if (height == 0)
       height = (1 + y * 3/4) * cellDim;
     this.markAsLaidOut();
     return {
       width: width,
       height: height,
     }
   }
   function getIntrinsicHeight() {
     let height = this.node.getProperty('height');
     if (typeof height != 'number') {
       // e.g. height: auto
       width = this.getIntrinsicWidth().value;
       let cellCount = this.node.getProperty('beehive-count');
       let cellDim = width / cellCount;
       let children = this.walkChildren();
       let loop = children.next();
       let childCount = 0;
       while (!loop.done) {
         childCount += 1;
         loop.next();
       }
       if (childCount > 0)
         height = cellDim * (1/4 + Math.ceil(childCount / cellCount) * 3/4);
       else
         height = 0;
     }
     return super(height); // does the equivalent of getIntrinsicWidth() above, applying min-height etc
   }
   function paintChildren(canvas) {
     let width = this.node.width;
     let cellCount = this.node.getProperty('beehive-count');
     let cellDim = width / cellCount;
     let children = this.walkChildren();
     let loop = children.next();
     while (!loop.done) {
       let child = loop.value;
       canvas.save();
       try {
         canvas.beginPath();
         canvas.moveTo(child.x, child.y + cellDim/4);
         canvas.lineTo(child.x + cellDim/2, child.y);
         canvas.lineTo(child.x + cellDim, child.y + cellDim/4);
         canvas.lineTo(child.x + cellDim, child.y + 3*cellDim/4);
         canvas.lineTo(child.x + cellDim/2, child.y + cellDim);
         canvas.moveTo(child.x, child.y + 3*cellDim/4);
         canvas.closePath();
         canvas.clip();
         canvas.paintChild(child);
       } finally {
         canvas.restore();
       }
       loop = children.next();
     }
   }
   function inHex(topLeftX, topLeftY, width, height, hitX, hitY) {
     let centerX = topLeftX - width/2;
     let absCenteredHitX = Math.abs(hitX - centerX);
     if (absCenteredHitX > width/2)
       return false;
     let centerY = topLeftY - height/2;
     let absCenteredHitY = Math.abs(hitY - centerY);
     if (absCenteredHitY > height/2)
       return false;
     if (absCenteredHitY < height * absCenteredHitX / (2 * width) + height / 2)
       return true;
     return false;
   }
   function hitTest(x, y) {
     let cellCount = this.node.getProperty('beehive-count');
     let cellDim = width / cellCount;
     let children = this.walkChildren();
     let loop = children.next();
     while (!loop.done) {
       let child = loop.value;
       if (this.inHex(child.x, child.y, child.width, child.height, x, y))
         return child.layoutManager.hitTest(x-child.x, y-child.y);
       loop = children.next();
     }
     return this.node;
   }
 }
 sky.registerLayoutManager('beehive', BeehiveLayoutManager);
 let BeehiveCountStyleGrammar = new StyleGrammar();
 BeehiveCountStyleGrammar.addParser((tokens) => {
   let token = tokens.next();
   if (token.done)
     throw new Error();
   if (token.value.kind != 'number')
     throw new Error();
   if (token.value.value <= 0)
     throw new Error();
   if (Math.trunc(token.value.value) != token.value.value) // is integer
     throw new Error();
   return new NumericStyleValue(token.value.value);
 });
 sky.registerProperty({
   name: 'beehive-count',
   type: BeehiveCountStyleGrammar,
   inherits: true,
   initialValue: 5,
   needsLayout: true,
 });
</script>
<style>
 div { display: beehive; beehive-count: 3; }
</style>
<div>
 <t>Hello</t>
 <t>World</t>
 <t>How</t>
 <t>Are</t>
 <t>You</t>
 <t>Today?</t>
</div>
