package com.android.main;

import java.util.Date;
import java.util.Vector;
import java.util.Random;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import android.graphics.Color;
import android.os.Environment;
import android.util.Log;

public class Buffer {
  public static final int sRate = 128;
  private static int dataIndex = 0;
  private static int sRateTag = 0;
  public static final int channels = 16;
  private static String TAG = "Buffer";
  private static boolean DEBUG = true;
  private static String rawDataPath;
  private static File rawDataFile;
  private static String fileTime;//Example: RawData Tue 15 2011 13:21:23.txt
  private static OutputStream rawDataOut;
  private static Date todayDate;
  //private Random r;
  private static int tempLatestDataIndex = 0;
  private static Channel[] element;
  public Buffer(){
	  element = new Channel[channels];
	  for(int i=0;i<channels;i++){
		  element[i] = new Channel(this);
	  }
	  rawDataPath = Environment.getExternalStorageDirectory().toString();
	  todayDate = new Date();
	  fileTime = todayDate.toGMTString();
	  char[]a = fileTime.toCharArray();
	  for(int i=0;i<a.length;i++){
		  if(a[i]==':')
			  a[i] = '_';
	  }
	  fileTime = String.copyValueOf(a);
	  /*rawDataFile = new File(rawDataPath,"RawData_"+fileTime+".txt");
	  if(DEBUG)Log.e(TAG,fileTime);
		try{
			if(rawDataFile.createNewFile())			
				rawDataOut = new FileOutputStream(rawDataFile);
			else
				if(DEBUG)Log.e(TAG, "rawDataOut stream can't be created");
		}catch (Exception e){
			if(DEBUG)Log.e(TAG, e.toString());
		}*/
  }
  public void saveRawDataToFile(){
	  System.gc();
	  double[][] temp = new double[sRate][channels];
	  double[] temp2;
	  try{
		  for(int times = 0;times<element[0].list.size();times++){//for length of dataList
			  for(int i=0;i<10;i++){//for each dataList
				  temp2 = (double[])element[i].list.elementAt(times);
				  for(int j=0;j<sRate;j++){//for each element
					  temp[j][i] = temp2[j];
				  }
			  }
			  for(int k=0;k<temp.length;k++){
				  for(int m=0;m<temp[k].length;m++){
					  rawDataOut.write(Double.toString(temp[k][m]).getBytes());
					  rawDataOut.write(" ".getBytes());
				  }
			  	  rawDataOut.write("\r\n".getBytes());
			  }
		  }
		  rawDataOut.flush();
		  rawDataOut.close();
		  Log.e(TAG, "Data has been saved!");
	  }
	  catch(Exception e){
		  if(DEBUG)Log.e(TAG, e.toString());
	  }
  }
  public static synchronized int getDataIndex(){
	    return dataIndex;
  }
  private static void increaseDataCount(){//synchronized? this one is called from synchronized one, which is setData()...
	  dataIndex +=1;
	  // mainEEG.displayCavas.numberToDial += Integer.toString( dataIndex)+",";
	  // append(Integer.toString( dataIndex));
  }
	
  public synchronized static void setData(double a,double b,double c,double d,
		  double e,double f,double g,double h,
		  double i,double j,double k,double l,
		  double m,double n,double o,double p){
      try{
          element[0].oneSecData[sRateTag] = a;
          element[1].oneSecData[sRateTag] = b;
          element[2].oneSecData[sRateTag] = c;
          element[3].oneSecData[sRateTag] = d;
          element[4].oneSecData[sRateTag] = e;
          element[5].oneSecData[sRateTag] = f;
          element[6].oneSecData[sRateTag] = g;
          element[7].oneSecData[sRateTag] = h;
          element[8].oneSecData[sRateTag] = i;
          element[9].oneSecData[sRateTag] = j;
          element[10].oneSecData[sRateTag] = k;
          element[11].oneSecData[sRateTag] = l;
          element[12].oneSecData[sRateTag] = m;
          element[13].oneSecData[sRateTag] = n;
          element[14].oneSecData[sRateTag] = o;
          element[15].oneSecData[sRateTag] = p;
          //mainEEG.displayCavas.setArray(a,b,c,d);
          //dlt.setData(a, b, c, d);
          if (++sRateTag == sRate) {
              //mainEEG.displayCavas.repaint();
              sRateTag = 0;
              // mainEEG.dc.setStringA("Before increase:"+Long.toString(java.lang.Runtime.getRuntime().freeMemory()));
              double[][] array = new double[channels][sRate];
              for(int index=0;index<channels;index++){
            	  System.arraycopy(element[index].oneSecData, 0, array[index], 0, sRate);
            	  element[index].list.addElement(array[index]);
              }
              //write3array(element[3].oneSecData, element[4].oneSecData, element[5].oneSecData, 1);
              increaseDataCount();
              if(DEBUG)Log.e(TAG, "SetData 128pst, OK");	
          }
      }
      catch(Exception exp){}
  }
  
