package com.penpower.apparch.keyboard.handwrite;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.os.StatFs;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;

import com.penpower.ime.hwr.JNISDK_HWR_Client;
import com.penpower.stdhwrexample.R;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.lang.reflect.Array;

public class PP_HW_Demo extends Activity {
	public static final int MSG_INIT_COPYFILE = 22;
	public static final int MSG_HIDE_PGORRESSDLG = 19;
	public static final int MSG_STORAGE_INSUFFICEINT = 24;

    /** Called when the activity is first created. */
	ScrollView mScrollView=null;
	LinearLayout mLinearlayout = null;
	HandWritingView mHWview = null;
	private static final String INKING_FILENAME = "penpower.ink";
	private static final short CANDIDATE_END_FLAG = 0xffffffff;
	static final String TAG = "Standard_PP_HW_Demo";
	static final String LOGTAG = TAG;
	private static final int ROW_MAX_ITEM = 4;
	private int miRowItemIndex = 0;
	protected ProgressDialog mProgressdialog = null;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        if(mProgressdialog == null)
        {
            mProgressdialog = new ProgressDialog(this);
            mProgressdialog.setCancelable(true);
            mProgressdialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        }
        //Make sure no connection activated.
		JNISDK_HWR_Client.PPHWRDisconnect();
        int iStatus = 0;        
        // 檢查database版本是否一致
        SharedPreferences settings = getSharedPreferences(Define.PREF, 0);

        String strPref_Version = settings.getString(Define.PREF_VERSION, "");
        String getStrVersion = Define.CORE_DATABASE_VERSION;
//        if("".equals(strPref_Version) || getStrVersion.equals(strPref_Version) == false)
        {
        	DeleteFiles();
            mHandler.sendEmptyMessage(MSG_INIT_COPYFILE);
        } 

    	mScrollView = (ScrollView) findViewById(R.id.ScrollView01);
        mHWview = (HandWritingView) findViewById(R.id.TouchView);
        mHWview.setManActivity(this);
        mLinearlayout = new LinearLayout(this);
        mLinearlayout.setOrientation( LinearLayout.VERTICAL );
        mLinearlayout.setBackgroundColor( 0xff000000 );    
       
