code: package freed.cam.apis.basecamera.parameters;
  
  import androidx.databinding.BaseObservable;
  import androidx.databinding.Bindable;
  import androidx.databinding.library.baseAdapters.BR;
  
  import java.util.ArrayList;
  
  import freed.FreedApplication;
  import freed.cam.apis.basecamera.CameraWrapperInterface;
  import freed.settings.SettingKeys;
  import freed.settings.SettingsManager;
  import freed.settings.mode.SettingMode;
  
  /**
   * Created by troop on 18.06.2017.
   */
  
  public abstract class AbstractParameter<C extends CameraWrapperInterface> extends BaseObservable implements ParameterInterface {
  
      public enum ViewState{
          Visible,
          Hidden,
          Disabled,
          Enabled
      }
  
      private ViewState viewState = ViewState.Hidden;
  
      /**
       * the parameterhandler
       */
      protected C cameraUiWrapper;
      /**
       * contains the values that are supported by the parameters
       */
      protected String[] stringvalues;
      /**
       * the key_value that is currently in use by the parameters
       */
      protected String currentString ="";
      /**
       * the true integer key_value that represents the the currentstring in the array stringvalues
       * so on negative values  -1 = stringarray[stringarray/2 + -1] must get used
       */
      protected int currentInt;
  
      protected SettingKeys.Key key;
      protected SettingMode settingMode;
      protected SettingsManager settingsManager;
  
      public AbstractParameter(SettingKeys.Key  key)
      {
          settingsManager = FreedApplication.settingsManager();
          this.key = key;
          if (key == null || settingsManager.get(key) == null) {
              setViewState(ViewState.Hidden);
              return;
          }
          if (settingsManager.get(key) instanceof  SettingMode) {
              this.settingMode = (SettingMode) settingsManager.get(key);
              stringvalues = settingMode.getValues();
              if (settingMode.isSupported())
                  setViewState(ViewState.Visible);
              currentString = settingMode.get();
          }
          notifyChange();
      }
  
      @Override
      public SettingKeys.Key getKey()
      {
          return key;
      }
  
      @Override
      public void setViewState(ViewState viewState) {
          this.viewState = viewState;
          fireViewStateChanged(viewState);
      }
  
      public AbstractParameter(C cameraUiWrapper, SettingKeys.Key  settingMode)
      {
          this(settingMode);
          this.cameraUiWrapper = cameraUiWrapper;
      }
  
      public void fireIntValueChanged(int current)
      {
          currentInt = current;
          notifyPropertyChanged(BR.intValue);
          notifyPropertyChanged(BR.stringValue);
      }
  
      public void fireStringValueChanged(String value)
      {
          currentString = value;
          notifyPropertyChanged(BR.stringValue);
      }
  
      @Override
      public void fireViewStateChanged(ViewState value)
      {
          viewState = value;
          notifyPropertyChanged(BR.viewState);
      }
  
      @Override
      public void fireStringValuesChanged(String[] value)
      {
          stringvalues = value;
          notifyPropertyChanged(BR.stringValues);
      }
  
      /**
       *
       * @return true if the parameter is supported
       */
      @Bindable
      @Override
      public ViewState getViewState() {
          return viewState;
      }
  
      /**
       *
       * @return returns the current key_value as int
       */
      @Bindable
      @Override
      public int getIntValue() {
          return currentInt;
      }
  
      /**
       *
       * @return returns the current key_value as string
       */
      @Bindable
      @Override
      public String getStringValue()
      {
          return currentString;
      }
  
      /**
       *
       * @return returns all values as StringArray
       */
      @Bindable
      @Override
      public String[] getStringValues() { return stringvalues;}
  
  
  
  
      /**
       * set value to camera async
         override that when you need dont need to run in it background
       * @param valueToSet the int value to set
       * @param setToCamera
       */
      @Override
      public void setIntValue(int valueToSet, boolean setToCamera)
      {
          setValue(valueToSet,setToCamera);
      }
  
      /**
       * runs async gets called from SetValue
       * override that when you want to set stuff in background
       * @param valueToSet
       * @param setToCamera
       */
      protected void setValue(int valueToSet, boolean setToCamera)
      {
          currentInt = valueToSet;
          if (stringvalues != null && valueToSet < stringvalues.length)
              currentString = stringvalues[valueToSet];
          if (settingMode != null)
              settingMode.set(String.valueOf(valueToSet));
          fireIntValueChanged(valueToSet);
      }
  
      /**
       * set value to camera async
       override that when you need dont need to run in it background
       * @param valueToSet to the camera
       * @param setToCamera not needed anymore?
       */
      @Override
      public void setStringValue(String valueToSet, boolean setToCamera) {
          setValue(valueToSet,setToCamera);
      }
  
      /**
       * runs async gets called from SetValue
       * override that when you want to set stuff in background
       * @param valueToSet
       * @param setToCamera
       */
      protected void setValue(String valueToSet, boolean setToCamera)
      {
          currentString = valueToSet;
          fireStringValueChanged(currentString);
          if (settingMode != null)
              settingMode.set(valueToSet);
      }
  
      /**
       * Creates a string array from the passed arguments
       * @param min the minimum value to start
       * @param max the maximum value to end
       * @param step the step wich get applied from min to max
       * @return the string array created
       */
      protected String[] createStringArray(int min,int max, float step)
      {
          ArrayList<String> ar = new ArrayList<>();
          if (step == 0)
              step = 1;
          for (int i = min; i <= max; i+=step)
          {
              ar.add(i+"");
          }
          return ar.toArray(new String[ar.size()]);
      }
  }
  