/* ----------------------------------------------------------------------------
 * This file was automatically generated by SWIG (http://www.swig.org).
 * Version 2.0.8
 *
 * Do not make changes to this file unless you know what you are doing--modify
 * the SWIG interface file instead.
 * ----------------------------------------------------------------------------- */

package com.savoirfairelinux.sflphone.service;

public class ConfigurationManagerJNI {
  private long swigCPtr;
  protected boolean swigCMemOwn;

  protected ConfigurationManagerJNI(long cPtr, boolean cMemoryOwn) {
    swigCMemOwn = cMemoryOwn;
    swigCPtr = cPtr;
  }

  protected static long getCPtr(ConfigurationManagerJNI obj) {
    return (obj == null) ? 0 : obj.swigCPtr;
  }

  protected void finalize() {
    delete();
  }

  public synchronized void delete() {
    if (swigCPtr != 0) {
      if (swigCMemOwn) {
        swigCMemOwn = false;
        SFLPhoneserviceJNI.delete_ConfigurationManagerJNI(swigCPtr);
      }
      swigCPtr = 0;
    }
  }

  public StringMap getIp2IpDetails() {
    return new StringMap(SFLPhoneserviceJNI.ConfigurationManagerJNI_getIp2IpDetails(swigCPtr, this), true);
  }

  public StringMap getAccountDetails(String accountID) {
    return new StringMap(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAccountDetails(swigCPtr, this, accountID), true);
  }

  public StringMap getTlsSettingsDefault() {
    return new StringMap(SFLPhoneserviceJNI.ConfigurationManagerJNI_getTlsSettingsDefault(swigCPtr, this), true);
  }

  public StringMap getTlsSettings() {
    return new StringMap(SFLPhoneserviceJNI.ConfigurationManagerJNI_getTlsSettings(swigCPtr, this), true);
  }