  public static synchronized Vector getData4(){//format: ch1->ch2->ch3->ch4, from last node
    Vector tempvector = new Vector(16);
    Vector tvector = new Vector(1);
    //int index =  getDataIndex()-1;
    if (element[0].list.size()>=1) {
    	for(int i=0;i<channels;i++){
    		tempvector.add(element[i].list.lastElement());
    	}
        if(DEBUG)Log.e(TAG, "in getData4(), OK");	
        //if(DEBUG)writeData(dataIndex, "GET1");
        return tempvector;
    }
    else{
    	if(DEBUG)Log.e(TAG, "in getData4(), size<1");	
    	//if(DEBUG)writeData(dataIndex, "GET2");
        return tvector;
    }
  }
  /**
   * for debug only
   */
  public synchronized static void writeData(double[] data){
	  try{
		  for(int i=0;i<data.length;i++){
			  rawDataOut.write(Double.toString(data[i]).getBytes());
			  rawDataOut.write("\r\n".getBytes());
			  rawDataOut.flush();
		  }
	  }catch(Exception e){
		  
	  }
  }
  public synchronized static void write3array(double[]a, double[]b, double[]c, int index){
	  try{
		  for(int i=0;i<a.length;i++){
			  rawDataOut.write(Double.toString(a[i]).getBytes());
			  rawDataOut.write("  ".getBytes());
			  rawDataOut.write(Double.toString(b[i]).getBytes());
			  rawDataOut.write("  ".getBytes());
			  rawDataOut.write(Double.toString(c[i]).getBytes());
			  rawDataOut.write("  ".getBytes());
			  rawDataOut.write(Integer.toString(index).getBytes());
			  rawDataOut.write("\r\n".getBytes());
			  rawDataOut.flush();
		  }
	  }catch(Exception e){
		  
	  }
  }
  public synchronized static void writeData(int number, String tag){
	  try{
		  rawDataOut.write(Integer.toString(number).getBytes());
		  rawDataOut.write("  ".getBytes());
		  rawDataOut.write(tag.getBytes());
		  rawDataOut.write("\r\n".getBytes());
		  rawDataOut.flush();
	  }catch(Exception e){
		  
	  }
  }
  public synchronized static void closeStream(){
	  try{
		  rawDataOut.flush();
		  rawDataOut.close();
	  }catch(Exception e){
		  
	  }
  }
}
  /* public synchronized Vector getData3(){//format: ch1->ch2->ch3->ch4
    Vector tempvector = new Vector(4);
    Vector tvector = new Vector(1);
    int index = getDataIndex()-1;
    if (index >= 1) {
        tempvector.addElement(data1List.elementAt(index));
        tempvector.addElement(data2List.elementAt(index));
        tempvector.addElement(data3List.elementAt(index));
        tempvector.addElement(data4List.elementAt(index));
        return tempvector;
    }
    else
        return tvector;
  }

  public Vector getData(){//format: ch1->ch2->ch3->ch4
    Vector tempvector = new Vector();
    int index = getDataIndex()-1;
    if(index <= tempLatestDataIndex){
        return new Vector(1);
    }
    else{
        tempLatestDataIndex = index;
        if (index >= 1) {
            tempvector.addElement(data1List.elementAt(index));
            tempvector.addElement(data2List.elementAt(index));
            tempvector.addElement(data3List.elementAt(index));
            tempvector.addElement(data4List.elementAt(index));
        } else {
            tempvector.addElement(ch1);
            tempvector.addElement(ch2);
            tempvector.addElement(ch3);
            tempvector.addElement(ch4);
        }
        return tempvector;
    }
  }
  public synchronized Vector getData(int seconds){
      Vector OKvector = new Vector(4);//if data is enough to get
      Vector FalseVector = new Vector(1);//if data is not enough to get
      if(seconds < (getDataIndex())){
          OKvector.addElement(data1List.elementAt(seconds));
          OKvector.addElement(data2List.elementAt(seconds));
          OKvector.addElement(data3List.elementAt(seconds));
          OKvector.addElement(data4List.elementAt(seconds));
          return OKvector;
      }
      else
          return FalseVector;
  }
 public Vector getData2(int pointsToFFT){//format: ch1->ch2->ch3->ch4-> ch1->ch2->ch3->ch4...
  int dataNeeded = 0;
  Vector tempvector = new Vector();
  int index = getDataIndex()-1;
  // .mainEEG.displayCavas.numberToDial2 += Integer.toString( dataIndex)+",";
  if(pointsToFFT >= sRate){
      if( pointsToFFT % sRate == 0){
          dataNeeded = pointsToFFT / sRate;
          if( dataNeeded <= index){
              for(int i=dataNeeded; i>0; i--,index--){
                  tempvector.insertElementAt(data1List.elementAt(index),0);
                  tempvector.insertElementAt(data2List.elementAt(index),0);
                  tempvector.insertElementAt(data3List.elementAt(index),0);
                  tempvector.insertElementAt(data4List.elementAt(index),0);
              }
          }
          else
              ;
              //System.out.println("# of points to FFT is not enough");//suck...
      }
      else
          ;
          //System.out.println("# of points to FFT is not fit Sample Rate");// suck....
  }
  else{
      //need to down sample
  }
  return tempvector;
}
public Vector getVector(int channel) {
if (channel == 1)
    return data1List;
else if (channel == 2)
    return data2List;
else if (channel == 3)
    return data3List;
else if (channel ==4)
    return data4List;
if (channel == 5)
    return data5List;
else if (channel == 6)
    return data6List;
else if (channel == 7)
    return data7List;
if (channel == 8)
    return data8List;
else if (channel == 9)
    return data9List;
else if (channel == 10)
    return data10List;
if (channel == 11)
    return data11List;
else if (channel == 12)
    return data12List;
else if (channel == 13)
    return data13List;
else if (channel == 14)
    return data14List;
else if (channel == 15)
    return data15List;
else//(channel == 16)
    return data16List;
}
public synchronized void removeRawData(int from, int to){
//mainEEG.dc.setStringC("Before remove: "+System.getProperty("com.nokia.memoryramfree"));
for(int i=from;i<to;i++){
 data1List.removeElementAt(0);
 data2List.removeElementAt(0);
 data3List.removeElementAt(0);
 data4List.removeElementAt(0);
 data5List.removeElementAt(0);
 data6List.removeElementAt(0);
 data7List.removeElementAt(0);
 data8List.removeElementAt(0);
 data9List.removeElementAt(0);
 data10List.removeElementAt(0);
 data11List.removeElementAt(0);
 data12List.removeElementAt(0);
 data13List.removeElementAt(0);
 data14List.removeElementAt(0);
 data15List.removeElementAt(0);
 data16List.removeElementAt(0);
}
dataIndex -=to;
System.gc();
//mainEEG.dc.setStringD("After remove: "+System.getProperty("com.nokia.memoryramfree"));
//mainEEG.dc.repaint();
}*/