        clearCandidateList();
        mScrollView.addView(mLinearlayout);
        
    }

    Handler mHandler = new Handler()
    {
        public void handleMessage(Message msg)
        {
            switch (msg.what)
            {
                case MSG_INIT_COPYFILE:
                    if (mProgressdialog != null && mProgressdialog.isShowing() == false)
                    {
                        mProgressdialog.setMessage(getResources().getString(R.string.init_progress_text));
                        mProgressdialog.show();
                    }
                    CopyFileThread copyFileThread = new CopyFileThread();
                    copyFileThread.start();
                    break;
                case MSG_HIDE_PGORRESSDLG:
                    if (mProgressdialog != null && mProgressdialog.isShowing())
                        mProgressdialog.hide();

                    Init();
                    break;
                case MSG_STORAGE_INSUFFICEINT:
                    if (mProgressdialog != null && mProgressdialog.isShowing())
                        mProgressdialog.hide();
                    Builder MyAlertDialog = new AlertDialog.Builder(PP_HW_Demo.this);
                    MyAlertDialog.setTitle(getResources().getString(R.string.copy_storage_insufficient));
                    MyAlertDialog.setPositiveButton(getResources().getString(R.string.ok), OkClick);
                    MyAlertDialog.show();
                    MyAlertDialog = null;
                    break;
            }
        }
    };

    DialogInterface.OnClickListener OkClick = new DialogInterface.OnClickListener()
    {
        public void onClick(DialogInterface dialog, int which)
        {
            finish();
        }
    };

    public int Init()
    {
    	String getDatabasePath = getApplicationInfo().dataDir;
        String MyPath = getDatabasePath+"/ppengbk.bin";
        String NulPath = "";
        
        int iStatus = JNISDK_HWR_Client.PPHWRConnect(
				                 MyPath.getBytes(), // 手寫數據庫路徑
                				false, NulPath.getBytes(), // 不使用人工智慧, 資料庫的路徑為空
                				false, NulPath.getBytes(), // 不使用多字人工智慧, 資料庫路徑為空
                				false, NulPath.getBytes(), // 不使用額外辭典, 辭典路徑為空
				 				false, NulPath.getBytes()  // 不使用學習字串數據庫, 資料庫路徑為空
		);

        Log.d(TAG,"HWRConnect returns status code = "+iStatus);
        if (iStatus>=0){
	        iStatus = JNISDK_HWR_Client.PPHWRSetType(JNISDK_HWR_Client.ALL_TYPE);
//			iStatus = JNISDK_HWR_Client.PPHWRSetType(JNISDK_HWR_Client.ALPHA_TYPE|JNISDK_HWR_Client.SYMBOL_TYPE);
	        WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
	    	int width = wm.getDefaultDisplay().getWidth();
	    	int height = wm.getDefaultDisplay().getHeight()/2;
	
	    	if(width < (height/2))
				JNISDK_HWR_Client.PPHWRSetBox(0, 0, width, width);
	    	else
				JNISDK_HWR_Client.PPHWRSetBox(0, 0, (height/2), (height/2));
        }
        else
        	return iStatus;
    	return iStatus;
    }
    
    public void DeleteFiles()
    {
        String[] allnames = new String[] {
                "ppengbk.bin" };
        String filename = getApplicationInfo().dataDir + "/";
        for(String name : allnames)
        {
            new File(filename + name).delete();
        }
    }

    private void clearCandidateList()
    {
    	mLinearlayout.removeAllViews();
    	
    	for(int j = 0 ;j< 4;j++)
   	 	{
    		LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        	LinearLayout llayout = (LinearLayout) inflater.inflate(R.layout.candidate_row, null);
        	mLinearlayout.addView(llayout);       		 
   	 	}
        mLinearlayout.requestLayout();
    }
    @Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// TODO Auto-generated method stub
    	 MenuInflater inflater = getMenuInflater();
    	 inflater.inflate(R.menu.menu, menu);
    	    return true;
	}

	@Override
	public boolean onMenuItemSelected(int featureId, MenuItem item) {
		// TODO Auto-generated method stub
		Log.d(LOGTAG,"Menu Selected");
		if(item.getItemId() == R.id.menu_clear)
		{
			Log.d(LOGTAG,"clear command issued");
			mHWview.InputStrokeClear();
			clearCandidateList();
			
		}
		else if(item.getItemId() == R.id.menu_save)
		{
			Log.d(LOGTAG,"save command issued");
			saveInkingData();
		}
		return super.onMenuItemSelected(featureId, item);
	}
	private void saveInkingData()
	{
	}

	private boolean checkInkingDataExist()
	{
		String [] filelist = fileList ();
		for(int i = 0; i< Array.getLength(filelist);i++)
		{
			if(filelist[i].equals(INKING_FILENAME))
			{
				return true;
			}
		}
		return false;
		
	}
	// Read settings 
	public String ReadSettings(Context context)
	{ 
		FileInputStream fIn = null; 
		InputStreamReader isr = null; 
	
		char[] inputBuffer = new char[255]; 
		String data = null; 
	
		try
		{ 
			fIn = openFileInput(INKING_FILENAME); 
			isr = new InputStreamReader(fIn); 
			isr.read(inputBuffer); 
			data = new String(inputBuffer); 
			Toast.makeText(context, "Settings read",Toast.LENGTH_SHORT).show(); 
		} 
		catch (Exception e) 
		{ 
			e.printStackTrace(); 
			Toast.makeText(context, "Settings not read",Toast.LENGTH_SHORT).show(); 
		} 
		finally 
		{ 
			try 
			{ 
				isr.close(); 
				fIn.close(); 
			} catch (IOException e) 
			{ 
				e.printStackTrace(); 
			} 
		}
		 
		return data; 
	}
	// Save settings 
	public void WriteSettings(Context context, String data)
	{ 
		FileOutputStream fOut = null; 
		OutputStreamWriter osw = null;
		
		boolean bFileExist = false;
		int iFileMode = MODE_PRIVATE;
		String [] filelist = fileList ();
		for(int i = 0; i< Array.getLength(filelist);i++)
		{
			if(filelist[i].equals(INKING_FILENAME))
			{
				bFileExist = true;
				break;
			}
		}
		
		if(bFileExist == true)
			iFileMode = MODE_APPEND;
		try
		{ 			
			fOut = openFileOutput(INKING_FILENAME,iFileMode);
			osw = new OutputStreamWriter(fOut); 
			osw.write(data); 
			osw.flush();
		} 
		catch (Exception e) 
		{ 
			e.printStackTrace(); 
			Toast.makeText(context, "Inking not saved",Toast.LENGTH_SHORT).show(); 
		} 
		finally 
		{ 
			try
			{ 
				fOut.close();	 
			} catch (IOException e) 
			{ 
				e.printStackTrace(); 
			} 
		} 
	}
	public void WriteSettings(Context context, byte[] data)
	{ 
		FileOutputStream fOut = null; 
		OutputStreamWriter osw = null;
		
		boolean bFileExist = false;
		int iFileMode = MODE_PRIVATE;
		String [] filelist = fileList ();
		for(int i = 0; i< Array.getLength(filelist);i++)
		{
			if(filelist[i].equals(INKING_FILENAME))
			{
				bFileExist = true;
				break;
			}
		}
		
		if(bFileExist == true)
			iFileMode = MODE_APPEND;
		try
		{ 			
			fOut = openFileOutput(INKING_FILENAME,iFileMode);
			fOut.write(data);
		} 
		catch (Exception e) 
		{ 
			e.printStackTrace(); 
			Toast.makeText(context, "Inking not saved",Toast.LENGTH_SHORT).show(); 
		} 
		finally 
		{ 
			try
			{ 
				//osw.close(); 
				fOut.close();	 
			} catch (IOException e) 
			{ 
				e.printStackTrace(); 
			} 
		} 
	}
	public void WriteSettings(Context context, int data)
	{ 
		FileOutputStream fOut = null; 
		OutputStreamWriter osw = null;
		
		boolean bFileExist = false;
		int iFileMode = MODE_PRIVATE;
		String [] filelist = fileList ();
		for(int i = 0; i< Array.getLength(filelist);i++)
		{
			if(filelist[i].equals(INKING_FILENAME))
			{
				bFileExist = true;
				break;
			}
		}
		
		if(bFileExist == true)
			iFileMode = MODE_APPEND;
		try
		{ 			
			fOut = openFileOutput(INKING_FILENAME,iFileMode);
			fOut.write(data);
			int highbyte = data >> 8;
			fOut.write(highbyte);
		} 
		catch (Exception e) 
		{ 
			e.printStackTrace(); 
			Toast.makeText(context, "Inking not saved",Toast.LENGTH_SHORT).show(); 
		} 
		finally 
		{ 
			try
			{ 
				fOut.close();	 
			} catch (IOException e) 
			{ 
				e.printStackTrace(); 
			} 
		} 
	}
	public void WriteSettings(Context context, short data)
	{ 
		FileOutputStream fOut = null; 
		OutputStreamWriter osw = null;
		
		boolean bFileExist = false;
		int iFileMode = MODE_PRIVATE;
		String [] filelist = fileList ();
		for(int i = 0; i< Array.getLength(filelist);i++)
		{
			if(filelist[i].equals(INKING_FILENAME))
			{
				bFileExist = true;
				break;
			}
		}
		
		if(bFileExist == true)
			iFileMode = MODE_APPEND;
		try
		{ 			
			fOut = openFileOutput(INKING_FILENAME,iFileMode);
			fOut.write(data);
			short highbyte = (short) (data >> 8);
			fOut.write(highbyte);
						 
		} 
		catch (Exception e) 
		{ 
			e.printStackTrace(); 
			Toast.makeText(context, "Inking not saved",Toast.LENGTH_SHORT).show(); 
		} 
		finally 
		{ 
			try
			{ 
				//osw.close(); 
				fOut.close();	 
			} catch (IOException e) 
			{ 
				e.printStackTrace(); 
			} 
		} 
	}
	public void setCandidateList(char[] Result)
    {
    	int j = 0;
    	int k = 0;
    	int m = 0;
    	int count = 1;
    	int total = 0;    	
    	short Wordnum =0;
    	String strCandidate="";
    	mLinearlayout.removeAllViews();
    	
    	int i;
        //單字書寫的時候使用
    	for(i = 0; i < Array.getLength(Result); i++)
    	{
    		strCandidate += Result[i];
    		addCandidateListItem(strCandidate,Color.BLUE);
    		strCandidate="";
    	}

    	mLinearlayout.requestLayout();
    }

	public void setCandidateList32(int[] Result)
    {
    	int j = 0;
    	int k = 0;
    	int m = 0;
    	int count = 1;
    	int total = 0;    	
    	short Wordnum =0;
    	String strCandidate="";
    	mLinearlayout.removeAllViews();
    
    	int i;
        //單字書寫的時候使用
    	short[] pResult= new short[(1+1)*2];
    	int [] pResult32 = new int[1];
    	int button_count = Array.getLength(Result);
    	if(button_count >= 16)
    	  button_count = 16;
    	for(i = 0; i < button_count; i++)
    	{
    		pResult32[0] = Result[i];
    		if(Result[i]!= 0) {
				JNISDK_HWR_Client.PPHWRUTF32_2_Surrogate(pResult32, pResult, 1);
    		  if( (pResult[0]>=0xDC00) && (pResult[0] < 0xE000) ) {
      		    strCandidate+=String.valueOf((char)pResult[1]);
      		    strCandidate+=String.valueOf((char)pResult[0]);
      		    Log.d(LOGTAG, i+" convert pResult32[0] : "+pResult32[0]+" converted to "+pResult[1]+pResult[0]);
    		  }
    		  else {
    		    strCandidate+=Character.toString((char)pResult[0]);
      		    Log.d(LOGTAG, i + " convert pResult32[0] : "+pResult32[0]+" converted to "+pResult[0]);
    		  }
    		}
    		else{
    			break;
    		}
    		addCandidateListItem(strCandidate,Color.BLUE);
    		strCandidate="";
    	}
    	for (;i<button_count;i++){
    		strCandidate="";
    		addCandidateListItem(strCandidate,Color.BLUE);
    	}

    	mLinearlayout.requestLayout();
    }

	private void addCandidateListItem(String str,int color)
    {
    
    	if(mLinearlayout.getChildCount() == 0 || (mLinearlayout.getChildCount()  > 0 && miRowItemIndex >= ROW_MAX_ITEM))
    	{
    		LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
    		LinearLayout llayout = (LinearLayout) inflater.inflate(R.layout.candidate_row, null);
        	mLinearlayout.addView(llayout);    
        	miRowItemIndex= 0;
    	}
    	if(miRowItemIndex < ROW_MAX_ITEM)
    	{
    		LinearLayout ll = (LinearLayout) mLinearlayout.getChildAt(mLinearlayout.getChildCount()-1);
    		Button btn = (Button) ll.getChildAt(miRowItemIndex++);
        	btn.setText(str);   
        	btn.setTextColor(color);
    	}
    	Log.d(LOGTAG,"addCandidateListItem");
    }
	@Override
	protected void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.d(LOGTAG,"onDestroy");
		JNISDK_HWR_Client.PPHWRDisconnect();
	}
	
    public int FileManagment(Boolean IsWrite)
    {
        int nFileSize = 0;
        nFileSize += Copyto(this, R.raw.ppengbk1, R.raw.ppengbk2, R.raw.ppengbk3, R.raw.ppengbk4, R.raw.ppengbk5, R.raw.ppengbk6, R.raw.ppengbk7, -1,"ppengbk.bin", IsWrite);
        return nFileSize;
    }
    
	class CopyFileThread extends Thread
    {
        @Override
        public void run()
        {
            super.run();

            int nFileNeedSize = FileManagment(false);

            File data = Environment.getDataDirectory();
            StatFs sf = new StatFs(data.getPath());
            int availableBlocks = sf.getAvailableBlocks();
            int size = sf.getBlockSize();
            int availableSize = 0;
            if (size >= 1024)
            {
                availableSize = availableBlocks / 1024 * (size / 1024);//遇到記憶體爆掉問題
                nFileNeedSize = (nFileNeedSize / 1024 / 1024) + 1;
            }
            else
            {
                availableSize = availableBlocks / 1024 * size;
                nFileNeedSize = (nFileNeedSize / 1024);
            }

            if (availableSize < nFileNeedSize)
            {
                mHandler.sendEmptyMessage(MSG_STORAGE_INSUFFICEINT);
            }
            else
            {
                FileManagment(true);
                //確認檔案複製成功之後再寫入設定檔
                restorePrefs();
                mHandler.sendEmptyMessage(MSG_HIDE_PGORRESSDLG);
            }
        }
    }

    public void restorePrefs()
    {
        SharedPreferences settings = getSharedPreferences(Define.PREF, 0);
        settings.edit().putString(Define.PREF_VERSION, Define.CORE_DATABASE_VERSION).commit();
    }
    
	public static int Copyto(Context context, int rawResId1, int rawResId2, int rawResId3, int rawResId4, int rawResId5, int rawResId6, int rawResId7, int rawResId8, String name,boolean IsWrite)
	{
		final int BUFFER_SIZE  = 65535;
		int nInputStreamSize=0;
		String filename = context.getApplicationInfo().dataDir + "/" + name;

		File file_new = null;
		OutputStream out = null;
		byte[] buf = null;
		if(IsWrite)
		{
			file_new = new File(filename);
			buf = new byte[BUFFER_SIZE];
		}

		if(IsWrite == false || file_new.exists() == false)
		{
			try
			{
				if(IsWrite)
				{
					out = new FileOutputStream(file_new);
				}

				InputStream in = context.getResources().openRawResource(rawResId1);
				int len = 0;
				if(rawResId1 != -1 )
				{
					if(IsWrite == false)
					{
						nInputStreamSize += in.available();
					}
					else
					{
						while((len = in.read(buf)) > 0)
						{
							out.write(buf, 0, len);
						}
						for(byte b:buf)
						{
							b = 0;
						}
					}
					in.close();
				}
				if(rawResId2 != -1)
				{
					in = context.getResources().openRawResource(rawResId2);
					len = 0;
					if(IsWrite == false)
					{
						nInputStreamSize += in.available();
					}
					else
					{
						while((len = in.read(buf)) > 0)
						{
							out.write(buf, 0, len);
						}
						for(byte b:buf)
						{
							b= 0;
						}
					}
					in.close();
				}
				if(rawResId3 != -1)
				{
					in = context.getResources().openRawResource(rawResId3);
					len = 0;

					if(IsWrite == false)
					{
						nInputStreamSize += in.available();
					}
					else
					{
						while((len = in.read(buf)) > 0)
						{
							out.write(buf, 0, len);
						}
						for(byte b:buf)
						{
							b = 0;
						}
					}
					in.close();
				}
				if(rawResId4 != -1)
				{
					in = context.getResources().openRawResource(rawResId4);
					len = 0;
					if(IsWrite == false)
					{
						nInputStreamSize += in.available();
					}
					else
					{
						while((len = in.read(buf)) > 0)
						{
							out.write(buf, 0, len);
						}
						for(byte b:buf)
						{
							b= 0;
						}
					}
					in.close();
				}
				if(rawResId5 != -1)
				{
					in = context.getResources().openRawResource(rawResId5);
					len = 0;
					if(IsWrite == false)
					{
						nInputStreamSize += in.available();
					}
					else
					{
						while((len = in.read(buf)) > 0)
						{
							out.write(buf, 0, len);
						}
						for(byte b:buf)
						{
							b = 0;
						}
 					}
					in.close();
				}
				if(rawResId6 != -1)
				{
					in = context.getResources().openRawResource(rawResId6);
					len = 0;
					if(IsWrite == false)
					{
						nInputStreamSize += in.available();
					}
					else
					{
						while((len = in.read(buf)) > 0)
						{
							out.write(buf, 0, len);
						}
						for(byte b:buf)
						{
							b = 0;
						}
 					}
					in.close();
				}
				if(rawResId7 != -1)
				{
					in = context.getResources().openRawResource(rawResId7);
					len = 0;
					if(IsWrite == false)
					{
						nInputStreamSize += in.available();
					}
					else
					{
						while((len = in.read(buf)) > 0)
						{
							out.write(buf, 0, len);
						}
						for(byte b:buf)
						{
							b = 0;
						}
 					}
					in.close();
				}
				if(rawResId8 != -1)
				{
					in = context.getResources().openRawResource(rawResId8);
					len = 0;
					if(IsWrite == false)
					{
						nInputStreamSize += in.available();
					}
					else
					{
						while((len = in.read(buf)) > 0)
						{
							out.write(buf, 0, len);
						}
						for(byte b:buf)
						{
							b = 0;
						}
 					}
					in.close();
				}
				if(IsWrite)
				{
 					out.close();
				}
 			}
 			catch(Exception e)
 			{
 				e.printStackTrace();
 			}
 		}
		buf = null;
		file_new = null;
		return nInputStreamSize;
	}
}
