/*
 * ConnectBot: simple, powerful, open-source SSH client for Android
 * Copyright 2016 Kenny Root, Jeffrey Sharkey
 *
 * 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 org.connectbot.views;

import java.util.List;

import org.connectbot.R;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.annotation.StringRes;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.support.v4.widget.ExploreByTouchHelper;
import android.support.v7.widget.SwitchCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

/**
 * Created by kenny on 5/31/16.
 */
public class CheckableMenuItem extends RelativeLayout {
	private static final String ACCESSIBILITY_EVENT_CLASS_NAME = "android.widget.Switch";

	private final View mRootView;
	private final TextView mTitle;
	private final TextView mSummary;
	private final SwitchCompat mSwitch;
	private final ExploreByTouchHelper mAccessHelper;

	public CheckableMenuItem(Context context, AttributeSet attrs) {
		this(context, attrs, 0);
	}

	public CheckableMenuItem(Context context, AttributeSet attrs, int defStyleAttr) {
		super(context, attrs, defStyleAttr);

		mRootView = inflate(context, R.layout.view_checkablemenuitem, this);

		mTitle = (TextView) mRootView.findViewById(R.id.title);
		mSummary = (TextView) mRootView.findViewById(R.id.summary);
		mSwitch = (SwitchCompat) findViewById(R.id.checkbox_switch);

		setFocusable(true);

		mAccessHelper = new ExploreByTouchHelper(this) {
			private final Rect mTmpRect = new Rect();

			@Override
			protected int getVirtualViewAt(float x, float y) {
				return HOST_ID;
			}

			@Override
			protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
			}

			@Override
			protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
				if (virtualViewId != HOST_ID) {
					return;
				}

				event.setContentDescription(mTitle.getText() + " " + mSummary.getText());
				event.setClassName(ACCESSIBILITY_EVENT_CLASS_NAME);
				event.setChecked(isChecked());
			}

			@Override
			protected void onPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfoCompat node) {
				if (virtualViewId != HOST_ID) {
					return;
				}

				mTmpRect.set(0, 0, CheckableMenuItem.this.getWidth(), CheckableMenuItem.this.getHeight());
				node.setBoundsInParent(mTmpRect);

				node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK);
				node.setClassName(ACCESSIBILITY_EVENT_CLASS_NAME);
				node.setCheckable(true);
				node.setChecked(isChecked());

				node.addChild(mTitle);
				node.addChild(mSummary);
			}

			@Override
			protected boolean onPerformActionForVirtualView(int virtualViewId, int action, Bundle arguments) {
				if (virtualViewId != HOST_ID) {
					return false;
				}

				if (action == AccessibilityNodeInfoCompat.ACTION_CLICK) {
					mSwitch.toggle();
					sendAccessibilityEvent(mRootView,
							AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED);
					return true;
				}

				return false;
			}
		};
		ViewCompat.setAccessibilityDelegate(mRootView, mAccessHelper);

		setOnClickListener(new View.OnClickListener() {
			@Override
			public void onClick(View v) {
				mSwitch.toggle();
			}
		});

		if (attrs != null) {
			TypedArray typedArray = getContext().obtainStyledAttributes(
					attrs, R.styleable.CheckableMenuItem, 0, 0);

			@DrawableRes int iconRes = typedArray.getResourceId(
					R.styleable.CheckableMenuItem_android_icon, 0);
			@StringRes int titleRes = typedArray.getResourceId(
					R.styleable.CheckableMenuItem_android_title, 0);
			@StringRes int summaryRes = typedArray.getResourceId(
					R.styleable.CheckableMenuItem_summary, 0);

			typedArray.recycle();

			ImageView icon = (ImageView) mRootView.findViewById(R.id.icon);
			mTitle.setText(titleRes);
			if (iconRes != 0) {
				Resources resources = context.getResources();
				Resources.Theme theme = context.getTheme();
				Drawable iconDrawable = VectorDrawableCompat.create(resources, iconRes, theme);

				icon.setImageDrawable(iconDrawable);
			}
			if (summaryRes != 0) {
				mSummary.setText(summaryRes);
			}
		}
	}

	public boolean isChecked() {
		return mSwitch.isChecked();
	}

	public void setChecked(boolean checked) {
		mAccessHelper.sendAccessibilityEvent(mRootView,
				AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED);
		mSwitch.setChecked(checked);
	}

	public void toggle() {
		mAccessHelper.sendAccessibilityEvent(mRootView,
				AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED);
		mSwitch.toggle();
	}

	public void setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener listener) {
		mSwitch.setOnCheckedChangeListener(listener);
	}
}

@@ -1847,16 +1847,132 @@
 itch%22;%0A%0A
+%09private final Rect mPlaceHolderRect = new Rect(0, 0, 1, 1);%0A%09private static final String PLACEHOLDER_STRING = %22%22;%0A%0A
 %09private
@@ -3065,32 +3065,142 @@
 d != HOST_ID) %7B%0A
+%09%09%09%09%09// TODO(kroot): remove this when the bug is fixed.%0A%09%09%09%09%09event.setContentDescription(PLACEHOLDER_STRING);%0A
 %09%09%09%09%09return;%0A%09%09%09
@@ -3521,32 +3521,188 @@
 d != HOST_ID) %7B%0A
+%09%09%09%09%09// TODO(kroot): remove this when the bug is fixed.%0A%09%09%09%09%09node.setBoundsInParent(mPlaceHolderRect);%0A%09%09%09%09%09node.setContentDescription(PLACEHOLDER_STRING);%0A
 %09%09%09%09%09return;%0A%09%09%09

Work around for a bug in the accessibility framework