/*
 * Copyright 2012 Jay Weisskopf
 *
 * Licensed under the MIT License (see LICENSE.txt)
 */

package net.jayschwa.android.preference;

import android.content.Context;
import android.content.res.TypedArray;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.View;
import android.widget.SeekBar;

/**
 * @author Jay Weisskopf
 */
public class SliderPreference extends DialogPreference {

	protected float mValue = DEFAULT_VALUE;
	protected int mSeekBarValue;
	protected int mSeekBarResolution = 10000;
	protected CharSequence[] mSummaries;
	protected final static float DEFAULT_VALUE = 0.5f;

	/**
	 * @param context
	 * @param attrs
	 */
	public SliderPreference(Context context, AttributeSet attrs) {
		super(context, attrs);
		setup(context, attrs);
	}

	/**
	 * @param context
	 * @param attrs
	 * @param defStyle
	 */
	public SliderPreference(Context context, AttributeSet attrs, int defStyle) {
		super(context, attrs, defStyle);
		setup(context, attrs);
	}

	private void setup(Context context, AttributeSet attrs) {
		setDialogLayoutResource(R.layout.slider_preference_dialog);
		TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.SliderPreference);
		try {
			setSummary(a.getTextArray(R.styleable.SliderPreference_android_summary));
		} catch (Exception e) {
			// Do nothing
		}
		a.recycle();
	}

	@Override
	protected Object onGetDefaultValue(TypedArray a, int index) {
		return a.getFloat(index, DEFAULT_VALUE);
	}

	@Override
	protected void onSetInitialValue(boolean restoreValue, Object defaultValue) {
		setValue(restoreValue ? getPersistedFloat(mValue) : (Float) defaultValue);
	}

	@Override
	public CharSequence getSummary() {
		if (mSummaries != null && mSummaries.length > 0) {
			int index = (int) (mValue * mSummaries.length);
			index = Math.min(index, mSummaries.length - 1);
			return mSummaries[index];
		} else {
			return super.getSummary();
		}
	}

	public void setSummary(CharSequence[] summaries) {
		mSummaries = summaries;
	}

	@Override
	public void setSummary(CharSequence summary) {
		super.setSummary(summary);
		mSummaries = null;
	}

	@Override
	public void setSummary(int summaryResId) {
		try {
			setSummary(getContext().getResources().getStringArray(summaryResId));
		} catch (Exception e) {
			super.setSummary(summaryResId);
		}
	}

	public float getValue() {
		return mValue;
	}

	public void setValue(float value) {
		value = Math.max(0, Math.min(value, 1)); // clamp to [0, 1]
		if (shouldPersist()) {
			persistFloat(value);
		}
		if (value != mValue) {
			mValue = value;
			notifyChanged();
		}
	}

	protected void setSeekBarValue(int value) {
		mSeekBarValue = value;
	}

	@Override
	protected View onCreateDialogView() {
		mSeekBarValue = (int) (mValue * mSeekBarResolution);
		View view = super.onCreateDialogView();
		SeekBar seekbar = (SeekBar) view.findViewById(R.id.slider_preference_seekbar);
		seekbar.setMax(mSeekBarResolution);
		seekbar.setProgress(mSeekBarValue);
		seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

			@Override
			public void onStopTrackingTouch(SeekBar seekBar) {
			}

			@Override
			public void onStartTrackingTouch(SeekBar seekBar) {
			}

			@Override
			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
				if (fromUser) {
					SliderPreference.this.setSeekBarValue(progress);
				}
			}
		});
		return view;
	}

	@Override
	protected void onDialogClosed(boolean positiveResult) {
		final float newValue = (float) mSeekBarValue / mSeekBarResolution;
		if (positiveResult && callChangeListener(newValue)) {
			setValue(newValue);
		}
		super.onDialogClosed(positiveResult);
	}

	// TODO: Save and restore preference state.
}

@@ -444,21 +444,25 @@
 ed f
-loat mValue =
+inal static float
  DEF
@@ -471,16 +471,23 @@
 LT_VALUE
+ = 0.5f
 ;%0A%09prote
@@ -495,25 +495,93 @@
 ted 
+f
 in
-t mSeekBarValue
+al static int SEEKBAR_RESOLUTION = 10000;%0A%0A%09protected float mValue = DEFAULT_VALUE
 ;%0A%09p
@@ -605,26 +605,13 @@
 kBar
-Resolution = 10000
+Value
 ;%0A%09p
@@ -649,60 +649,8 @@
 ies;
-%0A%09protected final static float DEFAULT_VALUE = 0.5f;
 %0A%0A%09/
@@ -2779,34 +2779,34 @@
 Value * 
-mSeekBarResolution
+SEEKBAR_RESOLUTION
 );%0A%09%09Vie
@@ -2940,34 +2940,34 @@
 .setMax(
-mSeekBarResolution
+SEEKBAR_RESOLUTION
 );%0A%09%09see
@@ -3552,26 +3552,26 @@
 e / 
-mSeekBarResolution
+SEEKBAR_RESOLUTION
 ;%0A%09%09

Change seek bar resolution to a constant