/*
 * Copyright (C) 2008,2009  OMRON SOFTWARE Co., Ltd.
 *
 * 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.hiroshica.android.input.nicownn2;

import android.inputmethodservice.InputMethodService;
import android.view.WindowManager;
import android.content.Context;
import android.view.View;
import android.view.KeyEvent;
import android.content.SharedPreferences;
import android.preference.PreferenceManager;

import android.util.Log;
import android.os.*;
import android.view.inputmethod.*;
import android.content.res.Configuration;
import android.graphics.*;
import android.graphics.drawable.*;
import android.view.MotionEvent;
import android.content.Intent;
import android.content.pm.PackageManager;

import java.lang.Object;
import java.util.List;

/**
 * The OpenWnn IME's base class.
 *
 * @author Copyright (C) 2009 OMRON SOFTWARE CO., LTD.  All Rights Reserved.
 */
public class NicoWnn extends InputMethodService {
	//private static final String GETACTION_INTERCEPT = "com.hiroshica.android.input.nicownn2.ACTION_INTERCEPT";
	//private static final String INPUTCONNECTION_KEY = "inputconnection_key";
	private static final String ACTION_INTERCEPT = "com.adamrocker.android.simeji.ACTION_INTERCEPT";
	private static final String CATEGORY_KEY = "com.adamrocker.android.simeji.REPLACE";
	private static final String REPLACE_KEY = "replace_key";
	private static final String INPUTCONNECTION_KEY = "inputconnection_key";


	// dic.setup
	public static final String writableJAJPBaseName = new String("writableJAJP.dic");
	public static final String writableENBaseName   = new String("writableEN.dic");

	public static final String writableJAJPDic = new String("/data/data/com.hiroshica.android.input.nicownn2/writableJAJP.dic");
	public static final String writableENDic   = new String("/data/data/com.hiroshica.android.input.nicownn2/writableEN.dic");

	public static final String INPUTMODE_NICO   = new String("input_nico");
	public static final String INPUTMODE_BELL   = new String("input_bell");
	public static final String INPUTMODE_NORMAL = new String("input_normal");
	public static final String INPUTMODE_NICO2  = new String("input_nico2");
	public static final String INPUTMODE_TEST   = new String("input_test");
	
	/** Candidate view */
	protected CandidatesViewManager  mCandidatesViewManager = null;
	/** Input view (software keyboard) */
	protected InputViewManager  mInputViewManager = null;
	protected String            mInputViewMode    = "input_nico";
	
	/** Conversion engine */
	protected WnnEngine  mConverter = null;
	/** Pre-converter (for Romaji-to-Kana input, Hangul input, etc.) */
	protected LetterConverter  mPreConverter = null;
	/** The inputing/editing string */
	protected ComposingText  mComposingText = null;
	/** The input connection */
	public InputConnection mInputConnection = null;
	/** Auto hide candidate view */
	protected boolean mAutoHideMode = true;
	/** Direct input mode */
	protected boolean mDirectInputMode = true;
     
	/** Flag for checking if the previous down key event is consumed by OpenWnn  */
	private boolean mConsumeDownEvent;

	/**
	 * Constructor
	 */
	public NicoWnn() {
		super();
	}

	/***********************************************************************
	 * InputMethodService 
	 **********************************************************************/
	/** @see android.inputmethodservice.InputMethodService#onCreate */
	@Override public void onCreate() {
		super.onCreate();

		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);


