package com.android.application;

import java.util.Vector;
import com.android.Algorithm.*;
//import com.android.testbtspp2_1.*;
import com.android.main.*;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.opengl.Matrix;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.FloatMath;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.Toast;
import android.widget.ViewFlipper;

public class PowerDensity extends Activity{
	private PowerDensityView pdv;
	protected void onCreate(Bundle bb) {
		super.onCreate(bb);
		pdv = new PowerDensityView(this);
		setContentView(pdv);
	}
	@Override
    public void onStop() {
         super.onStop();
         pdv.dfftthread.setStopTag(true);
         
         finish();
         System.gc();
    }
	class PowerDensityView extends View implements View.OnTouchListener, View.OnLongClickListener{
		private Paint paint;
		private int sampleRate;
		private boolean DEBUG = true;
		private final int secondForFFT = 4;//once modify here, modify in Channel.class as well.
		private String TAG = "PowerDensity";
		private float oriDistanceOfFingers;
		private int selectionForNextDisplay;
		private float oriXAxis,oriYAxis;//for one finger, swipe screen
		private String msgToDisplay = "";
		private Channel [] element;
		private DrawFFTThread dfftthread;
		private int indexForDataBuffer;
		private FastFourierTransform fft;
		//frames to display FFT result
		private int signalFrameWidth, signalFrameHeight;
		private int skullMapWidth, skullMapHeight;
		private final int picChannelWidth=50,picChannelHeight= 50;
		private final int topBottomGap=50, leftSideGap=15, rightSideGap = 20, skullSignalGap=10;
		//private int ch1MaxIndex = 0,ch2MaxIndex = 0,ch3MaxIndex = 0,ch4MaxIndex = 0;//Max index after FFT.
		private final int MIN_SLIDE_DISTANCE = 200;
		private boolean filterTag;
		private Toast popMsg;
		private int [] selectedChannelTable;
		private int nextIndexSelectedChannelTable;
		private Bitmap bitmapOrg,bitmapAfter,bitmapAlphaw,bitmapAlphag,bitmapBetaw,bitmapBetag,bitmapThetaw,bitmapThetag;
		private RectF rectForBitmap, rectForBitmapAlpha,rectForBitmapBeta,rectForBitmapTheta;
		private boolean isAlphaPressed,isBetaPressed,isThetaPressed;
		private int startTimeToDraw;//used as an index that indicates which moment to draw; 0 is default.
		private int xAxisExtend;//xAxisExtend=0(default), 1-pixel displays 1pts; xAxisExtend=1, 2-pixels display 1pts
		private final int baseLineSecond;//extract the Maximum value from 0 to baseLineSecond
		private boolean baseLineSecondTag;//baseLineSecondTag=false(default), if executionTime==baseLineSecond then baseLineSecondTag=true;
		public PowerDensityView(Context context){
			super(context);
			setTitle("FFT Domain Display");
			sampleRate = Buffer.sRate;
			paint = new Paint();
			paint.setStyle(Paint.Style.STROKE);
			paint.setStrokeWidth(1);
			setOnTouchListener(this);
			setLongClickable(false);
			setOnLongClickListener(this);
			oriDistanceOfFingers = 0;
			selectionForNextDisplay = -1;//initial, should be set by longClick
			oriXAxis = 0;
			oriYAxis = 0;
			element = new Channel[Buffer.channels];
			
			for (int i=0;i<Buffer.channels;i++){
				element[i] = new Channel(Integer.toString(i));
			}
			dfftthread = new DrawFFTThread(mHandler,"PowerDensityViewThread");
			dfftthread.start();
			indexForDataBuffer = 0;//0,1,2,...,secondForFFT-1
			fft = new FastFourierTransform();
			filterTag = false;
			popMsg = new Toast(getContext());
			selectedChannelTable = new int[6];//at least 1 channel; 0:first row, 1:second row, 2:third row, 3:fourth row
			skullMapWidth = 500;
			skullMapHeight = (520-topBottomGap);
			signalFrameWidth = 1024-leftSideGap-rightSideGap-skullMapWidth;
			signalFrameHeight = (520-topBottomGap*2)/selectedChannelTable.length; // 450/2
			nextIndexSelectedChannelTable = 0;
			
			initial();//initial the table and FFT channel
			
			bitmapOrg = BitmapFactory.decodeResource(getResources(), 
		               R.drawable.eeglayout);
			bitmapAlphaw = BitmapFactory.decodeResource(getResources(), 
		               R.drawable.alphaw);
			bitmapAlphag = BitmapFactory.decodeResource(getResources(), 
		               R.drawable.alphag);
			bitmapBetaw = BitmapFactory.decodeResource(getResources(), 
		               R.drawable.betaw);
			bitmapBetag = BitmapFactory.decodeResource(getResources(), 
		               R.drawable.betag);
			bitmapThetaw = BitmapFactory.decodeResource(getResources(), 
		               R.drawable.thetaw);
			bitmapThetag = BitmapFactory.decodeResource(getResources(), 
		               R.drawable.thetag);
			//bitmapOrg = bitmapOrg.copy(bitmapOrg.getConfig(), true);
			bitmapAfter = bitmapOrg.copy(bitmapOrg.getConfig(), true);
			rectForBitmap = new RectF(leftSideGap,topBottomGap,leftSideGap+skullMapWidth,topBottomGap+skullMapHeight);
			rectForBitmapTheta = new RectF(0,0,picChannelWidth+20,picChannelHeight+20);
			rectForBitmapAlpha = new RectF(0,picChannelHeight+20,picChannelWidth+20,picChannelHeight+20+picChannelHeight+20);
			rectForBitmapBeta = new RectF(0,(picChannelHeight+20)*2,picChannelWidth+20,(picChannelHeight+20)*2+picChannelHeight+20);
			isAlphaPressed = true;
			isBetaPressed = true;
			isThetaPressed = true;
			startTimeToDraw = 0;
			xAxisExtend = 1;
			baseLineSecond = 30;
			baseLineSecondTag = false;
		}
		private void initial2(){
			for(int i=0;i<selectedChannelTable.length;i++){
				selectedChannelTable[i]= i+1;
				element[i].isSelected = true;
			}
		}

