package com.io7m.jcanephora.examples.lwjgl30;

import java.nio.ByteBuffer;
import java.util.Properties;

import javax.annotation.Nonnull;

import org.lwjgl.opengl.Display;

import com.io7m.jaux.Constraints.ConstraintError;
import com.io7m.jcanephora.GLException;
import com.io7m.jcanephora.GLInterface;
import com.io7m.jcanephora.GLInterfaceLWJGL30;
import com.io7m.jcanephora.LWJGL30;
import com.io7m.jcanephora.Texture2DRGBA;
import com.io7m.jcanephora.TextureFilter;
import com.io7m.jcanephora.TextureWrap;
import com.io7m.jlog.Log;

public final class TextureExampleSimple
{
  private static int SCREEN_WIDTH   = 640;
  private static int SCREEN_HEIGHT  = 480;
  private static int TEXTURE_WIDTH  = 4;
  private static int TEXTURE_HEIGHT = 4;

  @SuppressWarnings("unused") public static void main(
    final String args[])
    throws ConstraintError,
      Error,
      GLException
  {
    LWJGL30.createDisplay(
      "TextureExample",
      TextureExampleSimple.SCREEN_WIDTH,
      TextureExampleSimple.SCREEN_HEIGHT);

    final Log log = new Log(new Properties(), "com.io7m", "example");
    final GLInterface gl = new GLInterfaceLWJGL30(log);

    try {
      new TextureExampleSimple(gl);
    } finally {
      Display.destroy();
    }
  }

  private final @Nonnull GLInterface gl;
  private final Texture2DRGBA        texture;

  public TextureExampleSimple(
    final GLInterface gl)
    throws ConstraintError,
      GLException
  {
    this.gl = gl;

    /*
     * Allocate an RGBA texture with the given filter and map modes.
     */

    this.texture =
      this.gl.allocateTextureRGBA(
        "Texture",
        TextureExampleSimple.TEXTURE_WIDTH,
        TextureExampleSimple.TEXTURE_HEIGHT,
        TextureWrap.TEXTURE_WRAP_REPEAT,
        TextureWrap.TEXTURE_WRAP_REPEAT,
        TextureFilter.TEXTURE_FILTER_NEAREST,
        TextureFilter.TEXTURE_FILTER_NEAREST);

    /*
     * Textures are automatically backed by a pixel unpack buffer. This buffer
     * is mapped into the program's address space in order to be populated
     * with bitmap data.
     */

    {
      final ByteBuffer map =
        this.gl
          .mapPixelUnpackBufferWrite(this.texture.getBuffer())
          .getByteBuffer();

      assert (map.remaining() == (TextureExampleSimple.TEXTURE_WIDTH
        * TextureExampleSimple.TEXTURE_HEIGHT * 4));

      final byte[] data = new byte[4];
      for (int y = 0; y < 4; ++y) {
        final double fy = y;
        for (int x = 0; x < 4; ++x) {
          final double fx = x;
          data[0] = (byte) (256.0 * (fx / 4.0));
          data[1] = (byte) (256.0 * (fy / 4.0));
          data[2] = (byte) 0xff;
          data[3] = (byte) 0xff;
          map.put(data);
        }
      }

      map.rewind();
      this.gl.unmapPixelUnpackBuffer(this.texture.getBuffer());
    }

    /*
     * Copy data from the pixel buffer into the texture.
     */

    this.gl.updateTexture2DRGBA(this.texture);
  }
}

@@ -44,36 +44,8 @@
 0;%0A%0A
-import java.nio.ByteBuffer;%0A
 impo
@@ -343,32 +343,151 @@
 ephora.LWJGL30;%0A
+import com.io7m.jcanephora.PixelUnpackBufferCursorWritable4b;%0Aimport com.io7m.jcanephora.PixelUnpackBufferWritableMap;%0A
 import com.io7m.
@@ -2162,46 +2162,163 @@
 ata.
-%0A     */%0A%0A    %7B%0A      final ByteBuffer
+ A cursor is obtained in order to safely insert four%0A     * values of type 'byte' for each element.%0A     */%0A%0A    %7B%0A      final PixelUnpackBufferWritableMap
  map
@@ -2335,27 +2335,16 @@
  this.gl
-%0A          
 .mapPixe
@@ -2391,199 +2391,79 @@
 r())
+;
 %0A      
-    .getByteBuffer();%0A%0A      assert (map.remaining() == (TextureExampleSimple.TEXTURE_WIDTH%0A        * TextureExampleSimple.TEXTURE_HEIGHT * 4));%0A%0A      final byte%5B%5D data = new byte%5B4%5D;
+final PixelUnpackBufferCursorWritable4b c = map.getCursor4b();%0A
 %0A   
@@ -2607,17 +2607,28 @@
     
-data%5B0%5D =
+c.put4b(%0A           
  (by
@@ -2643,33 +2643,33 @@
 .0 * (fx / 4.0))
-;
+,
 %0A          data%5B
@@ -2667,17 +2667,9 @@
     
-data%5B1%5D =
+ 
  (by
@@ -2692,17 +2692,17 @@
  / 4.0))
-;
+,
 %0A       
@@ -2708,17 +2708,9 @@
     
-data%5B2%5D =
+ 
  (by
@@ -2709,33 +2709,33 @@
      (byte) 0xff
-;
+,
 %0A          data%5B
@@ -2733,17 +2733,9 @@
     
-data%5B3%5D =
+ 
  (by
@@ -2746,32 +2746,8 @@
 0xff
-;%0A          map.put(data
 );%0A 
@@ -2774,20 +2774,35 @@
     
-map.rewind()
+assert c.hasNext() == false
 ;%0A  

Simplify texture example