/*
 * Copyright 2016 Peter Kenji Yamanaka
 *
 * 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.pyamsoft.padlock.app.list;

import android.databinding.DataBindingUtil;
import android.support.annotation.CheckResult;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.view.View;
import android.widget.CompoundButton;
import android.widget.RadioButton;
import com.mikepenz.fastadapter.items.AbstractItem;
import com.mikepenz.fastadapter.utils.ViewHolderFactory;
import com.pyamsoft.padlock.R;
import com.pyamsoft.padlock.databinding.AdapterItemLockinfoBinding;
import com.pyamsoft.padlock.model.ActivityEntry;
import com.pyamsoft.padlock.model.LockState;
import java.lang.ref.WeakReference;
import java.util.List;

class LockInfoItem extends AbstractItem<LockInfoItem, LockInfoItem.ViewHolder> {

  @NonNull private static final ViewHolderFactory<? extends ViewHolder> FACTORY = new ItemFactory();
  @NonNull private final String packageName;
  @NonNull private final ActivityEntry entry;

  LockInfoItem(@NonNull String packageName, @NonNull ActivityEntry entry) {
    this.packageName = packageName;
    this.entry = entry;
  }

  @CheckResult @NonNull LockInfoItem copyWithNewLockState(@NonNull LockState newState) {
    return new LockInfoItem(packageName, ActivityEntry.builder(entry).lockState(newState).build());
  }

  @Override public int getType() {
    return R.id.adapter_lock_info;
  }

  @Override public int getLayoutRes() {
    return R.layout.adapter_item_lockinfo;
  }

  @Override public void bindView(ViewHolder holder, List<Object> payloads) {
    super.bindView(holder, payloads);
    holder.bind(packageName, entry);
  }

  @Override public void unbindView(ViewHolder holder) {
    super.unbindView(holder);
    holder.unbind();
  }

  @Override public ViewHolderFactory<? extends ViewHolder> getFactory() {
    return FACTORY;
  }

  interface OnLockRadioCheckedChanged {

    void call(int position, @NonNull String name, @NonNull LockState oldState,
        @NonNull LockState newState);
  }

  @SuppressWarnings("WeakerAccess") protected static class ItemFactory
      implements ViewHolderFactory<ViewHolder> {
    @Override public ViewHolder create(View v) {
      return new ViewHolder(v);
    }
  }

  protected static final class ViewHolder extends RecyclerView.ViewHolder {

    @NonNull private final AdapterItemLockinfoBinding binding;
    @NonNull WeakReference<ActivityEntry> weakEntry;

    ViewHolder(View itemView) {
      super(itemView);
      binding = DataBindingUtil.bind(itemView);
      weakEntry = new WeakReference<>(null);
    }

    @CheckResult @NonNull AdapterItemLockinfoBinding getBinding() {
      return binding;
    }

    void bind(@NonNull String packageName, @NonNull ActivityEntry entry) {
      // Remove any old binds
      final RadioButton lockedButton;
      switch (entry.lockState()) {
        case DEFAULT:
          lockedButton = binding.lockInfoRadioDefault;
          break;
        case WHITELISTED:
          lockedButton = binding.lockInfoRadioWhite;
          break;
        case LOCKED:
          lockedButton = binding.lockInfoRadioBlack;
          break;
        default:
          throw new IllegalStateException("Illegal enum state");
      }

      binding.lockInfoRadioBlack.setOnCheckedChangeListener(null);
      binding.lockInfoRadioWhite.setOnCheckedChangeListener(null);
      binding.lockInfoRadioDefault.setOnCheckedChangeListener(null);
      lockedButton.setChecked(true);

      final String entryName = entry.name();
      String activityName = entryName;
      if (entryName.startsWith(packageName)) {
        final String strippedPackageName = entryName.replace(packageName, "");
        if (strippedPackageName.charAt(0) == '.') {
          activityName = strippedPackageName;
        }
      }
      binding.lockInfoActivity.setText(activityName);

      weakEntry.clear();
      weakEntry = new WeakReference<>(entry);
    }

    void bind(@NonNull OnLockRadioCheckedChanged onCheckedChanged) {
      binding.lockInfoRadioDefault.setOnCheckedChangeListener(
          new OnRadioCheckChangedListener(getAdapterPosition(), weakEntry, onCheckedChanged,
              LockState.DEFAULT));
      binding.lockInfoRadioWhite.setOnCheckedChangeListener(
          new OnRadioCheckChangedListener(getAdapterPosition(), weakEntry, onCheckedChanged,
              LockState.WHITELISTED));
      binding.lockInfoRadioBlack.setOnCheckedChangeListener(
          new OnRadioCheckChangedListener(getAdapterPosition(), weakEntry, onCheckedChanged,
              LockState.LOCKED));
    }

    void unbind() {
      binding.lockInfoActivity.setText(null);
      binding.lockInfoRadioBlack.setOnCheckedChangeListener(null);
      binding.lockInfoRadioWhite.setOnCheckedChangeListener(null);
      binding.lockInfoRadioDefault.setOnCheckedChangeListener(null);
      weakEntry.clear();
    }

    static class OnRadioCheckChangedListener implements CompoundButton.OnCheckedChangeListener {

      private final int position;
      @NonNull private final WeakReference<ActivityEntry> weakEntry;
      @NonNull private final OnLockRadioCheckedChanged onCheckedChanged;
      @NonNull private final LockState changeToState;

      OnRadioCheckChangedListener(int position, @NonNull WeakReference<ActivityEntry> weakEntry,
          @NonNull OnLockRadioCheckedChanged onCheckedChanged, @NonNull LockState changeToState) {
        this.position = position;
        this.weakEntry = weakEntry;
        this.onCheckedChanged = onCheckedChanged;
        this.changeToState = changeToState;
      }

      @Override public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
        if (b) {
          // Don't check it yet, get auth first
          compoundButton.setOnCheckedChangeListener(null);
          compoundButton.setChecked(false);
          compoundButton.setOnCheckedChangeListener(this);

          final ActivityEntry entry = weakEntry.get();
          if (entry != null) {
            onCheckedChanged.call(position, entry.name(), entry.lockState(), changeToState);
          }
        }
      }
    }
  }
}

@@ -1278,16 +1278,42 @@
 il.List;
+%0Aimport timber.log.Timber;
 %0A%0Aclass 
@@ -3813,25 +3813,24 @@
 %22);%0A      %7D%0A
-%0A
       bindin
@@ -4582,24 +4582,317 @@
 dChanged) %7B%0A
+      binding.lockInfoTristateRadiogroup.setOnCheckedChangeListener((radioGroup, i) -%3E %7B%0A        if (radioGroup.getCheckedRadioButtonId() == 0) %7B%0A          Timber.e(%22No radiobutton is checked, set to default%22);%0A          getBinding().lockInfoRadioDefault.setChecked(true);%0A        %7D%0A      %7D);%0A
       bindin
@@ -5650,32 +5650,32 @@
 Listener(null);%0A
-
       binding.lo
@@ -5723,24 +5723,99 @@
 ener(null);%0A
+      binding.lockInfoTristateRadiogroup.setOnCheckedChangeListener(null);%0A
       weakEn

Set lockinfo to default if nothing is checked