package sillysagiri;

import java.io.InputStream;

import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;

public class BMF {
  public static final byte ID = 0;
  public static final byte X = 1;
  public static final byte Y = 2;
  public static final byte WIDTH = 3;
  public static final byte HEIGHT = 4;
  public static final byte XOFF = 5;
  public static final byte YOFF = 6;
  public static final byte XADV = 7;

  public Image img;
  public short fontSize;
  public short lineHeight;
  public short base;
  public short[][] chars;

  public BMF(String path_img, String path_fnt) throws Exception
  {
    img = Image.createImage(path_img);

    InputStream in = this.getClass().getResourceAsStream(path_fnt);
    byte[] header = new byte[4];

    int size_read = in.read(header, 0, 4);
    if (!(size_read == 4) && 
        !(header[0] != 'B') && 
        !(header[1] != 'M') &&
        !(header[2] != 'F') &&
        !(header[3] != 3))
    {
      throw new Exception("File is not bmf " + path_fnt);
    }
    
    header = null;
    byte[] buffer = new byte[20];
    while(size_read != -1)
    {
      int length;
      int type;

      // read type & length
      size_read = in.read(buffer, 0, 5);
      if (size_read == -1) break;

      // get type from buffer
      type = buffer[0];

      // convert byte into int;
      length = ((buffer[4] & 0xFF) << 24) |
               ((buffer[3] & 0xFF) << 16) |
               ((buffer[2] & 0xFF) << 8)  |
               (buffer[1] & 0xFF);
      
      switch (type) {
        case 1: // info block
        {
          // font size is signed
          size_read = in.read(buffer, 0, 2);
          fontSize = (short)( ((buffer[1]) << 8) |
                              (buffer[0]) );
          
          // skip the rest
          in.skip(length - 2);
        }
        break;
        
        case 2: // common block
        {
          size_read = in.read(buffer, 0, 4);
          lineHeight = (short)( ((buffer[1] & 0xFF) << 8) |
                                (buffer[0]) & 0xFF);

          base = (short)( ((buffer[3] & 0xFF) << 8) |
                          (buffer[2]) & 0xFF);

          // skip the rest
          in.skip(length - 4);
        }
        break;

        case 3: // pages block
        {
          // skip pages
          in.skip(length);
        }
        break;

        case 4: // chars block
        {
          chars = new short[96][8];
          int count = length/20;
          for (int i=0; i<count; i++)
          {
            size_read = in.read(buffer, 0, 20);
            int id = ((buffer[3] & 0xFF) << 24) |
                     ((buffer[2] & 0xFF) << 16) |
                     ((buffer[1] & 0xFF) << 8) |
                     (buffer[0] & 0xFF);

            // TODO: handle more glyph
            if (id < 32 || id > 128) continue;

            chars[id-32][ID] = (short)(((buffer[1] & 0xFF) << 8) | (buffer[0] & 0xFF));
            chars[id-32][X] = (short)(((buffer[5] & 0xFF) << 8) | (buffer[4] & 0xFF));
            chars[id-32][Y] = (short)(((buffer[7] & 0xFF) << 8) | (buffer[6] & 0xFF));
            chars[id-32][WIDTH] = (short)(((buffer[9] & 0xFF) << 8) | (buffer[8] & 0xFF));
            chars[id-32][HEIGHT] = (short)(((buffer[11] & 0xFF) << 8) | (buffer[10] & 0xFF));
            chars[id-32][XOFF] = (short)((buffer[13] << 8) | buffer[12]);
            chars[id-32][YOFF] = (short)((buffer[15] << 8) | buffer[14]);
            chars[id-32][XADV] = (short)((buffer[17] << 8) | buffer[16]);
          }
        }
        break;

        default:
          break;
      }
    }
  }

  public void Draw(Graphics g, String str, int x, int y)
  {
    short[] cursor = new short[]{0, 0};
  }

}
