/**
 * 
 * @author declanshanaghy
 * http://blog.350nice.com/wp/archives/240
 * MultiChoice Preference Widget for Android
 *
 * @contributor matiboy
 * Added support for check all/none and custom separator defined in XML.
 * IMPORTANT: The following attributes MUST be defined (probably inside attr.xml) for the code to even compile
 * <declare-styleable name="ListPreferenceMultiSelect">
    	<attr format="string" name="separator" />
    </declare-styleable>
 *  Whether you decide to then use those attributes is up to you.
 *
 */

package com.mamewo.malarm24;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

import android.app.AlertDialog.Builder;
import android.content.Context;
import android.content.DialogInterface;
import android.content.res.TypedArray;
import android.preference.ListPreference;
import android.util.AttributeSet;
import android.util.Log;

public class MultiListPreference
	extends ListPreference
{
	public static final String SEPARATOR = "!";
	private static final String LOG_TAG = "ListPreferenceMultiSelect";
	private boolean[] mClickedDialogEntryIndices;
	
	// Constructor
	public MultiListPreference(Context context, AttributeSet attrs) {
		super(context, attrs);
		// Initialize the array of boolean to the same size as number of entries
		mClickedDialogEntryIndices = new boolean[getEntries().length];
	}

	@Override
	public void setEntries(CharSequence[] entries) {
		super.setEntries(entries);
		// Initialize the array of boolean to the same size as number of entries
		mClickedDialogEntryIndices = new boolean[entries.length];
	}

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

	@Override
	protected void onPrepareDialogBuilder(Builder builder) {
		CharSequence[] entries = getEntries();
		CharSequence[] entryValues = getEntryValues();
		if (entries == null || entryValues == null || entries.length != entryValues.length) {
			throw new IllegalStateException(
					"ListPreference requires an entries array and an entryValues array which are both the same length");
		}

		restoreCheckedEntries();
		builder.setMultiChoiceItems(entries, mClickedDialogEntryIndices, 
				new DialogInterface.OnMultiChoiceClickListener() {
			public void onClick(DialogInterface dialog, int which, boolean val) {
				mClickedDialogEntryIndices[which] = val;
			}
		});
	}

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

	public String[] parseStoredValue(CharSequence val) {
		if (null == val || "".equals(val)) {
			return null;
		}
		else {
			return ((String)val).split(SEPARATOR);
		}
	}

	private void restoreCheckedEntries() {
		CharSequence[] entryValues = getEntryValues();

		Log.i("malrm", "value: " + getValue());

		// Explode the string read in sharedpreferences
		String[] vals = parseStoredValue(getValue());

		if (vals != null) {
			List<String> valuesList = Arrays.asList(vals);
			for (int i = 0; i < entryValues.length; i++) {
				CharSequence entry = entryValues[i];
				if (valuesList.contains(entry)) {
					mClickedDialogEntryIndices[i] = true;
				}
			}
		}
	}

	@Override
	protected void onDialogClosed(boolean positiveResult) {
		ArrayList<String> values = new ArrayList<String>();

		CharSequence[] entryValues = getEntryValues();
		if (positiveResult && entryValues != null) {
			for (int i = 0; i < entryValues.length; i++) {
				if (mClickedDialogEntryIndices[i]) {
					// Don't save the state of check all option - if any
					String val = (String) entryValues[i];
					values.add(val);
				}
			}

			if (callChangeListener(values)) {
				setValue(join(values, SEPARATOR));
			}
		}
	}

	// Credits to kurellajunior on this post http://snippets.dzone.com/posts/show/91
	protected static String join( Iterable< ? extends Object > pColl, String separator ) {
		Iterator< ? extends Object > oIter;
		if ( pColl == null || ( !( oIter = pColl.iterator() ).hasNext() ) )
			return "";
		StringBuilder oBuilder = new StringBuilder( String.valueOf( oIter.next() ) );
		while ( oIter.hasNext() )
			oBuilder.append( separator ).append( oIter.next() );
		return oBuilder.toString();
	}
}

@@ -556,16 +556,70 @@
 alarm24;
+%0A//modified by Takashi Masuyama %3Cmamewotoko@gmail.com%3E
 %0A%0Aimport
@@ -1033,27 +1033,28 @@
 %0A%7B%0A%09
-public
+final
  static
- final
+%0A%09public
  Str
@@ -1079,28 +1079,29 @@
 %22;%0A%09
-private static final
+final static%0A%09private
  Str
@@ -1196,24 +1196,8 @@
 ;%0A%09%0A
-%09// Constructor%0A
 %09pub
@@ -1933,25 +1933,29 @@
 s == null %7C%7C
- 
+%0A%09%09%09%09
 entries.leng
@@ -2089,17 +2089,26 @@
 es array
- 
+%22 +%0A%09%09%09%09%09%22
 which ar
@@ -3811,16 +3811,24 @@
 show/91%0A
+%09static%0A
 %09protect
@@ -3834,15 +3834,8 @@
 ted 
-static 
 Stri
@@ -3842,17 +3842,16 @@
 ng join(
- 
 Iterable
@@ -3894,17 +3894,16 @@
 eparator
- 
 ) %7B%0A%09%09It

modify style