/* ----------------------------------------------------------------------------
 * 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 IntVect getAudioCodecList() {
    return new IntVect(SFLPhoneserviceJNI.ConfigurationManagerJNI_getAudioCodecList(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 getEchoCancelTailLength() {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_getEchoCancelTailLength(swigCPtr, this);
  }

  public void setEchoCancelTailLength(int length) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setEchoCancelTailLength(swigCPtr, this, length);
  }

  public int getEchoCancelDelay() {
    return SFLPhoneserviceJNI.ConfigurationManagerJNI_getEchoCancelDelay(swigCPtr, this);
  }

  public void setEchoCancelDelay(int delay) {
    SFLPhoneserviceJNI.ConfigurationManagerJNI_setEchoCancelDelay(swigCPtr, this, delay);
  }

  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);
  }

}