		if (mConverter != null) { mConverter.init(); }
		if (mComposingText != null) { mComposingText.clear(); }
	}

	/** @see android.inputmethodservice.InputMethodService#onCreateCandidatesView */
	@Override public View onCreateCandidatesView() {
		if (mCandidatesViewManager != null) {
			WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
			View view = mCandidatesViewManager.initView(this,
								    wm.getDefaultDisplay().getWidth(),
								    wm.getDefaultDisplay().getHeight());
			mCandidatesViewManager.setViewType(CandidatesViewManager.VIEW_TYPE_NORMAL);
			return view;
		} else {
			return super.onCreateCandidatesView();
		}
	}

	/** @see android.inputmethodservice.InputMethodService#onCreateInputView */
	@Override public View onCreateInputView() {

		if (mInputViewManager != null) {
			WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
			return mInputViewManager.initView(this,
							  wm.getDefaultDisplay().getWidth(),
							  wm.getDefaultDisplay().getHeight());
		} else {
			return super.onCreateInputView();
		}
	}

	/** @see android.inputmethodservice.InputMethodService#onDestroy */
	@Override public void onDestroy() {
		super.onDestroy();

		close();
	}

	/** @see android.inputmethodservice.InputMethodService#onKeyDown */
	@Override public boolean onKeyDown(int keyCode, KeyEvent event) {
		mConsumeDownEvent = onEvent(new NicoWnnEvent(event));
		if (!mConsumeDownEvent) {
			return super.onKeyDown(keyCode, event);
		}
		return mConsumeDownEvent;
	}

	/** @see android.inputmethodservice.InputMethodService#onKeyUp */
	@Override public boolean onKeyUp(int keyCode, KeyEvent event) {
		boolean ret = mConsumeDownEvent;
		if (!ret) {
			ret = super.onKeyUp(keyCode, event);
		}else{
			onEvent(new NicoWnnEvent(event));
		}
		return ret;
	}
        
	/** @see android.inputmethodservice.InputMethodService#onStartInput */
	@Override public void onStartInput(EditorInfo attribute, boolean restarting) {
		super.onStartInput(attribute, restarting);
		mInputConnection = getCurrentInputConnection();
		if (mComposingText != null) {
			mComposingText.clear();
		}
	}

	/** @see android.inputmethodservice.InputMethodService#onStartInputView */
	@Override public void onStartInputView(EditorInfo attribute, boolean restarting) {
		super.onStartInputView(attribute, restarting);
		mInputConnection = getCurrentInputConnection();

		setCandidatesViewShown(false);
		if (mInputConnection != null) {
			mDirectInputMode = false;
			if (mConverter != null) { mConverter.init(); }
		} else {
			mDirectInputMode = true;
		}
		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
		if (mCandidatesViewManager != null) { mCandidatesViewManager.setPreferences(pref);  }
		if (mInputViewManager != null) { mInputViewManager.setPreferences(pref, attribute);  }
		if (mPreConverter != null) { mPreConverter.setPreferences(pref);  }
		if (mConverter != null) { mConverter.setPreferences(pref);  }
	}

	/** @see android.inputmethodservice.InputMethodService#requestHideSelf */
	@Override public void requestHideSelf(int flag) {
		super.requestHideSelf(flag);
		if (mInputViewManager == null) {
			hideWindow();
		}
	}

	/** @see android.inputmethodservice.InputMethodService#setCandidatesViewShown */
	@Override public void setCandidatesViewShown(boolean shown) {
		super.setCandidatesViewShown(shown);
		if (shown) {
			showWindow(true);
		} else {
			if (mAutoHideMode && mInputViewManager == null) {
				hideWindow();
			}
		}
	}

	/** @see android.inputmethodservice.InputMethodService#hideWindow */
	@Override public void hideWindow() {
		super.hideWindow();
		mDirectInputMode = true;
		hideStatusIcon();
	}
	/** @see android.inputmethodservice.InputMethodService#onComputeInsets */
	@Override public void onComputeInsets(InputMethodService.Insets outInsets) {
		super.onComputeInsets(outInsets);
		outInsets.contentTopInsets = outInsets.visibleTopInsets;
	}


	/**********************************************************************
	 * OpenWnn
	 **********************************************************************/
	/**
	 * Process an event.
	 *
	 * @param  ev  An event
	 * @return  {@code true} if the event is processed in this method; {@code false} if not.
	 */
	public boolean onEvent(NicoWnnEvent ev) {
		return false;
	}

	/**
	 * Search a character for toggle input.
	 *
	 * @param prevChar     The character input previous
	 * @param toggleTable  Toggle table
	 * @param reverse      {@code false} if toggle direction is forward, {@code true} if toggle direction is backward
	 * @return          A character ({@code null} if no character is found)
	 */
	protected String searchToggleCharacter(String prevChar, String[] toggleTable, boolean reverse) {
		for (int i = 0; i < toggleTable.length; i++) {
			if (prevChar.equals(toggleTable[i])) {
				if (reverse) {
					i--;
					if (i < 0) {
						return toggleTable[toggleTable.length - 1];
					} else {
						return toggleTable[i];
					}
				} else {
					i++;
					if (i == toggleTable.length) {
						return toggleTable[0];
					} else {
						return toggleTable[i];
					}
				}
			}
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	public void mashUp() {
/*
		Intent intent = new Intent(ACTION_INTERCEPT);
		//intent.addCategory(CATEGORY_KEY);
		intent.putExtra(REPLACE_KEY, new String("test"));
 		List info = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
 		if (info.size() != 0) {
			startActivity(intent);
 		}
 */
		//Intent intent = new Intent(ACTION_INTERCEPT);
		//intent.setClass(this, NicoWnnMushUp.class);
		//intent.putExtra(REPLACE_KEY, new String("test"));
		//intent.putExtra(INPUTCONNECTION_KEY, mInputConnection);		
		
		Intent intent = new Intent().setClass(this, NicoWnnMushUp.class);

		startActivity(intent);
		
		hideWindow();
	}

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        //super.onActivityResult(requestCode, resultCode, data);
		if (0 == resultCode) {
			//mGetString = data.getStringExtra("replace_key");
		}
    }
// 	public float getX() {
// 		WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
// 		return wm.getX();
// 	}

// 	public float getY() {
// 		WindowManager wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
// 		return wm.getY();
// 	}

	/**
	 * Processing of resource open when IME ends.
	 */
	protected void close() {
		if (mConverter != null) { mConverter.close(); }
	}
}
