package framework.RWT;

import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;
import javax.microedition.khronos.opengles.GL11Ext;
import android.content.res.Resources;
import android.opengl.GLUtils;

import framework.model3D.Position3D;
import java3d.ImageComponent2D;
import java3d.Texture;
import java3d.TextureLoader;

/**
 * 画像管理クラス
 * 座標は左下が原点であることに注意(DirectXは左上のため)
 *
 * @author s.iwatani
 */
public class RWTSprite {
    private int[] textureId = null;
    private RWTImageLoader texLoader;
    private Texture tex;
    private ImageComponent2D image = null;

    // 表示座標
    private Position3D pos = new Position3D(0.f, 0.f, 0.f);
    private Position3D texSize = new Position3D(0.f, 0.f, 0.f);
    private Position3D texPos = new Position3D(0.f, 0.f, 0.f);
    private Position3D viewSize = new Position3D(0.f, 0.f, 0.f);

    public RWTSprite(final RWTSurfaceView view) {
        view.addSprite(this);
    }

    /**
     * 表示する座標を取得
     *
     * @author s.iwatani
     * @return Position3D
     */
    final public Position3D getPosition() {
        return pos;
    }

    /**
     * 表示サイズを取得
     *
     * @author s.iwatani
     * @return Position3D
     */
    final public Position3D getViewSize() {
        return viewSize;
    }

    /**
     * 画像サイズを取得
     *
     * @author s.iwatani
     * @return Position3D
     */
    final public Position3D getTextureSize() {
        return texSize;
    }

    /**
     * 描画する座標をセット
     *
     * @author s.iwatani
     * @param x x座標
     * @param y y座標
     */
    public void setPosition(float x, float y) {
        pos.setX(x);
        pos.setY(y);
    }

    /**
     * 描画する座標をセット
     * @param pos Position3D
     */
    public void setPosition(Position3D pos) {
        setPosition((float)pos.getX(), (float)pos.getY());
    }

    /**
     * テクスチャをセット
     *
     * @author s.iwatani
     * @param res Resources
     * @param id リソースのID R.drawable.なんちゃらみたいなやつ
     *
     * TODO: 画像サイズが元と違うため,そのサイズが元のものになるようにする
     *       Bitmap.createScaledBitmap(robot, 100, 100, false);のやつ
     */
    public void setTexture(Resources res, int id, boolean isEnableAlpha) {
        texLoader = new RWTImageLoader(res, id,
                                        TextureLoader.BY_REFERENCE | TextureLoader.Y_UP,
                                        isEnableAlpha ? ImageComponent2D.FORMAT_RGBA : ImageComponent2D.FORMAT_RGB);
        image = texLoader.getImage();
        tex = texLoader.getTexture();
        texPos.setX(0.f);
        texPos.setY(image.getBitmap().getHeight());
        texSize.setX(image.getBitmap().getWidth());
        texSize.setY(-image.getBitmap().getHeight());
        pos.set(0.0, 0.0, 0.0);
        viewSize.setX((float)image.getBitmap().getWidth());
        viewSize.setY((float)image.getBitmap().getHeight());
    }

    /**
     * 画像を描画する
     *
     * @author s.iwatani
     * @param gl GL10
     */
    public void draw(GL10 gl) {
        boolean isNullTextureId = textureId == null;
        if (isNullTextureId) {
            textureId = new int[1];
            gl.glGenTextures(1, textureId, 0);
        }
        //テクスチャIDに対応するテクスチャをバインドする
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureId[0]);

        // 初回のみ画像を流し込む
        if (isNullTextureId) {
            GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, image.getBitmap(), 0);
        }

        // 拡大縮小のアルゴリズム指定
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);

        int rect[] = { (int)texPos.getX(), (int)texPos.getY(), (int)texSize.getX(), (int)texSize.getY()};
        ((GL11) gl).glTexParameteriv(GL10.GL_TEXTURE_2D,GL11Ext.GL_TEXTURE_CROP_RECT_OES, rect, 0);
        ((GL11Ext) gl).glDrawTexfOES((int)pos.getX(), (int)pos.getY(), (int)pos.getZ(), (int)viewSize.getX(), (int)viewSize.getY());
    }
}
