package com.jaa.camera;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.ImageFormat;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.os.Environment;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.TextView;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;


public class CameraSurfaceView extends SurfaceView  
    implements  SurfaceHolder.Callback, Camera.PreviewCallback {
    
    public static final int JPEG_QUALITY = 70;
    
    private Camera camera;
    private Camera.Parameters parameters;
    
    private byte[] previewFrame;
    
    private int prevY;
    private int prevX;
    private static int prevSize;
    
    private int moveX;
    private int moveY;
    
    private SurfaceHolder prevHolder;
	
    private Bitmap bmp;
    private Paint paint;
    
    private boolean showFps;
    private int fps;
    private long time;
    private TextView fpsTextView;
    
    public CameraSurfaceView(Context c, AttributeSet s) {
	super(c, s);
	
	this.camera = Camera.open();
	this.paint = new Paint();
	
	setWillNotDraw(false);
	
	showFps = false;
	fps = 0;
	
	
	prevHolder = this.getHolder();
	prevHolder.addCallback(this);
    }
    
    
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
	parameters = camera.getParameters();
	Camera.Size size = getBestPreviewSize(width, height, parameters);  
	this.prevX = size.width;
	this.prevY = size.height;
	prevSize = prevX * prevY;
	
	if(prevX != width) {
	    moveX = (width - prevX) / 2;
	}
	if(prevY  != height) {
	    moveY = (height - prevY) / 2;
	}
	
	parameters.setPreviewSize(size.width, size.height);
	camera.setParameters(parameters);
	
//	ImageConversion.prevX = prevX;
//	ImageConversion.prevY = prevY;	
//	ImageConversion.csv = this;
	
	//converter = new ConvertThread(this, prevY, prevX);
	
	rgba = new int[prevX * prevY+1];
	
	this.previewFrame = new byte[prevX * prevY * 3 / 2];
	
	camera.addCallbackBuffer(new byte[prevX*prevY*3/2]);
	camera.setPreviewCallbackWithBuffer(this);
	camera.startPreview();
	//converter.start();
    }
    

    public void surfaceDestroyed(SurfaceHolder arg0) {
	bmp = null;
	camera.stopPreview();
	camera.release();
    }
    
    
    @Override
    protected void onDraw(Canvas canvas) {
	if((ALG && rgba == null) || (!ALG && bmp ==null)) {
	    return;
	}
	
	fps++;
	if(showFps && System.currentTimeMillis() > time + 1000) {
	    fpsTextView.setText("fps: " + fps);
	    fps = 0;
	    time = System.currentTimeMillis();
	}
	if(!ALG)
	    canvas.drawBitmap(bmp, moveX, moveY, paint);
	else
	    canvas.drawBitmap(rgba, 0, prevX, moveX, moveY, prevX, prevY, false, null);
    }
    
    public void onPreviewFrame(byte[] yuvsSource, Camera camera) {
	
	//System.arraycopy(yuvsSource, 0, previewFrame, 0, prevX*prevY*3/2);
	previewFrame = yuvsSource;
	
	createBitmap();
	
	invalidate();
	camera.addCallbackBuffer(yuvsSource);
	
    }
    
    public void setBitmap(Bitmap bitmap) {
	this.bmp = bitmap;
    }
    
    
    /**
     */
    public void createBitmap() {
	
	    YuvImage yuvimage;
	    ByteArrayOutputStream baos;

	    yuvimage = new YuvImage(this.previewFrame, ImageFormat.NV21, prevX, prevY, null);

	    baos = new ByteArrayOutputStream();
	    yuvimage.compressToJpeg(new Rect(0, 0, prevX, prevY), JPEG_QUALITY, baos);

	    bmp = BitmapFactory.decodeByteArray(baos.toByteArray(), 0, baos.size());
    }
    
    
    private Camera.Size getBestPreviewSize(int width, int height, Camera.Parameters parameters) {
	    Camera.Size result = null;	    
	    
	    for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
		//Log.d("tag", size.width + "x" + size.height);
		if (size.width <= width && size.height <= height) {
		    if (result == null) {
			result = size;
			continue;
		    }
		    else {
			int resultArea = result.width * result.height;
			int newArea = size.width * size.height;

			if (newArea > resultArea) {
			    result = size;
			}
		    }
		}
	    }	    
	    return result;
	}

    public void setFpsTextView(TextView fpsTextView) {
	this.fpsTextView = fpsTextView;
	time = System.currentTimeMillis();
	showFps = true;
    }

    public void surfaceCreated(SurfaceHolder arg0) {
    
    }
    
    
}