package com.camera.simplewebcam;

import android.content.Context;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Rect;

class CameraPreview extends SurfaceView implements SurfaceHolder.Callback, Runnable {

	private static final boolean DEBUG = true;
	protected Context context;
	private SurfaceHolder holder;
    Thread mainLoop = null;
	private Bitmap bmp=null;

	private boolean cameraExists=false;
	private boolean shouldStop=false;
	
	// /dev/videox (x=cameraId+cameraBase) is used.
	// In some omap devices, system uses /dev/video[0-3],
	// so users must use /dev/video[4-].
	// In such a case, try cameraId=0 and cameraBase=4
	private int cameraId=0;
	private int cameraBase=0;
	
	// This definition also exists in ImageProc.h.
	// Webcam must support the resolution 640x480 with YUYV format. 
	static final int IMG_WIDTH=640;
	static final int IMG_HEIGHT=480;

	// The following variables are used to draw camera images.
    private int winWidth=0;
    private int winHeight=0;
    private Rect rect;
    private int dw, dh;
    private float rate;
  
    // JNI functions
    public native int prepareCamera(int videoid);
    public native int prepareCameraWithBase(int videoid, int camerabase);
    public native void processCamera();
    public native void stopCamera();
    public native void pixeltobmp(Bitmap bitmap);
    static {
        System.loadLibrary("ImageProc");
    }
    
	CameraPreview(Context context) {
		super(context);
		this.context = context;
		if(DEBUG) Log.d("WebCam","CameraPreview constructed");
		setFocusable(true);
		
		holder = getHolder();
		holder.addCallback(this);
		holder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);	
	}
	
    @Override
    public void run() {
        while (true && cameraExists) {
        	//obtaining display area to draw a large image
        	if(winWidth==0){
        		winWidth=this.getWidth();
        		winHeight=this.getHeight();

        		if(winWidth*3/4<=winHeight){
        			dw = 0;
        			dh = (winHeight-winWidth*3/4)/2;
        			rate = ((float)winWidth)/IMG_WIDTH;
        			rect = new Rect(dw,dh,dw+winWidth-1,dh+winWidth*3/4-1);
        		}else{
        			dw = (winWidth-winHeight*4/3)/2;
        			dh = 0;
        			rate = ((float)winHeight)/IMG_HEIGHT;
        			rect = new Rect(dw,dh,dw+winHeight*4/3 -1,dh+winHeight-1);
        		}
        	}
        	
        	// obtaining a camera image (pixel data are stored in an array in JNI).
        	processCamera();
        	// camera image to bmp
        	pixeltobmp(bmp);
        	
            Canvas canvas = getHolder().lockCanvas();
            if (canvas != null)
            {
            	// draw camera bmp on canvas
            	canvas.drawBitmap(bmp,null,rect,null);

            	getHolder().unlockCanvasAndPost(canvas);
            }

            if(shouldStop){
            	shouldStop = false;  
            	break;
            }	        
        }
    }

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		if(DEBUG) Log.d("WebCam", "surfaceCreated");
		if(bmp==null){
			bmp = Bitmap.createBitmap(IMG_WIDTH, IMG_HEIGHT, Bitmap.Config.ARGB_8888);
		}
		// /dev/videox (x=cameraId + cameraBase) is used
		int ret = prepareCameraWithBase(cameraId, cameraBase);
		
		if(ret!=-1) cameraExists = true;
		
        mainLoop = new Thread(this);
        mainLoop.start();		
	}
	
	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
		if(DEBUG) Log.d("WebCam", "surfaceChanged");
	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {
		if(DEBUG) Log.d("WebCam", "surfaceDestroyed");
		if(cameraExists){
			shouldStop = true;
			while(shouldStop){
				try{ 
					Thread.sleep(100); // wait for thread stopping
				}catch(Exception e){}
			}
		}
		stopCamera();
	}   
}

@@ -584,17 +584,16 @@
 false;%0D%0A
-%09
 %0D%0A%09// /d
@@ -838,17 +838,16 @@
 ase=0;%0D%0A
-%09
 %0D%0A%09// Th
@@ -953,17 +953,16 @@
  format.
- 
 %0D%0A%09stati
@@ -1220,18 +1220,16 @@
  rate;%0D%0A
-  
 %0D%0A    //
@@ -1563,20 +1563,16 @@
 %0A    %7D%0D%0A
-    
 %0D%0A%09Camer
@@ -1723,26 +1723,24 @@
 ble(true);%0D%0A
-%09%09
 %0D%0A%09%09holder =
@@ -1787,68 +1787,12 @@
 );%0D%0A
-%09%09holder.setType(SurfaceHolder.SURFACE_TYPE_NORMAL);%09%0D%0A
 %09%7D%0D%0A
-%09
 %0D%0A  
@@ -2481,25 +2481,16 @@
     %09%7D%0D%0A
-        %09
 %0D%0A      
@@ -2652,25 +2652,16 @@
 (bmp);%0D%0A
-        %09
 %0D%0A      
@@ -2988,18 +2988,16 @@
 = false;
-  
 %0D%0A      
@@ -3028,17 +3028,8 @@
    %7D
-%09        
 %0D%0A  
@@ -3371,18 +3371,16 @@
 Base);%0D%0A
-%09%09
 %0D%0A%09%09if(r
@@ -3409,18 +3409,16 @@
  true;%0D%0A
-%09%09
 %0D%0A      
@@ -3478,17 +3478,14 @@
 t();
-%09%09
 %0D%0A%09%7D%0D%0A
-%09
 %0D%0A%09@
@@ -3828,17 +3828,16 @@
 %09%09%09%09try%7B
- 
 %0D%0A%09%09%09%09%09T
@@ -3888,16 +3888,17 @@
 g%0D%0A%09%09%09%09%7D
+ 
 catch(Ex
@@ -3941,16 +3941,13 @@
 a();%0D%0A%09%7D
-   
 %0D%0A%7D%0D%0A

Remove deprecated Android method call - not necessary to setType anymore.