/*
* AndFHEM - Open Source Android application to control a FHEM home automation
* server.
*
* Copyright (c) 2011, Matthias Klass or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors. All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU GENERAL PUBLIC LICENSE, as published by the Free Software Foundation.
*
* 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.
*
* You should have received a copy of the GNU GENERAL PUBLIC LICENSE
* along with this distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA 02110-1301 USA
*/
package li.klass.fhem.widget.deviceFunctionality;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.preference.DialogPreference;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import com.ericharlow.DragNDrop.DragNDropListView;
import org.apache.pig.impl.util.ObjectSerializer;
import java.util.ArrayList;
import java.util.List;
import javax.inject.Inject;
import li.klass.fhem.AndFHEMApplication;
import li.klass.fhem.R;
import li.klass.fhem.constants.PreferenceKeys;
import li.klass.fhem.domain.core.DeviceFunctionality;
import li.klass.fhem.util.ApplicationProperties;
import li.klass.fhem.util.ArrayListUtil;
import li.klass.fhem.util.Filter;
import static com.google.common.collect.Lists.newArrayList;
import static li.klass.fhem.widget.deviceFunctionality.DeviceFunctionalityOrderAdapter.OrderAction;
public class DeviceFunctionalityOrderPreference extends DialogPreference {
@Inject
ApplicationProperties applicationProperties;
private ArrayList<DeviceFunctionalityPreferenceWrapper> wrappedDevices = newArrayList();
@SuppressWarnings("unused")
public DeviceFunctionalityOrderPreference(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
inject(context);
}
@SuppressWarnings("unused")
public DeviceFunctionalityOrderPreference(Context context, AttributeSet attrs) {
super(context, attrs);
inject(context);
}
private void inject(Context context) {
((AndFHEMApplication) ((Activity) context).getApplication()).getDaggerComponent().inject(this);
}
@Override
protected View onCreateDialogView() {
LayoutInflater inflater = LayoutInflater.from(getContext());
@SuppressLint("InflateParams")
View view = inflater.inflate(R.layout.device_type_order_layout, null);
assert view != null;
DragNDropListView deviceTypeListView = (DragNDropListView) view.findViewById(android.R.id.list);
// dirty hack ... this should be called by Android automatically ...
onSetInitialValue(true, "");
final DeviceFunctionalityOrderAdapter adapter =
new DeviceFunctionalityOrderAdapter(getContext(), R.layout.device_type_list_item,
wrappedDevices);
adapter.setListener(new DeviceFunctionalityOrderAdapter.OrderActionListener() {
@Override
public void deviceTypeReordered(DeviceFunctionalityPreferenceWrapper wrapper, OrderAction action) {
int currentPosition = wrappedDevices.indexOf(wrapper);
switch (action) {
case VISIBILITY_CHANGE:
wrappedDevices.get(currentPosition).invertVisibility();
break;
}
callChangeListener(wrappedDevices);
}
});
deviceTypeListView.setAdapter(adapter);
return view;
}
@Override
protected void onSetInitialValue(boolean restore, Object defaultValue) {
super.onSetInitialValue(restore, defaultValue);
DeviceGroupHolder deviceTypeHolder = new DeviceGroupHolder(applicationProperties);
List<DeviceFunctionality> visible = deviceTypeHolder.getVisible(getContext());
List<DeviceFunctionality> invisible = deviceTypeHolder.getInvisible(getContext());
this.wrappedDevices = wrapDevices(visible, invisible);
}
private ArrayList<DeviceFunctionalityPreferenceWrapper> wrapDevices(
List<DeviceFunctionality> visible, List<DeviceFunctionality> invisible) {
ArrayList<DeviceFunctionalityPreferenceWrapper> returnList = newArrayList();
returnList.addAll(wrapList(visible, true));
returnList.addAll(wrapList(invisible, false));
return returnList;
}
private List<DeviceFunctionalityPreferenceWrapper> wrapList(
List<DeviceFunctionality> toWrap, boolean isVisible) {
List<DeviceFunctionalityPreferenceWrapper> result = newArrayList();
for (DeviceFunctionality deviceType : toWrap) {
result.add(new DeviceFunctionalityPreferenceWrapper(deviceType, isVisible));
}
return result;
}
@Override
protected void onDialogClosed(boolean positiveResult) {
if (!positiveResult) return;
save();
}
private void save() {
saveVisibleDevices();
saveInvisibleDevices();
}
private void saveVisibleDevices() {
ArrayList<DeviceFunctionalityPreferenceWrapper> visibleDevices =
ArrayListUtil.filter(wrappedDevices, new Filter<DeviceFunctionalityPreferenceWrapper>() {
@Override
public boolean doFilter(DeviceFunctionalityPreferenceWrapper object) {
return object.isVisible();
}
});
DeviceFunctionality[] toPersist = unwrapDeviceTypes(visibleDevices);
if (shouldPersist()) persistString(ObjectSerializer.serialize(toPersist));
}
private void saveInvisibleDevices() {
ArrayList<DeviceFunctionalityPreferenceWrapper> invisibleDevices =
ArrayListUtil.filter(wrappedDevices, new Filter<DeviceFunctionalityPreferenceWrapper>() {
@Override
public boolean doFilter(DeviceFunctionalityPreferenceWrapper object) {
return !object.isVisible();
}
});
DeviceFunctionality[] toPersist = unwrapDeviceTypes(invisibleDevices);
if (shouldPersist()) {
SharedPreferences sharedPreferences = getSharedPreferences();
assert sharedPreferences != null;
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString(PreferenceKeys.DEVICE_TYPE_FUNCTIONALITY_ORDER_INVISIBLE,
ObjectSerializer.serialize(toPersist)).apply();
}
}
private DeviceFunctionality[] unwrapDeviceTypes(ArrayList<DeviceFunctionalityPreferenceWrapper> toUnwrap) {
ArrayList<DeviceFunctionality> finalList = newArrayList();
for (DeviceFunctionalityPreferenceWrapper wrapper : toUnwrap) {
finalList.add(wrapper.getDeviceFunctionality());
}
return finalList.toArray(new DeviceFunctionality[finalList.size()]);
}
@Override
protected boolean shouldPersist() {
return true;
}
}