		/*public Bitmap overlay(Bitmap bmp1, Bitmap bmp2) {         
			Bitmap bmOverlay = Bitmap.createBitmap(bmp1.getWidth(), bmp1.getHeight(), bmp1.getConfig());         
			Canvas canvas = new Canvas(bmOverlay);         
			canvas.drawBitmap(bmp1, new Matrix(), null);         
			canvas.drawBitmap(bmp2, 0, 0, null);         
			return bmOverlay;     
		}*/
		private void setData(Vector v){
			synchronized(this){
				if(DEBUG)Log.e(TAG, "In setData()");
				putDataIntoDataBuffer(v);//put data into dataBuffer, and filter
				FFT();//FFT
				element[0].indexOfSumAlpha++;
				msgToDisplay = "";
				if(element[0].indexOfSumAlpha >=(element[0].FFTResultData.length)&& element[0].indexOfSumAlpha % (element[0].FFTResultData.length)==0)//reach display limit
					this.startTimeToDraw = ((int)(element[0].indexOfSumAlpha/(element[0].FFTResultData.length)))*(element[0].FFTResultData.length)-1;
				msgToDisplay =element[0].indexOfSumAlpha+"/"+ startTimeToDraw+"/"+xAxisExtend;
				modifyScale();//modify scale
				invalidate();//paint
			}
			
		}
		private void putDataIntoDataBuffer(Vector v){
			//double [][] temp;
			//if(DEBUG)Log.e(TAG, "in putDataIntoDataBuffer()");
			//if(DEBUG)Log.e(TAG, "in putDataIntoDataBuffer()/v= "+v.size());
			if(filterTag){
				for(int channel=0;channel<Buffer.channels;channel++){
					element[channel].oneSecData = element[channel].filter.filter((double[])v.elementAt(channel));
				}
			}
			else{
				for(int channel=0;channel<Buffer.channels;channel++){
					element[channel].oneSecData = (double[])v.elementAt(channel);
				}
			}
			if(indexForDataBuffer>=secondForFFT){//no more place to fill in the data
				//move data to previous one sec.
				for(int channel=0;channel<Buffer.channels;channel++){
					for (int i = 0; i < (secondForFFT-1); i++) {
	                    for (int j = 0; j < sampleRate; j++) {
	                    	element[channel].oriData[i * sampleRate +j] = element[channel].oriData[i * sampleRate + j + sampleRate];
	                    }
	                }
				}
				//insert data to last sec.
				for(int channel=0;channel<Buffer.channels;channel++){
					System.arraycopy(element[channel].oneSecData, 0, element[channel].oriData, (indexForDataBuffer-1)*sampleRate, sampleRate);
				}
			}
			else{
				//insert data to last sec.
				for(int channel=0;channel<Buffer.channels;channel++){
					System.arraycopy(element[channel].oneSecData, 0, element[channel].oriData, indexForDataBuffer*sampleRate, sampleRate);
				}
			}
			indexForDataBuffer++;
			if(indexForDataBuffer==(secondForFFT+1))
				indexForDataBuffer = secondForFFT;
			//msgToDisplay = Integer.toString(indexForDataBuffer);
			//if(DEBUG)Log.e(TAG, "in putDataIntoDataBuffer(), DONE");
		}
		private void FFT(){
			//if(DEBUG)Log.e(TAG, "in FFT()");
			//synchronized(this){
				for(int channel=0;channel<Buffer.channels;channel++){
					if(element[channel].isSelected){
						element[channel].FFTResultData = fft.fftMag(element[channel].oriData);	
						//if(DEBUG)Log.d(TAG,"element["+channel+"].indexOfSumAlpha= "+element[channel].indexOfSumAlpha);
						//if(DEBUG)Log.e(TAG, "element["+channel+"].sumTheta["+element[channel].indexOfSumAlpha+"]= "+element[channel].sumTheta[element[channel].indexOfSumAlpha]);
						for(int i=12;i<27;i++){//theta
							//if(DEBUG)Log.e(TAG, "in FFT, FFTResultData["+i+"]= "+element[channel].FFTResultData[i]);
							element[channel].sumTheta[element[channel].indexOfSumAlpha] += element[channel].FFTResultData[i];
						}
						for(int i=28;i<48;i++){//alpha
							element[channel].sumAlpha[element[channel].indexOfSumAlpha] += element[channel].FFTResultData[i];
						}
						for(int i=49;i<50;i++){//beta
							element[channel].sumBeta[element[channel].indexOfSumAlpha] += element[channel].FFTResultData[i];
						}
						
						//element[channel].indexOfSumAlpha++;
						//if(element[channel].indexOfSumAlpha>=120)//reach 2 min
						//	element[channel].indexOfSumAlpha = 0;
					}
				}
				if(DEBUG)Log.i(TAG, "in FFT, sumTheta["+element[0].indexOfSumAlpha+"]= "+element[0].sumTheta[element[0].indexOfSumAlpha]);
				if(DEBUG)Log.i(TAG, "in FFT, sumAlpha["+element[0].indexOfSumAlpha+"]= "+element[0].sumAlpha[element[0].indexOfSumAlpha]);
				if(DEBUG)Log.i(TAG, "in FFT, sumBeta["+element[0].indexOfSumAlpha+"]= "+element[0].sumBeta[element[0].indexOfSumAlpha]);
				//}
			//if(DEBUG)Log.e(TAG, "in FFT(), DONE");
		}
		private void modifyScale(){
			//seek the maximum
			//if(DEBUG)Log.e(TAG, "in modifyScale()");
			double [][] tempMax= new double[selectedChannelTable.length][2];
			/**
			 *          0        1
			 *  0    AmaxValue  Atemp
			 *  1    BmaxValue  Btemp
			 *  .		.		  .
			 *  .		.		  .
			 *  .
			 */
	        for(int times=0;times<selectedChannelTable.length;times++){
	        	if(element[selectedChannelTable[times]-1].isSelected){
	        		//seek theta maximum
	        		if((element[selectedChannelTable[times]-1].indexOfSumAlpha-1)%baseLineSecond ==0 && (!baseLineSecondTag)){//update scale every 30 seconds
			        	for (int i = 0; i < element[selectedChannelTable[times]-1].indexOfSumAlpha; i++) {
			        		//if(DEBUG)Log.d(TAG, "element[selectedChannelTable[times]-1].sumTheta["+i+"]= "+element[selectedChannelTable[times]-1].sumTheta[i]);
				            tempMax[times][0] = Math.max(tempMax[times][0], (element[selectedChannelTable[times]-1].sumTheta[i]));
				            if (tempMax[times][0] >= tempMax[times][1]) {
				            	//ch1MaxIndex = i;
				            	tempMax[times][1] = tempMax[times][0];
				            }
				        }
			        	element[selectedChannelTable[times]-1].tempThetaMax = tempMax[times][0];			        	
			        	//if(DEBUG)Log.d(TAG, "element[selectedChannelTable[times]-1].tempThetaMax= "+element[selectedChannelTable[times]-1].tempThetaMax);
			        	//if(DEBUG)Log.d(TAG, "element[selectedChannelTable[times]-1].indexOfSumAlpha= "+element[selectedChannelTable[times]-1].indexOfSumAlpha);
	        		}
		        	//modify scale
	        		element[selectedChannelTable[times]-1].XAxis[0] = skullMapWidth+skullSignalGap;//For element[selectedChannelTable[times]-1].XAxis[0] location.
		        	for (int i = 1; i < element[selectedChannelTable[times]-1].FFTResultData.length; i++) {
		        		element[selectedChannelTable[times]-1].XAxis[i] = i+skullMapWidth+skullSignalGap+i*xAxisExtend;//the same x axis
		        		}
		        	//different y axis
	        		{
	        			element[selectedChannelTable[times]-1].sumThetaAfterScale[element[selectedChannelTable[times]-1].indexOfSumAlpha-1] = 
		        			element[selectedChannelTable[times]-1].sumTheta[element[selectedChannelTable[times]-1].indexOfSumAlpha-1]*(signalFrameHeight/element[selectedChannelTable[times]-1].tempThetaMax)*(-1)+signalFrameHeight*(times+1)+topBottomGap;
	        		}
	        		
		        	
		        	/*if(DEBUG)
			        	for(int i=0;i<element[selectedChannelTable[times]-1].indexOfSumAlpha-1;i++){
			        		Log.d(TAG, "After scale, sumTheta["+i+"]= "+element[selectedChannelTable[times]-1].sumThetaAfterScale[i]+"/"+element[selectedChannelTable[times]-1].sumTheta[i]);
			        	}*/
		        	
		        
		        	for(int i=0;i<tempMax.length;i++){
		        		tempMax[i][0] = 0;
		        		tempMax[i][1] = 0;
		        	}
	        		//seek alpha maximum
		        	if((element[selectedChannelTable[times]-1].indexOfSumAlpha-1)%baseLineSecond ==0 && (!baseLineSecondTag)){//update scale every 30 seconds
			        	for (int i = 0; i < element[selectedChannelTable[times]-1].indexOfSumAlpha; i++) {
				            tempMax[times][0] = Math.max(tempMax[times][0], (element[selectedChannelTable[times]-1].sumAlpha[i]));
				            if (tempMax[times][0] >= tempMax[times][1]) {
				            	//ch1MaxIndex = i;
				            	tempMax[times][1] = tempMax[times][0];
				            }
				        }
			        	element[selectedChannelTable[times]-1].tempAlphaMax = tempMax[times][0];
		        	}
		        	//modify scale

	        		//the same x axis
		        	//for (int i = 0; i < element[selectedChannelTable[times]-1].FFTResultData.length; i++) {
		        		//element[selectedChannelTable[times]-1].XAxis[i] = i+skullMapWidth+50;
		        	//}
	        		//different y axis
	        		{
		        		element[selectedChannelTable[times]-1].sumAlphaAfterScale[element[selectedChannelTable[times]-1].indexOfSumAlpha-1] = 
		        			element[selectedChannelTable[times]-1].sumAlpha[element[selectedChannelTable[times]-1].indexOfSumAlpha-1]*(signalFrameHeight/element[selectedChannelTable[times]-1].tempAlphaMax)*(-1)+signalFrameHeight*(times+1)+topBottomGap;
	        		}
	        		
		        	/*if(DEBUG)
			        	for(int i=0;i<element[selectedChannelTable[times]-1].indexOfSumAlpha-1;i++){
			        		Log.e(TAG, "After scale, sumAlpha["+i+"]= "+element[selectedChannelTable[times]-1].sumAlphaAfterScale[i]+"/"+element[selectedChannelTable[times]-1].sumAlpha[i]);
			        	}*/
		        	
		        	for(int i=0;i<tempMax.length;i++){
		        		tempMax[i][0] = 0;
		        		tempMax[i][1] = 0;
		        	}
		        	//seek beta maximum
		        	if((element[selectedChannelTable[times]-1].indexOfSumAlpha-1)%baseLineSecond ==0 && (!baseLineSecondTag)){//update scale every 30 second
	        			baseLineSecondTag = false;//never adjust scale anymore
			        	for (int i = 0; i < element[selectedChannelTable[times]-1].indexOfSumAlpha; i++) {
				            tempMax[times][0] = Math.max(tempMax[times][0], (element[selectedChannelTable[times]-1].sumBeta[i]));
				            if (tempMax[times][0] >= tempMax[times][1]) {
				            	//ch1MaxIndex = i;
				            	tempMax[times][1] = tempMax[times][0];
				            }
				        }
			        	element[selectedChannelTable[times]-1].tempBetaMax = tempMax[times][0];
		        	}
		        	//modify scale
		        	//the same x axis
		        	//for (int i = 0; i < element[selectedChannelTable[times]-1].FFTResultData.length; i++) {
		        		//element[selectedChannelTable[times]-1].XAxis[i] = i+skullMapWidth+50;
		        	//}

	        		//different y axis
	        		{
		        		element[selectedChannelTable[times]-1].sumBetaAfterScale[element[selectedChannelTable[times]-1].indexOfSumAlpha-1] = 
		        			element[selectedChannelTable[times]-1].sumBeta[element[selectedChannelTable[times]-1].indexOfSumAlpha-1]*(signalFrameHeight/element[selectedChannelTable[times]-1].tempBetaMax)*(-1)+signalFrameHeight*(times+1)+topBottomGap;
	        		}
		        	/*if(DEBUG)
			        	for(int i=0;i<element[selectedChannelTable[times]-1].indexOfSumAlpha-1;i++){
			        		Log.e(TAG, "After scale, sumBetaAfterScale["+i+"]= "+element[selectedChannelTable[times]-1].sumBetaAfterScale[i]+"/"+element[selectedChannelTable[times]-1].sumBeta[i]);
			        	}*/
	        	}
	        }
	        //if(DEBUG)Log.e(TAG, "in modifyScale(), done");
		}
		protected void onDraw(Canvas canvas){
			super.onDraw(canvas);
			if(DEBUG)Log.e(TAG, "in onDraw!");
			//clear old canvas
			canvas.drawColor(Color.WHITE);
			if(element[selectedChannelTable[0]-1].indexOfSumAlpha>1){
				for(int times=0;times<selectedChannelTable.length;times++){
					paint.setStrokeWidth(1);
					
					if(isThetaPressed){
						paint.setColor(Color.RED);//Theta
						for(int i=startTimeToDraw,j=0;i<element[selectedChannelTable[times]-1].indexOfSumAlpha-1;i++,j++){
							canvas.drawLine((int)element[selectedChannelTable[times]-1].XAxis[j],(int)element[selectedChannelTable[times]-1].sumThetaAfterScale[i],
									(int)element[selectedChannelTable[times]-1].XAxis[j+1],(int)element[selectedChannelTable[times]-1].sumThetaAfterScale[i+1],paint);
							//msgToDisplay = "";
							//msgToDisplay=element[selectedChannelTable[times]-1].sumTheta[0]+"/"+element[selectedChannelTable[times]-1].sumTheta[1]+"/"+element[selectedChannelTable[times]-1].sumTheta[2];
							//msgToDisplay = element[selectedChannelTable[times]-1].sumTheta[i]+"/"+signalFrameHeight+"/"+element[selectedChannelTable[times]-1].tempThetaMax;
						}
					}
					if(isAlphaPressed){
						paint.setColor(Color.GREEN);//alpha
						for(int i=startTimeToDraw,j=0;i<element[selectedChannelTable[times]-1].indexOfSumAlpha-1;i++,j++){
							canvas.drawLine((int)element[selectedChannelTable[times]-1].XAxis[j],(int)element[selectedChannelTable[times]-1].sumAlphaAfterScale[i],
									(int)element[selectedChannelTable[times]-1].XAxis[j+1],(int)element[selectedChannelTable[times]-1].sumAlphaAfterScale[i+1],paint);
							//msgToDisplay+=element[selectedChannelTable[times]-1].sumAlpha[0]+"/";
						}
					}
					if(isBetaPressed){
						paint.setColor(Color.BLUE);//beta
						for(int i=startTimeToDraw,j=0;i<element[selectedChannelTable[times]-1].indexOfSumAlpha-1;i++,j++){
							canvas.drawLine((int)element[selectedChannelTable[times]-1].XAxis[j],(int)element[selectedChannelTable[times]-1].sumBetaAfterScale[i],
									(int)element[selectedChannelTable[times]-1].XAxis[j+1],(int)element[selectedChannelTable[times]-1].sumBetaAfterScale[i+1],paint);
							//msgToDisplay+=element[selectedChannelTable[times]-1].sumAlpha[0]+"/";
						}
					}				
					paint.setStyle(Style.FILL);
					paint.setColor(Color.GRAY);
					paint.setTextSize(15);
					canvas.drawText(element[selectedChannelTable[times]-1].channelName, 
							element[selectedChannelTable[0]-1].XAxis[0]-40, signalFrameHeight*(times+1)+topBottomGap, paint);
					paint.setColor(Color.BLACK);
					paint.setStrokeWidth(2);
					//Y axis
					canvas.drawLine(element[selectedChannelTable[0]-1].XAxis[0], topBottomGap, element[selectedChannelTable[0]-1].XAxis[0], topBottomGap+signalFrameHeight*selectedChannelTable.length, paint);
					//X axis
					canvas.drawLine(element[selectedChannelTable[0]-1].XAxis[0], signalFrameHeight*(times+1)+topBottomGap, element[selectedChannelTable[0]-1].XAxis[0]+element[selectedChannelTable[0]-1].FFTResultData.length*(2), signalFrameHeight*(times+1)+topBottomGap, paint);
				}
			}
			
			//canvas.drawText(msgToDisplay, 250,300, paint);
			/*paint.setColor(Color.YELLOW);
			paint.setTextSize(15);
			//ch1 and ch2 x axis symbol
			canvas.drawText("10", element[selectedChannelTable[0]-1].XAxis[(10-1)*4], signalFrameHeight*(selectedChannelTable.length)+topBottomGap, paint);
			canvas.drawText("20", element[selectedChannelTable[0]-1].XAxis[(20-1)*4], signalFrameHeight*(selectedChannelTable.length)+topBottomGap, paint);
			canvas.drawText("30", element[selectedChannelTable[0]-1].XAxis[(30-1)*4], signalFrameHeight*(selectedChannelTable.length)+topBottomGap, paint);
			canvas.drawText("40", element[selectedChannelTable[0]-1].XAxis[(40-1)*4], signalFrameHeight*(selectedChannelTable.length)+topBottomGap, paint);
			canvas.drawText("50", element[selectedChannelTable[0]-1].XAxis[(50-1)*4], signalFrameHeight*(selectedChannelTable.length)+topBottomGap, paint);
			canvas.drawText("60", element[selectedChannelTable[0]-1].XAxis[(60-1)*4], signalFrameHeight*(selectedChannelTable.length)+topBottomGap, paint);
			canvas.drawText("Hz", element[selectedChannelTable[0]-1].XAxis[(60-1)*4]+40, signalFrameHeight*(selectedChannelTable.length)+topBottomGap, paint);*/
			canvas.drawBitmap(bitmapAfter, null, rectForBitmap, paint);
			if(isAlphaPressed)
				canvas.drawBitmap(bitmapAlphaw, null, rectForBitmapAlpha,paint);
			else
				canvas.drawBitmap(bitmapAlphag, null, rectForBitmapAlpha,paint);
			if(isBetaPressed)
				canvas.drawBitmap(bitmapBetaw, null, rectForBitmapBeta,paint);
			else
				canvas.drawBitmap(bitmapBetag, null, rectForBitmapBeta,paint);
			if(isThetaPressed)
				canvas.drawBitmap(bitmapThetaw, null, rectForBitmapTheta,paint);
			else
				canvas.drawBitmap(bitmapThetag, null, rectForBitmapTheta,paint);
			if(DEBUG){
				paint.setColor(Color.RED);
				canvas.drawText(msgToDisplay, 400, 490, paint);
			}
			//paint.setColor(Color.rgb(180, 180, 180));
			for(int channel=0;channel<Buffer.channels;channel++){
				if(element[channel].isSelected){
					//canvas.drawOval(element[channel].rectf, paint);
					canvas.drawBitmap(element[channel].picWhite,null,element[channel].rectf,paint);
				}
				else
					canvas.drawBitmap(element[channel].picGray,null,element[channel].rectf,paint);
			}
		}
		private void initial(){
			for(int i=0;i<selectedChannelTable.length;i++){
				selectedChannelTable[i] = i+1;
				element[i].isSelected = true;
			}
			for(int i=0;i<Buffer.channels;i++){
				//selectedChannelTable[i]= i+1;
				//element[i].isSelected = true;
				if(i==0){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.fpzg);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.fpzw);
					element[i].setPicXY(259-25, 119-25,259-25+picChannelWidth, 119-25+picChannelHeight);
				}
				else if(i==1){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.fzg);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.fzw);
					element[i].setPicXY(259-25, 171-25,259-25+picChannelWidth, 171-25+picChannelHeight);
				}
				else if(i==2){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.f3g);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.f3w);
					element[i].setPicXY(190-25, 209-25,190-25+picChannelWidth, 209-25+picChannelHeight);
				}
				else if(i==3){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.f4g);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.f4w);
					element[i].setPicXY(328-25,209-25,328-25+picChannelWidth, 209-25+picChannelHeight);;
				}
				else if(i==4){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.f7g);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.f7w);
					element[i].setPicXY(142-25, 182-25,142-25+picChannelWidth, 182-25+picChannelHeight);
				}
				else if(i==5){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.f8g);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.f8w);
					element[i].setPicXY(380-25, 182-25,380-25+picChannelWidth, 182-25+picChannelHeight);
				}
				else if(i==6){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.fczg);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.fczw);
					element[i].setPicXY(259-25, 231-25,259-25+picChannelWidth, 231-25+picChannelHeight);
				}
				else if(i==7){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.czg);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.czw);
					element[i].setPicXY(259-25, 290-25,259-25+picChannelWidth, 290-25+picChannelHeight);
				}
				else if(i==8){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.c3g);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.c3w);
					element[i].setPicXY(190-25, 290-25,190-25+picChannelWidth, 290-25+picChannelHeight);
				}
				else if(i==9){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.c4g);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.c4w);
					element[i].setPicXY(328-25, 290-25,328-25+picChannelWidth, 290-25+picChannelHeight);
				}
				else if(i==10){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.pzg);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.pzw);
					element[i].setPicXY(259-25, 361-25,259-25+picChannelWidth, 361-25+picChannelHeight);
				}
				else if(i==11){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.p3g);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.p3w);
					element[i].setPicXY(190-25, 361-25,190-25+picChannelWidth, 361-25+picChannelHeight);
				}
				else if(i==12){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.p4g);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.p4w);
					element[i].setPicXY(328-25, 361-25,328-25+picChannelWidth, 361-25+picChannelHeight);
				}
				else if(i==13){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.t5g);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.t5w);
					element[i].setPicXY(149-25, 405-25,149-25+picChannelWidth, 405-25+picChannelHeight);
				}
				else if(i==14){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.t6g);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.t6w);
					element[i].setPicXY(380-25, 405-25,380-25+picChannelWidth, 405-25+picChannelHeight);
				}
				else if(i==15){
					element[i].picGray = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.ozg);
					element[i].picWhite = BitmapFactory.decodeResource(getResources(), 
				               R.drawable.ozw);
					element[i].setPicXY(259-25, 455-25,259-25+picChannelWidth, 455-25+picChannelHeight);
				}
			}
		}
		private final Handler mHandler = new Handler() {
	        public void handleMessage(Message msg) {
	            switch (msg.what) {
	            case 0://repaint            	
	            	invalidate();
	           	 break;
	            case 1://fill in data
	            	//msgToDisplay = Integer.toString((Integer)msg.obj);
	            	//invalidate();
	            	setData((Vector)msg.obj);
	            	//if(DEBUG)Log.e(TAG, "in Handler!");
	           	 break;
	            case 2:
	           	 break;
	            }
	        }
	    };
		public boolean onTouch(View v, MotionEvent e) {
			handleTwoFingers(e);
			handleOneFingerSwipe(e);
			return false;//if return true, the onLongClick can't work.
		}
		
		private void handleOneFingerSwipe(MotionEvent event){
			
			int action = event.getAction();
			int actionCode = action & MotionEvent.ACTION_MASK;
			if(actionCode == MotionEvent.ACTION_DOWN && event.getPointerCount()==1){
				oriXAxis = event.getX();
				oriYAxis = event.getY();
				if(DEBUG)Log.e(TAG, "oriXAxis= "+oriXAxis+"\n");
				//msgToDisplay = "";
				//msgToDisplay = oriXAxis+"/"+oriYAxis;
				handleSelectedChannel(oriXAxis, oriYAxis);				
			}
			if(actionCode == MotionEvent.ACTION_MOVE &&event.getPointerCount()==1){
				if(event.getX()>oriXAxis && (event.getX()-oriXAxis >MIN_SLIDE_DISTANCE)){//swipe to right, to FFT
					finish();
					startActivity(new Intent(PowerDensity.this, FrequencyDomainActivity.class));	
					if(DEBUG)Log.e(TAG, "SWIPE TO RIGHT! /oriXAxis= "+oriXAxis+" / "+event.getX()+"\n");
				}
				else if(event.getX()<oriXAxis && (oriXAxis-event.getX() >MIN_SLIDE_DISTANCE)){//swipe to left.
					//finish();
					//startActivity(new Intent(PowerDensity.this, CCADomainActivity.class));		
					if(DEBUG)Log.e(TAG, "SWIPE TO LEFT! /oriXAxis= "+oriXAxis+" / "+event.getX()+"\n");
				}
				//swipe up, turn the Filter
				else if(event.getY()<oriYAxis &&(oriYAxis-event.getY()>MIN_SLIDE_DISTANCE)){
					filterTag = true;
					popMsg.makeText( this.getContext(), R.string.Enable_Band_Pass_Filter,popMsg.LENGTH_SHORT).show();
				}
				//swipe down, turn off the filter
				else if(event.getY()>oriYAxis &&(event.getY()-oriYAxis>MIN_SLIDE_DISTANCE)){
					filterTag = false;
					popMsg.makeText( this.getContext(), R.string.Disable_Band_Pass_Filter,popMsg.LENGTH_SHORT).show();
				}
			}
		}
		private void handleTwoFingers(MotionEvent event) {
			float newDistanceOfFingers;
			int action = event.getAction();
			int actionCode = action & MotionEvent.ACTION_MASK;
			//if(DEBUG)Log.e(TAG, "**********In handleTwoFingers()");
			if(actionCode == MotionEvent.ACTION_POINTER_DOWN && event.getPointerCount()==2){
				oriDistanceOfFingers = FloatMath.sqrt((event.getX(0)-event.getX(1)) * (event.getX(0)-event.getX(1)) + 
						(event.getY(0)-event.getY(1)) * (event.getY(0)-event.getY(1)));
				//if(DEBUG)Log.e(TAG,"**********ori= "+oriDistanceOfFingers);
			}
			if(actionCode == MotionEvent.ACTION_MOVE &&event.getPointerCount()==2){
				newDistanceOfFingers = FloatMath.sqrt((event.getX(0)-event.getX(1)) * (event.getX(0)-event.getX(1)) + 
						(event.getY(0)-event.getY(1)) * (event.getY(0)-event.getY(1)));
				Log.e(TAG,"**********new= "+newDistanceOfFingers);
				if(newDistanceOfFingers < oriDistanceOfFingers ){
					if(xAxisExtend>0&& newDistanceOfFingers>MIN_SLIDE_DISTANCE){
						//xAxisExtend--;
						//msgToDisplay = "Zoom Out";	
						//if(DEBUG)Log.e(TAG,"CCCCCCCCCc");
					}
					//popMsg.makeText( this.getContext(), R.string.ZoomOut_text,popMsg.LENGTH_SHORT).show();
					
				}
				if(newDistanceOfFingers > oriDistanceOfFingers ){
					if(xAxisExtend<1 && newDistanceOfFingers>MIN_SLIDE_DISTANCE){
						//xAxisExtend++;
						//msgToDisplay = "Zoom In";
						//if(DEBUG)Log.e(TAG,"DDDDDDDDDD");
					}
					//popMsg.makeText(getContext(), R.string.ZoomIn_text,popMsg.LENGTH_SHORT).show();
					
				}
			}
		}
		private void handleSelectedChannel(float x, float y){
			synchronized(this){
				//extract which channel was selected
				int selectedChannel = -1;// = ((int) (x%Buffer.channels))+1;
				for(int i=0;i<Buffer.channels;i++){
					if(element[i].rectf.left<x && element[i].rectf.right>x && element[i].rectf.top<y && element[i].rectf.bottom>y){
						//msgToDisplay +="##"+element[0].rectf.left+"/"+element[0].rectf.right+"/"+element[0].rectf.top+"/"+element[0].rectf.bottom;
						selectedChannel = i+1;
						break;
					}
				}
				if(x<(picChannelWidth+20) && y>0 && y<(picChannelHeight+20))//theta Pressed,
					isThetaPressed = !isThetaPressed;
				if(x<(picChannelWidth+20) && y>(picChannelHeight+20) && y<(picChannelHeight+20)*2)//alpha Pressed,
					isAlphaPressed = !isAlphaPressed;
				if(x<(picChannelWidth+20) && y>(picChannelHeight+20)*2 && y<(picChannelHeight+20)*3)//beta Pressed,
					isBetaPressed = !isBetaPressed;
				/*if(DEBUG){
					Log.e(TAG, "///////////ORI////////////");
					for(int i=0;i<4;i++){
						Log.e(TAG, "selectedChannelTable["+i+"]= "+selectedChannelTable[i]);
					}
					for(int i=0;i<Buffer.channels;i++){
						if(element[i].isSelected)
							Log.e(TAG, "selected channel= "+(i+1));
					}
					Log.e(TAG, "///////////ORI////////////////");
				}*/
				if(selectedChannel!=-1){
					if(!element[selectedChannel-1].isSelected){
						nextIndexSelectedChannelTable++;
						
						if(DEBUG)Log.e(TAG, "selectedChannel= "+selectedChannel+", nextIndexSelectedChannelTable= "+nextIndexSelectedChannelTable);
						
						//update color on skull map
						
						//update the selected channel table and element[].isSelected
						if(nextIndexSelectedChannelTable>selectedChannelTable.length){
							element[selectedChannelTable[0]-1].isSelected = false;
							element[selectedChannel-1].isSelected = true;
							nextIndexSelectedChannelTable=1;
							selectedChannelTable[nextIndexSelectedChannelTable-1] = selectedChannel;
						}
						else{
							if(selectedChannelTable[nextIndexSelectedChannelTable-1]>0)
								if(element[selectedChannelTable[nextIndexSelectedChannelTable-1]-1].isSelected)
									element[selectedChannelTable[nextIndexSelectedChannelTable-1]-1].isSelected = false;
							selectedChannelTable[nextIndexSelectedChannelTable-1] = selectedChannel;
							element[selectedChannel-1].isSelected = true;
						}
					}
					//refreshScreen();//refresh the signal screen
					/*if(DEBUG){
						Log.e(TAG, "///////////AFTER////////////////");
						for(int i=0;i<4;i++){
							Log.e(TAG, "selectedChannelTable["+i+"]= "+selectedChannelTable[i]);
						}
						for(int i=0;i<Buffer.channels;i++){
							if(element[i].isSelected)
								Log.e(TAG, "selected channel= "+(i+1));
						}
						Log.e(TAG, "///////////AFTER////////////////");
					}*/
				}
			}
		}
		private void refreshScreen(){
			for(int channel=0;channel<Buffer.channels;channel++){
				element[channel].indexOfSumAlpha = 0;
				element[channel].tempAlphaMax = 0;
				element[channel].tempBetaMax = 0;
				element[channel].tempThetaMax = 0;
			}
		}
		public boolean onLongClick(View v) {
			/*//msgToDisplay = "11111111111";
			new AlertDialog.Builder(this.getContext())
	        //.setIcon(R.drawable.alert_dialog_icon)
	        .setTitle(R.string.app_name)
	        .setSingleChoiceItems(R.array.select_dialog_items2, 0, new DialogInterface.OnClickListener() {
	            public void onClick(DialogInterface dialog, int whichButton) {
	            	switch(whichButton){
	            	case 0:
	            		selectionForNextDisplay = 0;//button 1 pressed, Time mode display
	            		break;
	            	case 1:
	            		selectionForNextDisplay = 1;//button 2 pressed, Frequency mode display
	            		break;
	            	case 2:
	            		selectionForNextDisplay = 2;//button 3 pressed, CCA display
	            		break;
	            	case 3:
	            		selectionForNextDisplay = 3;//button 4 pressed, Debug mode
	            		break;
	            	}
	            }
	        })
	        .setPositiveButton(R.string.timeDomainDialog_button_ok, new DialogInterface.OnClickListener() {
	            public void onClick(DialogInterface dialog, int whichButton) {
	            	if(selectionForNextDisplay !=-1){
	            		msgToDisplay = "selectionForNextDisplay"+"/pressed";
	            	}
	            	selectionForNextDisplay =-1;//in case user didn't press any of mode to display, and press OK/CANCEL only.
	            }
	        })
	        .setNegativeButton(R.string.timeDomainDialog_button_cancel, new DialogInterface.OnClickListener() {
	            public void onClick(DialogInterface dialog, int whichButton) {
	            	msgToDisplay += "3/";	
	                // User clicked No so do some stuff 
	            }
	        })
	       .show();
			if(DEBUG)Log.e(TAG, "onLongClick!\n");*/
			return true;
		}
	}
}
