"""

Python Interchangeable Virtual Instrument Library

Copyright (c) 2014 Alex Forencich

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

"""

from . import ivi

# Exceptions
class InvalidScanListException(ivi.IviException): pass
class InvalidSwitchPathException(ivi.IviException): pass
class EmptyScanListException(ivi.IviException): pass
class EmptySwitchPathException(ivi.IviException): pass
class ScanInProgressException(ivi.IviException): pass
class NoScanInProgressException(ivi.IviException): pass
class NoSuchPathException(ivi.IviException): pass
class IsConfigurationChannelException(ivi.IviException): pass
class NotAConfigurationChannelException(ivi.IviException): pass
class AttemptToConnectSourcesException(ivi.IviException): pass
class ExplicitConnectionExistsException(ivi.IviException): pass
class LegMissingFirstChannelException(ivi.IviException): pass
class LegMissingSecondChannelException(ivi.IviException): pass
class ChannelDuplicatedInLegException(ivi.IviException): pass
class ChannelDuplicatedInPathException(ivi.IviException): pass
class PathNotFoundException(ivi.IviException): pass
class DiscontinuousPathException(ivi.IviException): pass
class CannotConnectDirectlyException(ivi.IviException): pass
class ChannelsAlreadyConnectedException(ivi.IviException): pass
class CannotConnectToItselfException(ivi.IviException): pass

# Parameter Values
ScanMode = set(['none', 'break_before_make', 'break_after_make'])
ScanActionType = set(['connect_path', 'disconnect_path', 'wait_for_trigger'])
Path = set(['available', 'exists', 'unsupported', 'resource_in_use',
            'source_conflict', 'channel_not_available'])

class Base(ivi.IviContainer):
    "Base IVI methods for all switch modules"
    
    def __init__(self, *args, **kwargs):
        # needed for _init_channels calls from other __init__ methods
        self._channel_count = 1
        
        super(Base, self).__init__( *args, **kwargs)
        
        cls = 'IviSwtch'
        grp = 'Base'
        ivi.add_group_capability(self, cls+grp)
        
        self._channel_name = list()
        self._channel_characteristics_ac_current_carry_max = list()
        self._channel_characteristics_ac_current_switching_max = list()
        self._channel_characteristics_ac_power_carry_max = list()
        self._channel_characteristics_ac_power_switching_max = list()
        self._channel_characteristics_ac_voltage_max = list()
        self._channel_characteristics_bandwidth = list()
        self._channel_characteristics_impedance = list()
        self._channel_characteristics_dc_current_carry_max = list()
        self._channel_characteristics_dc_current_switching_max = list()
        self._channel_characteristics_dc_power_carry_max = list()
        self._channel_characteristics_dc_power_switching_max = list()
        self._channel_characteristics_dc_voltage_max = list()
        self._channel_is_configuration_channel = list()
        self._channel_is_source_channel = list()
        self._channel_characteristics_settling_time = list()
        self._channel_characteristics_wire_mode = list()
        self._path_is_debounced = False
        
        self._add_property('channels[].characteristics.ac_current_carry_max',
                        self._get_channel_characteristics_ac_current_carry_max,
                        None,
                        None,
                        ivi.Doc("""
                        The maximum AC current the channel can carry, in amperes RMS.
                        
                        Notice that values for this attribute are on per-channel basis and may not
                        take into account the other switches that make up a path to or from this
                        channel.
                        """, cls, grp, '4.2.1'))
        self._add_property('channels[].characteristics.ac_current_switching_max',
                        self._get_channel_characteristics_ac_current_switching_max,
                        None,
                        None,
                        ivi.Doc("""
                        The maximum AC current the channel can switch, in amperes RMS.
                        
                        Notice that values for this attribute are on per-channel basis and may not
                        take into account the other switches that make up a path to or from this
                        channel.
                        """, cls, grp, '4.2.2'))
        self._add_property('channels[].characteristics.ac_power_carry_max',
                        self._get_channel_characteristics_ac_power_carry_max,
                        None,
                        None,
                        ivi.Doc("""
                        The maximum AC power the channel can handle, in volt-amperes.
                        
                        Notice that values for this attribute are on per-channel basis and may not
                        take into account the other switches that make up a path to or from this
                        channel.
                        """, cls, grp, '4.2.3'))
        self._add_property('channels[].characteristics.ac_power_switching_max',
                        self._get_channel_characteristics_ac_power_switching_max,
                        None,
                        None,
                        ivi.Doc("""
                        The maximum AC power the channel can switch, in volt-amperes.
                        
                        Notice that values for this attribute are on per-channel basis and may not
                        take into account the other switches that make up a path to or from this
                        channel.
                        """, cls, grp, '4.2.4'))
        self._add_property('channels[].characteristics.ac_voltage_max',
                        self._get_channel_characteristics_ac_voltage_max,
                        None,
                        None,
                        ivi.Doc("""
                        The maximum AC voltage the channel can handle, in volts RMS.
                        
                        Notice that values for this attribute are on per-channel basis and may not
                        take into account the other switches that make up a path to or from this
                        channel.
                        """, cls, grp, '4.2.5'))
        self._add_property('channels[].characteristics.bandwidth',
                        self._get_channel_characteristics_bandwidth,
                        None,
                        None,