/*
 * Copyright 2009 Cedric Priscal
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License. 
 */

package com.tcl.factory.serial;

import java.io.File;
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidParameterException;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.Bundle;
import com.tcl.factory.serial.SerialPort;
import com.tcl.factory.utils.Debug;

public abstract class SerialPortApplication {

	protected SerialPort mSerialPort;
	FileDescriptor mFd;
	private ReadThread mReadThread;
	public SerialPortFinder mSerialPortFinder = new SerialPortFinder();
	
	private boolean isSendRecvData = false;
	
	private int cmd_max_size = 4096;
	private byte[] rev_data = new byte[cmd_max_size];
	private byte[] buffer = new byte[cmd_max_size];
	private int rev_size = 0;
	private long start_time = 0;
	private SendDataThread mSendDataThread = null;

	

	public SerialPort getSerialPort() throws SecurityException, IOException, InvalidParameterException {
		if (mSerialPort == null) {
			/* Read serial port parameters */
//			SharedPreferences sp = getSharedPreferences("android_serialport_api.sample_preferences", MODE_PRIVATE);
			String path = "/dev/ttyS1";//sp.getString("DEVICE", "");
			int baudrate = 115200;//Integer.decode(sp.getString("BAUDRATE", "-1"));

			/* Check parameters */
			if ( (path.length() == 0) || (baudrate == -1)) {
				throw new InvalidParameterException();
			}

			/* Open the serial port */
			mSerialPort = new SerialPort(new File(path), baudrate, 0);
		}
		return mSerialPort;
	}

	public void closeSerialPort() {
		if (mSerialPort != null) {
			mSerialPort.close();
			mSerialPort = null;
		}
	}
	
	private class ReadThread extends Thread {

		@Override
		public void run() {
			super.run();
			while(!isInterrupted()) {
				int size;
				if (mSerialPort == null) return;
				size = mSerialPort.read(buffer,buffer.length);
				if (size > 0) {
					for(int i=0;i<size;i++)
					{
						rev_data[rev_size++] = buffer[i];
					}
					if(!isSendRecvData)
					{
						isSendRecvData = true;
						mSendDataThread.run();
					}else{
						start_time = System.nanoTime();
					}
				}
			}
		}
	}
	
	private class SendDataThread extends Thread {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			super.run();
			boolean waitTimer = true;
			start_time = System.nanoTime();  
			long now_time = 0;
			while(waitTimer)
			{
//				try {
//					Thread.sleep(1);
//					} catch (InterruptedException e) {
//					// TODO Auto-generated catch block
//					e.printStackTrace();
//				}
				now_time = System.nanoTime();
				if((now_time - start_time)>2000000)//2ms
				{
					waitTimer = false;
					isSendRecvData = false;

					onDataReceived(rev_data,rev_size);
					rev_size = 0;
				}
			}
		}
	}
	
	

	private void DisplayError(int resourceId) {
/*		AlertDialog.Builder b = new AlertDialog.Builder(this);
		b.setTitle("Error");
		b.setMessage(resourceId);
		b.setPositiveButton("OK", new OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				SerialPortApplication.this.finish();
			}
		});
		b.show();*/
	}

	void OpenUartSerial() {
		try {
			mFd = getSerialPort().getFileDescriptor();
			/* Create a receiving thread */
			mReadThread = new ReadThread();
			mReadThread.start();
			
			mSendDataThread = new SendDataThread();
		} catch (SecurityException e) {
			//DisplayError(R.string.error_security);
		} catch (IOException e) {
			//DisplayError(R.string.error_unknown);
		} catch (InvalidParameterException e) {
			//DisplayError(R.string.error_configuration);
		}
	}


	
	void CloseUARTSerial() {
		if (mReadThread != null)
			mReadThread.interrupt();
		closeSerialPort();
	}
	
	
	protected abstract void onDataReceived(final byte[] buffer, final int size);
	
}