  public void setTlsSettings(StringMap details) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setTlsSettings(swigCPtr, this, StringMap.getCPtr(details), details);
  }

  public void setAccountDetails(String accountID, StringMap details) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setAccountDetails(swigCPtr, this, accountID, StringMap.getCPtr(details), details);
  }

  public void sendRegister(String accountID, boolean enable) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_sendRegister(swigCPtr, this, accountID, enable);
  }

  public void registerAllAccounts() {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_registerAllAccounts(swigCPtr, this);
  }

  public StringMap getAccountTemplate() {
    return new StringMap(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAccountTemplate(swigCPtr, this), true);
  }

  public String addAccount(StringMap details) {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_addAccount(swigCPtr, this, StringMap.getCPtr(details), details);
  }

  public void removeAccount(String accoundID) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_removeAccount(swigCPtr, this, accoundID);
  }

  public StringVect getAccountList() {
    return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAccountList(swigCPtr, this), true);
  }

  public StringVect getSupportedTlsMethod() {
    return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getSupportedTlsMethod(swigCPtr, this), true);
  }

  public StringVect getAudioCodecDetails(int payload) {
    return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioCodecDetails(swigCPtr, this, payload), true);
  }

  public IntVect getActiveAudioCodecList(String accountID) {
    return new IntVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getActiveAudioCodecList(swigCPtr, this, accountID), true);
  }

  public void setActiveAudioCodecList(StringVect list, String accountID) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setActiveAudioCodecList(swigCPtr, this, StringVect.getCPtr(list), list, accountID);
  }

  public StringVect getAudioPluginList() {
    return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioPluginList(swigCPtr, this), true);
  }

  public void setAudioPlugin(String audioPlugin) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setAudioPlugin(swigCPtr, this, audioPlugin);
  }

  public StringVect getAudioOutputDeviceList() {
    return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioOutputDeviceList(swigCPtr, this), true);
  }

  public StringVect getAudioInputDeviceList() {
    return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioInputDeviceList(swigCPtr, this), true);
  }

  public void setAudioOutputDevice(int index) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setAudioOutputDevice(swigCPtr, this, index);
  }

  public void setAudioInputDevice(int index) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setAudioInputDevice(swigCPtr, this, index);
  }

  public void setAudioRingtoneDevice(int index) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setAudioRingtoneDevice(swigCPtr, this, index);
  }

  public StringVect getCurrentAudioDevicesIndex() {
    return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getCurrentAudioDevicesIndex(swigCPtr, this), true);
  }

  public int getAudioDeviceIndex(String name) {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioDeviceIndex(swigCPtr, this, name);
  }

  public String getCurrentAudioOutputPlugin() {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_getCurrentAudioOutputPlugin(swigCPtr, this);
  }

  public String getNoiseSuppressState() {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_getNoiseSuppressState(swigCPtr, this);
  }

  public void setNoiseSuppressState(String state) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setNoiseSuppressState(swigCPtr, this, state);
  }

  public String getEchoCancelState() {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_getEchoCancelState(swigCPtr, this);
  }

  public StringMap getRingtoneList() {
    return new StringMap(SFLPhoneserviceJNI.ConfigurationManagerJNI_getRingtoneList(swigCPtr, this), true);
  }

  public void setEchoCancelState(String state) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setEchoCancelState(swigCPtr, this, state);
  }

  public int isIax2Enabled() {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_isIax2Enabled(swigCPtr, this);
  }

  public String getRecordPath() {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_getRecordPath(swigCPtr, this);
  }

  public void setRecordPath(String recPath) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setRecordPath(swigCPtr, this, recPath);
  }

  public boolean getIsAlwaysRecording() {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_getIsAlwaysRecording(swigCPtr, this);
  }

  public void setIsAlwaysRecording(boolean rec) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setIsAlwaysRecording(swigCPtr, this, rec);
  }

  public void setRecordingCall(String id) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setRecordingCall(swigCPtr, this, id);
  }

  public int getHistoryLimit() {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_getHistoryLimit(swigCPtr, this);
  }

  public void clearHistory() {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_clearHistory(swigCPtr, this);
  }

  public void setHistoryLimit(int days) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setHistoryLimit(swigCPtr, this, days);
  }

  public void setAudioManager(String api) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setAudioManager(swigCPtr, this, api);
  }

  public String getAudioManager() {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioManager(swigCPtr, this);
  }

  public StringMap getHookSettings() {
    return new StringMap(SFLPhoneserviceJNI.ConfigurationManagerJNI_getHookSettings(swigCPtr, this), true);
  }

  public void setHookSettings(StringMap settings) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setHookSettings(swigCPtr, this, StringMap.getCPtr(settings), settings);
  }

  public void setAccountsOrder(String order) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setAccountsOrder(swigCPtr, this, order);
  }

  public VectMap getHistory() {
    return new VectMap(SFLPhoneserviceJNI.ConfigurationManagerJNI_getHistory(swigCPtr, this), true);
  }

  public String getAddrFromInterfaceName(String arg0) {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_getAddrFromInterfaceName(swigCPtr, this, arg0);
  }

  public StringVect getAllIpInterface() {
    return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAllIpInterface(swigCPtr, this), true);
  }

  public StringVect getAllIpInterfaceByName() {
    return new StringVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAllIpInterfaceByName(swigCPtr, this), true);
  }

  public StringMap getShortcuts() {
    return new StringMap(SFLPhoneserviceJNI.ConfigurationManagerJNI_getShortcuts(swigCPtr, this), true);
  }

  public void setShortcuts(StringMap shortcutsMap) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setShortcuts(swigCPtr, this, StringMap.getCPtr(shortcutsMap), shortcutsMap);
  }

  public VectMap getCredentials(String accountID) {
    return new VectMap(SFLPhoneserviceJNI.ConfigurationManagerJNI_getCredentials(swigCPtr, this, accountID), true);
  }

  public void setCredentials(String accountID, VectMap details) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setCredentials(swigCPtr, this, accountID, VectMap.getCPtr(details), details);
  }

  public ConfigurationManagerJNI() {
    this(SFLPhoneserviceJNI.new_ConfigurationManagerJNI(), true);
  }

}
