public ClientDataTable(
      Context pContext,
      SQLiteDatabase pSqliteDataBase,
      String pTableName,
      String[] pWhereClauseColumns) {
    _mContext = pContext;
    _mRes = pContext.getResources();
    _mSqliteDataBase = pSqliteDataBase;
    _mTableName = pTableName;
    _mWhereClauseColumns = pWhereClauseColumns;

    if (pSqliteDataBase == null)
      PuUtils.showMessage(_mContext, "Errueur Base de donnée", "La base de données est NULL");
    if (_mTableName == null && _mTableName.equals(""))
      PuUtils.showMessage(_mContext, "Errerur de table", "La table est non mentionnée");

    if (pWhereClauseColumns != null && pWhereClauseColumns.length != 0) {

      _mWhereClause = new StringBuffer();
      _mWhereClause.append(pWhereClauseColumns[0] + "= ?");

      for (int i = 1; i < pWhereClauseColumns.length; i++)
        _mWhereClause.append("AND " + pWhereClauseColumns[i] + "= ?");
    }
  }
  private void updateInDB() {

    if (_mWhereClause != null) {
      ContentValues lValues = new ContentValues();
      String[] lArgs = new String[_mWhereClauseColumns.length];
      int lSize = _mListOfColumns.size();

      for (int i = 0; i < lSize; i++) {

        String lColumnName = _mListOfColumns.get(i).getName();
        TCell lCell = cellByName(lColumnName);
        String lColumnValue = lCell.asString();
        DBAccessMode lAccessMode = lCell.getDBAccessMode();

        if (lAccessMode == DBAccessMode.UPDATE) lValues.put(lColumnName, lColumnValue);
      }

      for (int i = 0; i < _mWhereClauseColumns.length; i++) {

        if (indexOfColumn(_mWhereClauseColumns[i]) == -1) {
          PuUtils.showMessage(
              _mContext,
              "Erreur Column",
              "Column "
                  + _mWhereClauseColumns[i]
                  + " de clause Where  "
                  + "n'est pas une column de client data table :"
                  + _mCDTName);
          return;
        } else if (lValues.containsKey(_mWhereClauseColumns[i])) {
          PuUtils.showMessage(
              _mContext,
              "Erreur Column",
              "impossible de definir la colonne "
                  + _mWhereClauseColumns[i]
                  + " de clause Where comme colonne à modifier dans le CDT:"
                  + _mCDTName);
          return;
        }
        TCell lCell = cellByName(_mWhereClauseColumns[i]);
        lArgs[i] = lCell.asString();
      }
      if (lValues.size() != 0)
        _mSqliteDataBase.update(_mTableName, lValues, _mWhereClause.toString(), lArgs);
    } else PuUtils.showMessage(_mContext, "Erreur Update", "Clause where non definit");
  }
  /**
   * Sort the client data table with priority of columns passed in parametres
   *
   * @param pListOfSortedColumnsNames
   * @param TRowSortOrder : The order of Sort ASSENDING or Decedding
   */
  public void sort(String[] pListOfSortedColumnsNames, TRowSortOrder pSortType) {

    if (pListOfSortedColumnsNames != null && pListOfSortedColumnsNames.length != 0)
      Collections.sort(_mListOfRows, new TRowComparator(pListOfSortedColumnsNames, pSortType));
    else
      PuUtils.showMessage(
          _mContext,
          _mRes.getString(R.string.title_err_sort),
          _mRes.getString(R.string.msg_err_sort));
  }
  /** Apply changes on Date base (if connected) and refresh the layout with the new values */
  public void commit() {

    if (_mCDTStatus == CDTStatus.DELETE || _mCDTStatus == CDTStatus.UPDATE)
      if (getRowsCount() == 0) {
        PuUtils.showMessage(_mContext, "CDT vide", "Client data table est vide");
        return;
      }

    if (_mSqliteDataBase != null && !_mTableName.equals(""))
      if (_mSqliteDataBase.isOpen()) commitIntoDataBase();
      else PuUtils.showMessage(_mContext, "Erreur Data base", "La base de données est fermé");

    commitIntoCDT();

    if (_mOnNotifyDataSetChangedListener != null)
      _mOnNotifyDataSetChangedListener.notifyValueChanged();

    _mCDTStatus = CDTStatus.DEFAULT;
  }
  private void deleteFromDB() {

    if (_mWhereClause != null) {

      String[] lArgs = new String[_mWhereClauseColumns.length];

      for (int i = 0; i < _mWhereClauseColumns.length; i++) {
        TCell lCell = cellByName(_mWhereClauseColumns[i]);

        lArgs[i] = lCell.asString();
        if (lCell.asString().equals(""))
          Log.e(TAG_Error, "Valeur vide pour la clé de suppression :" + _mWhereClauseColumns[i]);
      }

      _mSqliteDataBase.delete(_mTableName, _mWhereClause.toString(), lArgs);
    } else PuUtils.showMessage(_mContext, "Erreur delete", "Clause where non definit");
  }
  /**
   * {@linkplain displayContent} to display client data table content in LogCat
   *
   * @param pColumnsToDisplay : List of columns to display <strong>if we put * we will display all
   *     columns content</strong>
   */
  public void displayContent(String... pColumnsToDisplay) {

    if (pColumnsToDisplay != null && pColumnsToDisplay.length != 0) {

      StringBuffer lColumns = new StringBuffer();
      int lSize = _mListOfRows.size();
      if (pColumnsToDisplay.length == 1 && pColumnsToDisplay[0].equals("*")) {

        for (int i = 0; i < _mListOfColumns.size(); i++)
          lColumns.append(_mListOfColumns.get(i).getName() + " | ");
        // Display columns names
        Log.d(TAG, "COLUMNS:  " + lColumns.toString() + "\n");

        // Display rows
        for (int i = 0; i < lSize; i++)
          Log.v(TAG, "ROW N°" + (i + 1) + ":  " + _mListOfRows.get(i).getContent());

      } else {
        for (int i = 0; i < pColumnsToDisplay.length; i++)
          lColumns.append(pColumnsToDisplay[i] + " | ");

        // Display columns names
        Log.d(TAG, "COLUMNS:  " + lColumns.toString() + "\n");

        for (int i = 0; i < lSize; i++) {

          StringBuffer lRowContent = new StringBuffer();

          for (int j = 0; j < pColumnsToDisplay.length; j++) {
            String lCellContent =
                _mListOfRows.get(i).getCell(indexOfColumn(pColumnsToDisplay[j])).asString();
            lRowContent.append(lCellContent + " | ");
          }

          Log.v(TAG, "ROW N°" + (i + 1) + ":  " + lRowContent);
        }
      }
      // TODO chaines dans les resources
    } else {
      PuUtils.showMessage(
          _mContext,
          "Erreur DisplayContent",
          "il faut que la liste != null ou elle contien au moins 1 element");
    }
  }
  private void commitIntoDataBase() {

    switch (_mCDTStatus) {
      case INSERT:
        insertInDB();
        break;
      case UPDATE:
        updateInDB();
        break;
      case DELETE:
        deleteFromDB();
        break;
      case DEFAULT:
        PuUtils.showMessage(
            _mContext, "No commit", "Acun changement n'est appliqué car le mode est DEFAULT");
        break;
      default:
        break;
    }
  }
  private void insertInDB() {

    ContentValues lValues = new ContentValues();

    int lSize = _mListOfColumns.size();

    for (int i = 0; i < lSize; i++) {

      String lColumnName = _mListOfColumns.get(i).getName();
      TCell lCell = cellByName(lColumnName);
      String lColumnValue = lCell.asString();
      DBAccessMode lAccessMode = lCell.getDBAccessMode();

      if (lAccessMode == DBAccessMode.INSERT) lValues.put(lColumnName, lColumnValue);
    }
    if (lValues.size() == 0) {
      PuUtils.showMessage(_mContext, "Erreur insertion", "Acune valeur définie pour inserer");
      return;
    }
    _mSqliteDataBase.insertOrThrow(_mTableName, null, lValues);
  }