/*
 * Copyright (C) 2008-2012  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.
 */

/*
 * Copyright (C) 2008-2009 Google Inc.
 * 
 * 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 jp.co.omronsoft.openwnn.JAJP;

import jp.co.omronsoft.openwnn.*;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
import android.os.Handler;
import android.os.Message;
import android.text.Layout;
import android.text.SpannableStringBuilder;
import android.text.StaticLayout;
import android.text.Spanned;
import android.text.style.ImageSpan;
import android.text.style.DynamicDrawableSpan;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.PopupWindow;
import android.widget.TextView;

import java.util.ArrayList;
import java.util.List;

public class TutorialJAJP implements OnTouchListener {
    
    private List<Bubble> mBubbles = new ArrayList<Bubble>();
    private static final int LONG_PRESS_INDEX = 8;
    private View mInputView;
    private OpenWnnJAJP mIme;
    private int[] mLocation = new int[2];
    private static final int MSG_SHOW_BUBBLE = 0;
    
    private int mBubbleIndex;
    private DefaultSoftKeyboardJAJP mInputManager;
    private boolean mEnableKeyTouch = false;
    
    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_SHOW_BUBBLE:
                    Bubble bubba = (Bubble) msg.obj;
                    bubba.show(mLocation[0], mLocation[1]);
                    break;
            }
        }
    };

    class Bubble {
        Drawable bubbleBackground;
        int x;
        int y;
        int width;
        int gravity;
        CharSequence text;
        boolean dismissOnTouch;
        boolean dismissOnClose;
        PopupWindow window;
        TextView textView;
        View inputView;

        Bubble(Context context, View inputView,
                int backgroundResource, int bx, int by, int description, int guide) {

            CharSequence text = context.getResources().getText(description);
            init(context, inputView, backgroundResource, bx, by, text, guide, false);
        }

        Bubble(Context context, View inputView, int backgroundResource, int bx, int by,
               CharSequence description, int guide, boolean leftAlign) {
            init(context, inputView, backgroundResource, bx, by, description, guide, leftAlign);
        }
        
        void init(Context context, View inputView, int backgroundResource,
                  int bx, int by, CharSequence description, int guide, boolean leftAlign) {
            bubbleBackground = context.getResources().getDrawable(backgroundResource);
            x = bx;
            y = by;
            width = (int) (inputView.getWidth() * 0.9);
            this.gravity = Gravity.TOP | Gravity.LEFT;
            text = new SpannableStringBuilder()
                .append(description)
                .append("\n") 
                .append(context.getResources().getText(guide));
            this.dismissOnTouch = true;
            this.dismissOnClose = false;
            this.inputView = inputView;
            window = new PopupWindow(context);
            window.setBackgroundDrawable(null);
            LayoutInflater inflate =
                (LayoutInflater) context
                        .getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            textView = (TextView) inflate.inflate(R.layout.bubble_text, null);
            textView.setBackgroundDrawable(bubbleBackground);
            textView.setText(text);
            if (leftAlign) {
                textView.setGravity(Gravity.CENTER_VERTICAL | Gravity.LEFT);
            }
            window.setContentView(textView);
            window.setFocusable(false);
            window.setTouchable(true);
            window.setOutsideTouchable(false);
        }

        private int chooseSize(PopupWindow pop, View parentView, CharSequence text, TextView tv) {
            int wid = tv.getPaddingLeft() + tv.getPaddingRight();
            int ht = tv.getPaddingTop() + tv.getPaddingBottom();

            /*
             * Figure out how big the text would be if we laid it out to the
             * full width of this view minus the border.
             */
            int cap = width - wid;

            Layout l = new StaticLayout(text, tv.getPaint(), cap,
                                        Layout.Alignment.ALIGN_NORMAL, 1, 0, true);
            float max = 0;
            for (int i = 0; i < l.getLineCount(); i++) {
                max = Math.max(max, l.getLineWidth(i));
            }

            /*
             * Now set the popup size to be big enough for the text plus the border.
             */
            pop.setWidth(width);
            pop.setHeight(ht + l.getHeight());
            return l.getHeight();
        }

        void show(int offx, int offy) {
            int textHeight = chooseSize(window, inputView, text, textView);
            offy -= textView.getPaddingTop() + textHeight;
            if (inputView.getVisibility() == View.VISIBLE 
                    && inputView.getWindowVisibility() == View.VISIBLE) {
                try {
                    if ((gravity & Gravity.BOTTOM) == Gravity.BOTTOM) offy -= window.getHeight();
                    if ((gravity & Gravity.RIGHT) == Gravity.RIGHT) offx -= window.getWidth();
                    textView.setOnTouchListener(new View.OnTouchListener() {
                        public boolean onTouch(View view, MotionEvent me) {

                            boolean ret = !mEnableKeyTouch;
                            switch (me.getAction()) {
                            case MotionEvent.ACTION_UP:
                                if (mBubbleIndex >= mBubbles.size()) {
                                    mInputView.setOnTouchListener(null);
                                } else {
                                    TutorialJAJP.this.next();
                                }
                                break;
                            default:
                                break;
                            }
                            return ret;
                        }
                    });
                    window.showAtLocation(inputView, Gravity.NO_GRAVITY, x + offx, y + offy);
                } catch (Exception e) {
                }
            }
        }
        
        void hide() {
            if (window.isShowing()) {
                textView.setOnTouchListener(null);
                window.dismiss();
            }
        }
        
        boolean isShowing() {
            return window.isShowing();
        }
    }

    /** Constructor */
    public TutorialJAJP(OpenWnnJAJP ime, View inputView, DefaultSoftKeyboardJAJP inputManager) {
        mInputManager = inputManager;
        mInputView = inputView;
        mIme = ime;

        Context context = inputView.getContext();
        int inputWidth = inputView.getWidth();
        Resources r = inputView.getContext().getResources();
        final int x = inputWidth / 20;
        r.getDimensionPixelOffset(R.dimen.bubble_pointer_offset);

        SpannableStringBuilder spannable = new SpannableStringBuilder();
        Bubble button;

        spannable.clear();
        spannable.append(r.getText(R.string.tip_to_step1));

        setSpan(spannable, "\u25cb", R.drawable.tutorial_12key_key);
        button = new Bubble(context, inputView, 
                R.drawable.dialog_bubble, x, 0, 
                spannable, R.string.touch_to_continue, false);
        mBubbles.add(button);

        spannable.clear();
        spannable.append(r.getText(R.string.tip_to_step2_a));

        setSpan(spannable, "\u25cb", R.drawable.tutorial_12key_toggle);
        button = new Bubble(context, inputView, 
                R.drawable.dialog_bubble, x, 0, 
                spannable, R.string.touch_to_continue, true);
        mBubbles.add(button);

        spannable.append(r.getText(R.string.tip_to_step2_b));

        setSpan(spannable, "\u2192", R.drawable.tutorial_12key_right);

        button = new Bubble(context, inputView, 
                R.drawable.dialog_bubble, x, 0, 
                spannable, R.string.touch_to_continue, true);
        mBubbles.add(button);

        spannable.append(r.getText(R.string.tip_to_step2_c));

        setSpan(spannable, "\u25cb", R.drawable.tutorial_12key_toggle);

        button = new Bubble(context, inputView, 
                R.drawable.dialog_bubble, x, 0, 
                spannable, R.string.touch_to_continue, true);
        mBubbles.add(button);

        spannable.append(r.getText(R.string.tip_to_step2_d));

        setSpan(spannable, "\u25a0", R.drawable.tutorial_12key_space_jp);

        setSpan(spannable, "\u2193", R.drawable.tutorial_12key_enter);

        button = new Bubble(context, inputView, 
                R.drawable.dialog_bubble, x, 0, 
                spannable, R.string.touch_to_continue, true);
        mBubbles.add(button);

        spannable.clear();
        spannable.append(r.getText(R.string.tip_to_step3_a));

        setSpan(spannable, "\u25a0", R.drawable.tutorial_12key_mode);
        button = new Bubble(context, inputView, 
                R.drawable.dialog_bubble_moji, x, 0, 
                spannable, R.string.touch_to_continue, false);
        mBubbles.add(button);

        button = new Bubble(context, inputView, 
                R.drawable.dialog_bubble_moji, x, 0, 
                R.string.tip_to_step3_b, R.string.touch_to_continue);
        mBubbles.add(button);

        button = new Bubble(context, inputView, 
                R.drawable.dialog_bubble_moji, x, 0, 
                R.string.tip_to_step3_c, R.string.touch_to_continue);
        mBubbles.add(button);

        spannable.clear();
        spannable.append(r.getText(R.string.tip_to_step4));

        setSpan(spannable, "\u25a0", R.drawable.tutorial_12key_mode);
        button = new Bubble(context, inputView, 
                R.drawable.dialog_bubble_moji, x, 0, 
                spannable, R.string.touch_to_try, false);
        mBubbles.add(button);

        spannable.clear();
        spannable.append(r.getText(R.string.tip_to_step5));
 
        setSpan(spannable, "\u2190", R.drawable.tutorial_back);
 
        button = new Bubble(context, inputView, 
                R.drawable.dialog_bubble, x, 0, 
                spannable, R.string.touch_to_continue, false);
        mBubbles.add(button);

        button = new Bubble(context, inputView, 
                R.drawable.dialog_bubble, x, 0, 
                R.string.tip_to_step6, R.string.touch_to_finish);
        mBubbles.add(button);
    }

    private void setSpan(SpannableStringBuilder spannable, String marker, int imageResourceId) {
        String text = spannable.toString();
        int target = text.indexOf(marker);
        while (0 <= target) {
            ImageSpan span = new ImageSpan(mIme, imageResourceId,
                    DynamicDrawableSpan.ALIGN_BOTTOM);
            spannable.setSpan(span, target, target + 1, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE); 
            target = text.indexOf(marker, target + 1);
        }
    }
    
    public void start() {
        mInputView.getLocationInWindow(mLocation);
        mBubbleIndex = -1;
        mInputView.setOnTouchListener(this);
        next();
    }

    boolean next() {
        if (mBubbleIndex >= 0) {
            if (!mBubbles.get(mBubbleIndex).isShowing()) {
                return true;
            }
            for (int i = 0; i <= mBubbleIndex; i++) {
                mBubbles.get(i).hide();
            }
        }
        mBubbleIndex++;
        if (mBubbleIndex >= mBubbles.size()) {
            mEnableKeyTouch = true;
            mIme.sendDownUpKeyEvents(-1);
            mIme.tutorialDone();
            return false;
        }

        if ((6 <= mBubbleIndex) && (mBubbleIndex <= 8)) {
            mInputManager.nextKeyMode();
        }

        if (mBubbleIndex == LONG_PRESS_INDEX) {
            mEnableKeyTouch = true;
        } else if (LONG_PRESS_INDEX < mBubbleIndex) {
            mEnableKeyTouch = false;
        }

        mHandler.sendMessageDelayed(
                mHandler.obtainMessage(MSG_SHOW_BUBBLE, mBubbles.get(mBubbleIndex)), 500);
        return true;
    }
    
    void hide() {
        for (int i = 0; i < mBubbles.size(); i++) {
            mBubbles.get(i).hide();
        }
        mInputView.setOnTouchListener(null);
    }

    public boolean close() {
        mHandler.removeMessages(MSG_SHOW_BUBBLE);
        hide();
        return true;
    }

    public boolean onTouch(View v, MotionEvent event) {
        boolean ret = !mEnableKeyTouch;
        if (event.getAction() == MotionEvent.ACTION_UP) {
            if (mBubbleIndex >= mBubbles.size()) {
                mInputView.setOnTouchListener(null);
            } else {
                if (mBubbleIndex != LONG_PRESS_INDEX) {
                    next();
                }
            }
        }
        return ret;
    }
}