//******************************************************************************************************
/*package com.android.testbtspp2_1;

import java.util.Vector;
import java.util.Random;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

import android.graphics.Color;
import android.os.Environment;
import android.util.Log;

public class Buffer {
  public static final int sRate = 128;
  private static int dataIndex = 0;
  private static int sRateTag = 0;
  public static final int channels = 16;
  private String TAG = "Buffer";
  private boolean DEBUG = true;
  private String rawDataPath;
  private File rawDataFile;
  private OutputStream rawDataOut;
  private static Vector data1List = new Vector();
  private static Vector data2List = new Vector();
  private static Vector data3List = new Vector();
  private static Vector data4List = new Vector();
  private static Vector data5List = new Vector();
  private static Vector data6List = new Vector();
  private static Vector data7List = new Vector();
  private static Vector data8List = new Vector();
  private static Vector data9List = new Vector();
  private static Vector data10List = new Vector();
  private static Vector data11List = new Vector();
  private static Vector data12List = new Vector();
  private static Vector data13List = new Vector();
  private static Vector data14List = new Vector();
  private static Vector data15List = new Vector();
  private static Vector data16List = new Vector();
  //private Random r;
  private static double ch1[] = new double[sRate];
  private static double ch2[] = new double[sRate];
  private static double ch3[] = new double[sRate];
  private static double ch4[] = new double[sRate];
  private static double ch5[] = new double[sRate];
  private static double ch6[] = new double[sRate];
  private static double ch7[] = new double[sRate];
  private static double ch8[] = new double[sRate];
  private static double ch9[] = new double[sRate];
  private static double ch10[] = new double[sRate];
  private static double ch11[] = new double[sRate];
  private static double ch12[] = new double[sRate];
  private static double ch13[] = new double[sRate];
  private static double ch14[] = new double[sRate];
  private static double ch15[] = new double[sRate];
  private static double ch16[] = new double[sRate];
  private static int tempLatestDataIndex = 0;
  public Buffer(){
	  rawDataPath = Environment.getExternalStorageDirectory().toString();
	  rawDataFile = new File(rawDataPath,"RawData.txt");
		try{
			if(rawDataFile.createNewFile())			
				rawDataOut = new FileOutputStream(rawDataFile);
		}catch (Exception e){	
		}
		  
  }
  public void saveRawDataToFile(){
	  try{
		  for(int i=0;i<data1List.size();i++){//for each dataList
			  for(int j=0;j<sRate;j++){//for each element
				  //rawDataOut.write(Double.toString((double[])data1List.elementAt(i)).getBytes());
			  }
			  
		  }
	  }catch(Exception e){
		  
	  }
  }
  public Vector getVector(int channel) {
      if (channel == 1)
          return data1List;
      else if (channel == 2)
          return data2List;
      else if (channel == 3)
          return data3List;
      else if (channel ==4)
          return data4List;
      if (channel == 5)
          return data5List;
      else if (channel == 6)
          return data6List;
      else if (channel == 7)
          return data7List;
      if (channel == 8)
          return data8List;
      else if (channel == 9)
          return data9List;
      else if (channel == 10)
          return data10List;
      if (channel == 11)
          return data11List;
      else if (channel == 12)
          return data12List;
      else if (channel == 13)
          return data13List;
      else if (channel == 14)
          return data14List;
      else if (channel == 15)
          return data15List;
      else//(channel == 16)
          return data16List;
  }
  public synchronized void removeRawData(int from, int to){
      //mainEEG.dc.setStringC("Before remove: "+System.getProperty("com.nokia.memoryramfree"));
      for(int i=from;i<to;i++){
       data1List.removeElementAt(0);
       data2List.removeElementAt(0);
       data3List.removeElementAt(0);
       data4List.removeElementAt(0);
       data5List.removeElementAt(0);
       data6List.removeElementAt(0);
       data7List.removeElementAt(0);
       data8List.removeElementAt(0);
       data9List.removeElementAt(0);
       data10List.removeElementAt(0);
       data11List.removeElementAt(0);
       data12List.removeElementAt(0);
       data13List.removeElementAt(0);
       data14List.removeElementAt(0);
       data15List.removeElementAt(0);
       data16List.removeElementAt(0);
      }
      dataIndex -=to;
      System.gc();
      //mainEEG.dc.setStringD("After remove: "+System.getProperty("com.nokia.memoryramfree"));
      //mainEEG.dc.repaint();
  }
  public synchronized void setData(double a,double b,double c,double d,
		  double e,double f,double g,double h,
		  double i,double j,double k,double l,
		  double m,double n,double o,double p){
      try{
          ch1[sRateTag] = a;
          ch2[sRateTag] = b;
          ch3[sRateTag] = c;
          ch4[sRateTag] = d;
          ch5[sRateTag] = e;
          ch6[sRateTag] = f;
          ch7[sRateTag] = g;
          ch8[sRateTag] = h;
          ch9[sRateTag] = i;
          ch10[sRateTag] = j;
          ch11[sRateTag] = k;
          ch12[sRateTag] = l;
          ch13[sRateTag] = m;
          ch14[sRateTag] = n;
          ch15[sRateTag] = o;
          ch16[sRateTag] = p;
          //mainEEG.displayCavas.setArray(a,b,c,d);
          //dlt.setData(a, b, c, d);
          if (++sRateTag == sRate) {
              //mainEEG.displayCavas.repaint();
              sRateTag = 0;
              // mainEEG.dc.setStringA("Before increase:"+Long.toString(java.lang.Runtime.getRuntime().freeMemory()));
              double[] aa = new double[sRate];
              double[] bb = new double[sRate];
              double[] cc = new double[sRate];
              double[] dd = new double[sRate];
              double[] ee = new double[sRate];
              double[] ff = new double[sRate];
              double[] gg = new double[sRate];
              double[] hh = new double[sRate];
              double[] ii = new double[sRate];
              double[] jj = new double[sRate];
              double[] kk = new double[sRate];
              double[] ll = new double[sRate];
              double[] mm = new double[sRate];
              double[] nn = new double[sRate];
              double[] oo = new double[sRate];
              double[] pp = new double[sRate];

              System.arraycopy(ch1, 0, aa, 0, sRate);
              System.arraycopy(ch2, 0, bb, 0, sRate);
              System.arraycopy(ch3, 0, cc, 0, sRate);
              System.arraycopy(ch4, 0, dd, 0, sRate);
              System.arraycopy(ch5, 0, ee, 0, sRate);
              System.arraycopy(ch6, 0, ff, 0, sRate);
              System.arraycopy(ch7, 0, gg, 0, sRate);
              System.arraycopy(ch8, 0, hh, 0, sRate);
              System.arraycopy(ch9, 0, ii, 0, sRate);
              System.arraycopy(ch10, 0, jj, 0, sRate);
              System.arraycopy(ch11, 0, kk, 0, sRate);
              System.arraycopy(ch12, 0, ll, 0, sRate);
              System.arraycopy(ch13, 0, mm, 0, sRate);
              System.arraycopy(ch14, 0, nn, 0, sRate);
              System.arraycopy(ch15, 0, oo, 0, sRate);
              System.arraycopy(ch16, 0, pp, 0, sRate);
              data1List.addElement(aa);
              data2List.addElement(bb);
              data3List.addElement(cc);
              data4List.addElement(dd);
              data5List.addElement(ee);
              data6List.addElement(ff);
              data7List.addElement(gg);
              data8List.addElement(hh);
              data9List.addElement(ii);
              data10List.addElement(jj);
              data11List.addElement(kk);
              data12List.addElement(ll);
              data13List.addElement(mm);
              data14List.addElement(nn);
              data15List.addElement(oo);
              data16List.addElement(pp);
              increaseDataCount();
          }
      }
      catch(Exception exp){}
  }
  public Vector getData2(int pointsToFFT){//format: ch1->ch2->ch3->ch4-> ch1->ch2->ch3->ch4...
      int dataNeeded = 0;
      Vector tempvector = new Vector();
      int index = getDataIndex()-1;
      // .mainEEG.displayCavas.numberToDial2 += Integer.toString( dataIndex)+",";
      if(pointsToFFT >= sRate){
          if( pointsToFFT % sRate == 0){
              dataNeeded = pointsToFFT / sRate;
              if( dataNeeded <= index){
                  for(int i=dataNeeded; i>0; i--,index--){
                      tempvector.insertElementAt(data1List.elementAt(index),0);
                      tempvector.insertElementAt(data2List.elementAt(index),0);
                      tempvector.insertElementAt(data3List.elementAt(index),0);
                      tempvector.insertElementAt(data4List.elementAt(index),0);
                  }
              }
              else
                  ;
                  //System.out.println("# of points to FFT is not enough");//suck...
          }
          else
              ;
              //System.out.println("# of points to FFT is not fit Sample Rate");// suck....
      }
      else{
          //need to down sample
      }
      return tempvector;
  }
  public synchronized Vector getData4(){//format: ch1->ch2->ch3->ch4, from last node
    Vector tempvector = new Vector(16);
    Vector tvector = new Vector(1);
    //int index =  getDataIndex()-1;
    if (data1List.size()>=1) {
        tempvector.addElement(data1List.lastElement());
        tempvector.addElement(data2List.lastElement());
        tempvector.addElement(data3List.lastElement());
        tempvector.addElement(data4List.lastElement());
        tempvector.addElement(data5List.lastElement());
        tempvector.addElement(data6List.lastElement());
        tempvector.addElement(data7List.lastElement());
        tempvector.addElement(data8List.lastElement());
        tempvector.addElement(data9List.lastElement());
        tempvector.addElement(data10List.lastElement());
        tempvector.addElement(data11List.lastElement());
        tempvector.addElement(data12List.lastElement());
        tempvector.addElement(data13List.lastElement());
        tempvector.addElement(data14List.lastElement());
        tempvector.addElement(data15List.lastElement());
        tempvector.addElement(data16List.lastElement());
        if(DEBUG)Log.e(TAG, "in getData4(), size>=1");	
        return tempvector;
    }
    else{
    	if(DEBUG)Log.e(TAG, "in getData4(), size<1");	
        return tvector;
    }
  }

  public synchronized Vector getData3(){//format: ch1->ch2->ch3->ch4
    Vector tempvector = new Vector(4);
    Vector tvector = new Vector(1);
    int index = getDataIndex()-1;
    if (index >= 1) {
        tempvector.addElement(data1List.elementAt(index));
        tempvector.addElement(data2List.elementAt(index));
        tempvector.addElement(data3List.elementAt(index));
        tempvector.addElement(data4List.elementAt(index));
        return tempvector;
    }
    else
        return tvector;
  }

  public Vector getData(){//format: ch1->ch2->ch3->ch4
    Vector tempvector = new Vector();
    int index = getDataIndex()-1;
    if(index <= tempLatestDataIndex){
        return new Vector(1);
    }
    else{
        tempLatestDataIndex = index;
        if (index >= 1) {
            tempvector.addElement(data1List.elementAt(index));
            tempvector.addElement(data2List.elementAt(index));
            tempvector.addElement(data3List.elementAt(index));
            tempvector.addElement(data4List.elementAt(index));
        } else {
            tempvector.addElement(ch1);
            tempvector.addElement(ch2);
            tempvector.addElement(ch3);
            tempvector.addElement(ch4);
        }
        return tempvector;
    }
  }
  public synchronized Vector getData(int seconds){
      Vector OKvector = new Vector(4);//if data is enough to get
      Vector FalseVector = new Vector(1);//if data is not enough to get
      if(seconds < (getDataIndex())){
          OKvector.addElement(data1List.elementAt(seconds));
          OKvector.addElement(data2List.elementAt(seconds));
          OKvector.addElement(data3List.elementAt(seconds));
          OKvector.addElement(data4List.elementAt(seconds));
          return OKvector;
      }
      else
          return FalseVector;
  }
  protected synchronized int getDataIndex(){
    return dataIndex;
  }
  private void increaseDataCount(){//synchronized? this one is called from synchronized one, which is setData()...
    dataIndex +=1;
    // mainEEG.displayCavas.numberToDial += Integer.toString( dataIndex)+",";
    // append(Integer.toString( dataIndex));
  }
}*/
