/*
 * Copyright (C) 2016 Tobias Brunner
 * HSR Hochschule fuer Technik Rapperswil
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation; either version 2 of the License, or (at your
 * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 */

package org.strongswan.android.ui.widget;

import android.content.Context;
import android.content.res.TypedArray;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.google.android.material.textfield.TextInputLayout;

import org.strongswan.android.R;

import androidx.annotation.Nullable;
import androidx.core.view.ViewCompat;
import androidx.core.view.ViewPropertyAnimatorListenerAdapter;

/**
 * Layout that extends {@link TextInputLayout} with a helper text
 * displayed below the text field when it receives the focus. Also, any error message shown with
 * {@link #setError(CharSequence)} is hidden when the text field is changed (this mirrors the
 * behavior of {@link android.widget.EditText}).
 */
public class TextInputLayoutHelper extends TextInputLayout
{
	private LinearLayout mHelperContainer;
	private TextView mHelperText;

	public TextInputLayoutHelper(Context context)
	{
		this(context, null);
	}

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

	public TextInputLayoutHelper(Context context, AttributeSet attrs, int defStyleAttr)
	{
		super(context, attrs);
		TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TextInputLayoutHelper);
		String helper = a.getString(R.styleable.TextInputLayoutHelper_helper_text);
		a.recycle();
		if (helper != null)
		{
			mHelperContainer = new LinearLayout(context);
			mHelperContainer.setOrientation(LinearLayout.HORIZONTAL);
			mHelperContainer.setVisibility(View.INVISIBLE);
			addView(mHelperContainer, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);

			mHelperText = new TextView(context);
			mHelperText.setText(helper);
			mHelperText.setTextSize(TypedValue.COMPLEX_UNIT_SP, 12);
			a = context.obtainStyledAttributes(attrs, new int[]{android.R.attr.textColorSecondary});
			mHelperText.setTextColor(a.getColor(0, mHelperText.getCurrentTextColor()));
			a.recycle();

			mHelperContainer.addView(mHelperText, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
		}
	}

	@Override
	public void addView(View child, int index, ViewGroup.LayoutParams params)
	{
		super.addView(child, index, params);
		if (child instanceof EditText)
		{
			EditText text = (EditText)child;
			text.addTextChangedListener(new TextWatcher() {
				@Override
				public void beforeTextChanged(CharSequence s, int start, int count, int after) {}

				@Override
				public void onTextChanged(CharSequence s, int start, int before, int count) {}

				@Override
				public void afterTextChanged(Editable s)
				{
					if (getError() != null)
					{
						setError(null);
					}
				}
			});
			if (mHelperContainer != null)
			{
				text.setOnFocusChangeListener(new OnFocusChangeListener() {
					@Override
					public void onFocusChange(View v, boolean hasFocus)
					{
						showHelper(hasFocus);
					}
				});
				ViewCompat.setPaddingRelative(mHelperContainer, ViewCompat.getPaddingStart(text),
											  0, ViewCompat.getPaddingEnd(text), text.getPaddingBottom());
			}
		}
	}

	@Override
	public void setError(@Nullable CharSequence error)
	{
		super.setError(error);
		if (mHelperContainer != null)
		{
			if (error == null)
			{	/* this frees up space used by the now invisible error message */
				setErrorEnabled(false);
			}
			else
			{	/* re-add the helper as the error message should be displayed directly under the textbox */
				removeView(mHelperContainer);
				addView(mHelperContainer, LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT);
			}
		}
	}

	/**
	 * Set the helper text to be displayed below the text field.
	 *
	 * @attr ref R.styleable#TextInputLayoutHelper_helper_text
	 */
	public void setHelperText(CharSequence text)
	{
		if (mHelperText != null)
		{
			mHelperText.setText(text);
		}
	}

	private void showHelper(boolean show)
	{
		if (show == (mHelperContainer.getVisibility() == View.VISIBLE))
		{
			return;
		}
		if (show)
		{
			ViewCompat.animate(mHelperContainer)
					  .alpha(1f)
					  .setDuration(200)
					  .setListener(new ViewPropertyAnimatorListenerAdapter() {
						  @Override
						  public void onAnimationStart(View view)
						  {
							  view.setVisibility(View.VISIBLE);
						  }
					  }).start();
		}
		else
		{
			ViewCompat.animate(mHelperContainer)
					  .alpha(0f)
					  .setDuration(200)
					  .setListener(new ViewPropertyAnimatorListenerAdapter() {
						  @Override
						  public void onAnimationEnd(View view)
						  {
							  view.setVisibility(View.INVISIBLE);
						  }
					  }).start();
		}
	}
}
