/*
 * Copyright (C) 2013 ZXing authors
 *
 * 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.google.zxing.client.android;

import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;

import android.app.AlertDialog;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.CheckBoxPreference;
import android.preference.EditTextPreference;
import android.preference.Preference;
import android.preference.PreferenceFragment;
import android.preference.PreferenceScreen;

/**
 * Implements support for barcode scanning preferences.
 *
 * @see PreferencesActivity
 */
public final class PreferencesFragment 
    extends PreferenceFragment 
    implements SharedPreferences.OnSharedPreferenceChangeListener {

  private CheckBoxPreference[] checkBoxPrefs;
  
  @Override
  public void onCreate(Bundle icicle) {
    super.onCreate(icicle);
    addPreferencesFromResource(R.xml.preferences);
    
    PreferenceScreen preferences = getPreferenceScreen();
    preferences.getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
    checkBoxPrefs = findDecodePrefs(preferences,
                                    PreferencesActivity.KEY_DECODE_1D_PRODUCT,
                                    PreferencesActivity.KEY_DECODE_1D_INDUSTRIAL,
                                    PreferencesActivity.KEY_DECODE_QR,
                                    PreferencesActivity.KEY_DECODE_DATA_MATRIX,
                                    PreferencesActivity.KEY_DECODE_AZTEC,
                                    PreferencesActivity.KEY_DECODE_PDF417);
    disableLastCheckedPref();

    EditTextPreference customProductSearch = (EditTextPreference)
        preferences.findPreference(PreferencesActivity.KEY_CUSTOM_PRODUCT_SEARCH);
    customProductSearch.setOnPreferenceChangeListener(new CustomSearchURLValidator());
  }

  private static CheckBoxPreference[] findDecodePrefs(PreferenceScreen preferences, String... keys) {
    CheckBoxPreference[] prefs = new CheckBoxPreference[keys.length];
    for (int i = 0; i < keys.length; i++) {
      prefs[i] = (CheckBoxPreference) preferences.findPreference(keys[i]);
    }
    return prefs;
  }
  
  @Override
  public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
    disableLastCheckedPref();
  }

  private void disableLastCheckedPref() {
    Collection<CheckBoxPreference> checked = new ArrayList<>(checkBoxPrefs.length);
    for (CheckBoxPreference pref : checkBoxPrefs) {
      if (pref.isChecked()) {
        checked.add(pref);
      }
    }
    boolean disable = checked.size() <= 1;
    for (CheckBoxPreference pref : checkBoxPrefs) {
      pref.setEnabled(!(disable && checked.contains(pref)));
    }
  }

  private final class CustomSearchURLValidator implements Preference.OnPreferenceChangeListener {
    @Override
    public boolean onPreferenceChange(Preference preference, Object newValue) {
      if (!isValid(newValue)) {
        AlertDialog.Builder builder =
            new AlertDialog.Builder(PreferencesFragment.this.getActivity());
        builder.setTitle(R.string.msg_error);
        builder.setMessage(R.string.msg_invalid_value);
        builder.setCancelable(true);
        builder.show();
        return false;
      }
      return true;
    }

    private boolean isValid(Object newValue) {
      // Allow empty/null value
      if (newValue == null) {
        return true;
      }
      String valueString = newValue.toString();
      if (valueString.isEmpty()) {
        return true;
      }
      // Before validating, remove custom placeholders, which will not
      // be considered valid parts of the URL in some locations:
      // Blank %t and %s:
      valueString = valueString.replaceAll("%[st]", "");
      // Blank %f but not if followed by digit or a-f as it may be a hex sequence
      valueString = valueString.replaceAll("%f(?![0-9a-f])", "");
      // Require a scheme otherwise:
      try {
        URI uri = new URI(valueString);
        return uri.getScheme() != null;
      } catch (URISyntaxException use) {
        return false;
      }
    }
  }

}
