private void initializeListData() {
   mListData = new ArrayList<Integer>();
   // Add duration and suppression at the top
   mListData.add(LIST_POS_DURATION, mNotifDesc.getDuration());
   mListData.add(LIST_POS_SUPPRESSION, mNotifDesc.getSuppression());
   // Add something at the repeat header pos to make the array index
   // consistent
   mListData.add(LIST_POS_REPEAT_HEADER, 0);
   // Now add all the repeat items at the end
   mListData.addAll(mNotifDesc.getSortedRepeats());
 }
  @Override
  public void onClick(View v) {
    // Ignore all clicks on the list once a dialog has been
    // created. This is needed to guard against quikly pressing
    // the buttons multiple times.
    if (mDialog != null && mDialog.isShowing()) {
      return;
    }

    int id = v.getId();
    if (id == R.id.button_remove_repeat) {
      int iList = (Integer) v.getTag();
      mListData.remove(iList);
      mListAdapter.notifyDataSetChanged();
    } else if (id == R.id.button_add_new) {
      // Find a new value for the repeat and add a
      // repeat item based on it. This is done by simply
      // adding the default repeat value to the maximum
      // value in the list and then bounding it using the
      // maximum repeat value (which is max(duration) - 1)
      int maxRepeat = 0;
      for (int i = LIST_POS_REPEAT_START; i < mListData.size(); i++) {
        int repeat = mListData.get(i);
        if (repeat > maxRepeat) {
          maxRepeat = repeat;
        }
      }
      int duration = mListData.get(LIST_POS_DURATION);
      maxRepeat += NotifConfig.defaultRepeat;
      if (maxRepeat >= duration) {
        maxRepeat = duration - 1;
      }
      // Add the new repeat item to the list
      mListData.add(LIST_POS_REPEAT_START, new Integer(maxRepeat));
      mListAdapter.notifyDataSetChanged();
    } else if (id == R.id.trig_edit_done) {
      // Copy the values from the UI to the description class,
      // convert to string and then send back the result
      mNotifDesc.setDuration(mListData.get(LIST_POS_DURATION));
      mNotifDesc.setSuppression(mListData.get(LIST_POS_SUPPRESSION));
      if (LIST_POS_REPEAT_START < mListData.size()) {
        mNotifDesc.setRepeats(mListData.subList(LIST_POS_REPEAT_START, mListData.size()));
      } else {
        mNotifDesc.setRepeats(new ArrayList<Integer>());
      }
      Intent intent = new Intent();
      intent.putExtra(KEY_NOTIF_CONFIG, mNotifDesc.toString());
      setResult(0, intent);
      finish();
    } else if (id == R.id.trig_edit_cancel) {
      finish();
    }
  }
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Get the notification description from the intent
    Intent intent = getIntent();
    String desc = intent.getStringExtra(KEY_NOTIF_CONFIG);
    if (desc == null) {
      Log.e(TAG, "NotifEditActivity: No notification " + "description passed. Exiting...");

      finish();
      return;
    }

    // Parse and load the description
    mNotifDesc = new NotifDesc();
    if (!mNotifDesc.loadString(desc)) {
      Log.e(
          TAG,
          "NotifEditActivity: Failed to parse the "
              + "notification description passed. Exiting...");

      finish();
      return;
    }

    setContentView(R.layout.trigger_editor);

    Button b = (Button) findViewById(R.id.trig_edit_done);
    b.setOnClickListener(this);
    b = (Button) findViewById(R.id.trig_edit_cancel);
    b.setOnClickListener(this);

    // Update the GUI with the data
    initializeListData();
    setupListAdaptor();
    validateDataAndUpdateView();
  }
  /*
   * Helper function to prepare the list of active surveys corresponding
   * to trigger.
   *
   * A trigger is active if it has not expired (the notification duration
   * has not been reached) after going off the last time.
   *
   * All surveys associated with an active active trigger are active
   * 	- EXCEPT those which have already been taken by the user within
   * 	  the suppression window.
   */
  private static HashSet<String> getActiveSurveys(Context context, Cursor trig) {

    HashSet<String> actSurveys = new HashSet<String>();

    String runTime = trig.getString(trig.getColumnIndexOrThrow(TriggerDB.KEY_RUNTIME_DESCRIPT));

    String notif = trig.getString(trig.getColumnIndexOrThrow(TriggerDB.KEY_NOTIF_DESCRIPT));

    String actions = trig.getString(trig.getColumnIndexOrThrow(TriggerDB.KEY_TRIG_ACTION_DESCRIPT));

    String campaignUrn = trig.getString(trig.getColumnIndexOrThrow(TriggerDB.KEY_CAMPAIGN_URN));

    Log.i(DEBUG_TAG, "NotifSurveyAdaptor: Calculating active surveys for trigger");

    TriggerRunTimeDesc rtDesc = new TriggerRunTimeDesc();
    NotifDesc notifDesc = new NotifDesc();
    TriggerActionDesc actDesc = new TriggerActionDesc();

    if (!rtDesc.loadString(runTime)
        || !notifDesc.loadString(notif)
        || !actDesc.loadString(actions)) {

      Log.w(DEBUG_TAG, "NotifSurveyAdaptor: Descritptor(s) failed to parse");

      return actSurveys;
    }

    if (!rtDesc.hasTriggerTimeStamp()) {
      Log.i(DEBUG_TAG, "NotifSurveyAdaptor: Trigger time stamp is invalid");

      return actSurveys;
    }

    long now = System.currentTimeMillis();
    long trigTS = rtDesc.getTriggerTimeStamp();

    if (trigTS > now) {
      Log.w(DEBUG_TAG, "NotifSurveyAdaptor: Trigger time stamp is in the future!");
      return actSurveys;
    }

    // How long it has been since the trigger went off
    long elapsedMS = now - trigTS;

    long durationMS = notifDesc.getDuration() * 60000;
    long suppressMS = notifDesc.getSuppression() * 60000;

    if (elapsedMS < durationMS) {

      // The trigger has not expired, check each survey

      String[] surveys = actDesc.getSurveys();
      for (int i = 0; i < surveys.length; i++) {

        // Has the survey been taken in within the
        // suppression window?
        if (IsSurveyTaken(context, campaignUrn, surveys[i], trigTS - suppressMS)) {
          continue;
        }

        // Add the active survey to the set
        actSurveys.add(surveys[i]);
      }
    }

    return actSurveys;
  }
  @Override
  protected Dialog onCreateDialog(int id) {

    if (id >= mListData.size()) {
      return null;
    }

    String title = "";
    String text = "";
    int max = 0;
    int min = 0;

    switch (id) {
      case LIST_POS_DURATION: // Edit notification duration
        title = "Notification duration \n(1 - " + NotifConfig.maxDuration + ")";

        text = String.valueOf(mListData.get(LIST_POS_DURATION));
        max = NotifConfig.maxDuration;
        min = DURATION_MIN;
        break;

      case LIST_POS_SUPPRESSION: // Edit suppression window
        title = "Suppression window \n(0 - " + NotifConfig.maxSuppression + ")";

        text = String.valueOf(mListData.get(LIST_POS_SUPPRESSION));
        max = NotifConfig.maxSuppression;
        min = SUPPRESSION_MIN;
        break;

      case LIST_POS_REPEAT_HEADER: // Repeat header, ignore. Nothing
        // to edit here.
        return null;

      default: // Any other id would correspond to a repeat value
        text = String.valueOf(mListData.get(id));
        min = mNotifDesc.getMinAllowedRepeat();
        max = mListData.get(LIST_POS_DURATION) - 1;

        title = "Set reminder \n(" + min + " - " + max + ")";

        if (min == max) {
          // Nothing to edit. Do nothing
          return null;
        }
    }

    // Launch the text edit dialog
    TrigTextInput ti = new TrigTextInput(this);
    ti.setTitle(title);
    ti.setText(text);
    ti.setNumberMode(true);
    ti.setNumberModeRange(min, max);
    ti.setTag(new Integer(id));
    ti.setPositiveButtonText("Done");
    ti.setNegativeButtonText("Cancel");
    ti.setOnClickListener(
        new TrigTextInput.onClickListener() {

          @Override
          public void onClick(TrigTextInput textInput, int which) {

            if (which == TrigTextInput.BUTTON_POSITIVE) {
              int listPos = (Integer) textInput.getTag();
              if (listPos < mListData.size()) {
                mListData.set(listPos, Integer.valueOf(textInput.getText()));

                // Validate the data
                validateDataAndUpdateView();
              }
            }
          }
        });

    mDialog = ti.createDialog();
    return mDialog;
  }