#!mojo mojo:sky
<import src="sky:core" as="sky"/>
<script>
 class BeehiveLayoutManager extends sky.LayoutManager {
   function layout(width, height) {
     this.markAsLaidOut();
     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);
       }
       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;
     return {
       width: width,
       height: height,
     }
   }
   function getIntrinsicWidth() {
     // this is the logic that LayoutManager.getIntrinsicWidth() has by default
     // shown here because I wrote it before realising it should be the default
     let width = this.node.getProperty('width');
     if (typeof width != 'number')
       width = 0;
     let minWidth = this.node.getProperty('min-width');
     if (typeof width != 'number')
       minWidth = 0;
     let maxWidth = this.node.getProperty('max-width');
     if (typeof width != 'number')
       maxWidth = Infinity;
     if (maxWidth < minWidth)
       maxWidth = minWidth;
     if (width > maxWidth)
       width = maxWidth;
     if (width < minWidth)
       width = minWidth;
     return {
       minimum: minWidth,
       value: width,
       maximum: maxWidth,
     };
   }
   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;
       if (child.needsPaint) {
         canvas.save();
         try {
           canvas.beginPath();
           canvas.translate(child.x, child.y);
           canvas.moveTo(0, cellDim/4);
           canvas.lineTo(cellDim/2, 0);
           canvas.lineTo(cellDim, cellDim/4);
           canvas.lineTo(cellDim, 3*cellDim/4);
           canvas.lineTo(cellDim/2, cellDim);
           canvas.moveTo(0, 3*cellDim/4);
           canvas.closePath();
           canvas.clip();
           child.paint(canvas);
         } 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 BeehiveCountStyleValueType = new StyleValueType();
 BeehiveCountStyleValueType.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 {
     value: token.value.value;
   }
 });
 sky.registerProperty({
   name: 'beehive-count',
   type: BeehiveCountStyleValueType,
   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>
