from ..exceptions import WQXException
from .MeasureCompact import MeasureCompact
from .SimpleContent import (
  ActivityConductingOrganizationText,
  ActivityEndDate,
  ActivityIdentifier,
  ActivityIdentifierUserSupplied,
  ActivityMediaName,
  ActivityMediaSubdivisionName,
  ActivityRelativeDepthName,
  ActivityStartDate,
  ActivityTypeCode,
  CommentText,
  DepthAltitudeReferencePointText,
  MonitoringLocationIdentifier,
  ProjectIdentifier,
  SamplingComponentName
)
from .WQXTime import WQXTime
from typing import List, Union
from yattag import Doc

class ActivityDescription:
  """Basic identification information for an activity conducted within a project."""

  __activityIdentifier: ActivityIdentifier
  __activityIdentifierUserSupplied: ActivityIdentifierUserSupplied
  __activityTypeCode: ActivityTypeCode
  __activityMediaName: ActivityMediaName
  __activityMediaSubdivisionName: ActivityMediaSubdivisionName
  __activityStartDate: ActivityStartDate
  __activityStartTime: WQXTime
  __activityEndDate: ActivityEndDate
  __activityEndTime: WQXTime
  __activityRelativeDepthName: ActivityRelativeDepthName
  __activityDepthHeightMeasure: MeasureCompact
  __activityTopDepthHeightMeasure: MeasureCompact
  __activityBottomDepthHeightMeasure: MeasureCompact
  __activityDepthAltitudeReferencePointText: DepthAltitudeReferencePointText
  __projectIdentifier: ProjectIdentifier
  __activityConductingOrganizationText: List[ActivityConductingOrganizationText]
  __monitoringLocationIdentifier: MonitoringLocationIdentifier
  __samplingComponentName: SamplingComponentName
  __activityCommentText: CommentText

  def __init__(self, o=None, *,
    activityIdentifier:ActivityIdentifier = None,
    activityIdentifierUserSupplied:ActivityIdentifierUserSupplied = None,
    activityTypeCode:ActivityTypeCode = None,
    activityMediaName:ActivityMediaName = None,
    activityMediaSubdivisionName:ActivityMediaSubdivisionName = None,
    activityStartDate:ActivityStartDate = None,
    activityStartTime:WQXTime = None,
    activityEndDate:ActivityEndDate = None,
    activityEndTime:WQXTime = None,
    activityRelativeDepthName:ActivityRelativeDepthName = None,
    activityDepthHeightMeasure:MeasureCompact = None,
    activityTopDepthHeightMeasure:MeasureCompact = None,
    activityBottomDepthHeightMeasure:MeasureCompact = None,
    activityDepthAltitudeReferencePointText:DepthAltitudeReferencePointText = None,
    projectIdentifier:ProjectIdentifier = None,
    activityConductingOrganizationText:List[ActivityConductingOrganizationText] = None,
    monitoringLocationIdentifier:MonitoringLocationIdentifier = None,
    samplingComponentName:SamplingComponentName = None,
    activityCommentText:CommentText = None
  ):
    if isinstance(o, ActivityDescription):
      # Assign attributes from object without typechecking
      self.__activityIdentifier = o.activityIdentifier
      self.__activityIdentifierUserSupplied = o.activityIdentifierUserSupplied
      self.__activityTypeCode = o.activityTypeCode
      self.__activityMediaName = o.activityMediaName
      self.__activityMediaSubdivisionName = o.activityMediaSubdivisionName
      self.__activityStartDate = o.activityStartDate
      self.__activityStartTime = o.activityStartTime
      self.__activityEndDate = o.activityEndDate
      self.__activityEndTime = o.activityEndTime
      self.__activityRelativeDepthName = o.activityRelativeDepthName
      self.__activityDepthHeightMeasure = o.activityDepthHeightMeasure
      self.__activityTopDepthHeightMeasure = o.activityTopDepthHeightMeasure
      self.__activityBottomDepthHeightMeasure = o.activityBottomDepthHeightMeasure
      self.__activityDepthAltitudeReferencePointText = o.activityDepthAltitudeReferencePointText
      self.__projectIdentifier = o.projectIdentifier
      self.__activityConductingOrganizationText = o.activityConductingOrganizationText
      self.__monitoringLocationIdentifier = o.monitoringLocationIdentifier
      self.__samplingComponentName = o.samplingComponentName
      self.__activityCommentText = o.activityCommentText
    elif isinstance(o, dict):
      # Assign attributes from other ActivityDescription with typechecking
      self.activityIdentifier = o.get('activityIdentifier', default = None)
      self.activityIdentifierUserSupplied = o.get('activityIdentifierUserSupplied', default = None)
      self.activityTypeCode = o.get('activityTypeCode', default = None)
      self.activityMediaName = o.get('activityMediaName', default = None)
      self.activityMediaSubdivisionName = o.get('activityMediaSubdivisionName', default = None)
      self.activityStartDate = o.get('activityStartDate', default = None)
      self.activityStartTime = o.get('activityStartTime', default = None)
      self.activityEndDate = o.get('activityEndDate', default = None)
      self.activityEndTime = o.get('activityEndTime', default = None)
      self.activityRelativeDepthName = o.get('activityRelativeDepthName', default = None)
      self.activityDepthHeightMeasure = o.get('activityDepthHeightMeasure', default = None)
      self.activityTopDepthHeightMeasure = o.get('activityTopDepthHeightMeasure', default = None)
      self.activityBottomDepthHeightMeasure = o.get('activityBottomDepthHeightMeasure', default = None)
      self.activityDepthAltitudeReferencePointText = o.get('activityDepthAltitudeReferencePointText', default = None)
      self.projectIdentifier = o.get('projectIdentifier', default = None)
      self.activityConductingOrganizationText = o.get('activityConductingOrganizationText', default = [])
      self.monitoringLocationIdentifier = o.get('monitoringLocationIdentifier', default = None)
      self.samplingComponentName = o.get('samplingComponentName', default = None)
      self.activityCommentText = o.get('activityCommentText', default = None)
    else:
      # Assign attributes from named keywords with typechecking
      self.activityIdentifier = activityIdentifier
      self.activityIdentifierUserSupplied = activityIdentifierUserSupplied
      self.activityTypeCode = activityTypeCode
      self.activityMediaName = activityMediaName
      self.activityMediaSubdivisionName = activityMediaSubdivisionName
      self.activityStartDate = activityStartDate
      self.activityStartTime = activityStartTime
      self.activityEndDate = activityEndDate
      self.activityEndTime = activityEndTime
      self.activityRelativeDepthName = activityRelativeDepthName
      self.activityDepthHeightMeasure = activityDepthHeightMeasure
      self.activityTopDepthHeightMeasure = activityTopDepthHeightMeasure
      self.activityBottomDepthHeightMeasure = activityBottomDepthHeightMeasure
      self.activityDepthAltitudeReferencePointText = activityDepthAltitudeReferencePointText
      self.projectIdentifier = projectIdentifier
      self.activityConductingOrganizationText = activityConductingOrganizationText
      self.monitoringLocationIdentifier = monitoringLocationIdentifier
      self.samplingComponentName = samplingComponentName
      self.activityCommentText = activityCommentText

  @property
  def activityIdentifier(self) -> ActivityIdentifier:
    return self.__activityIdentifier
  @activityIdentifier.setter
  def activityIdentifier(self, val:ActivityIdentifier) -> None:
    self.__activityIdentifier = None if val is None else ActivityIdentifier(val)

  @property
  def activityIdentifierUserSupplied(self) -> ActivityIdentifierUserSupplied:
    return self.__activityIdentifierUserSupplied
  @activityIdentifierUserSupplied.setter
  def activityIdentifierUserSupplied(self, val:ActivityIdentifierUserSupplied) -> None:
    self.__activityIdentifierUserSupplied = None if val is None else ActivityIdentifierUserSupplied(val)

  @property
  def activityTypeCode(self) -> ActivityTypeCode:
    return self.__activityTypeCode
  @activityTypeCode.setter
  def activityTypeCode(self, val:ActivityTypeCode) -> None:
    self.__activityTypeCode = None if val is None else ActivityTypeCode(val)

  @property
  def activityMediaName(self) -> ActivityMediaName:
    return self.__activityMediaName
  @activityMediaName.setter
  def activityMediaName(self, val:ActivityMediaName) -> None:
    self.__activityMediaName = None if val is None else ActivityMediaName(val)

  @property
  def activityMediaSubdivisionName(self) -> ActivityMediaSubdivisionName:
    return self.__activityMediaSubdivisionName
  @activityMediaSubdivisionName.setter
  def activityMediaSubdivisionName(self, val:ActivityMediaSubdivisionName) -> None:
    self.__activityMediaSubdivisionName = None if val is None else ActivityMediaSubdivisionName(val)

  @property
  def activityStartDate(self) -> ActivityStartDate:
    return self.__activityStartDate
  @activityStartDate.setter
  def activityStartDate(self, val:ActivityStartDate) -> None:
    self.__activityStartDate = None if val is None else ActivityStartDate(year=val.year,month=val.month,day=val.day)

  @property
  def activityStartTime(self) -> WQXTime:
    """The measure of clock time when the field activity began."""
    return self.__activityStartTime
  @activityStartTime.setter
  def activityStartTime(self, val:WQXTime) -> None:
    """The measure of clock time when the field activity began."""
    self.__activityStartTime = None if val is None else WQXTime(val)

  @property
  def activityEndDate(self) -> ActivityEndDate:
    return self.__activityEndDate
  @activityEndDate.setter
  def activityEndDate(self, val:ActivityEndDate) -> None:
    self.__activityEndDate = None if val is None else ActivityEndDate(year=val.year,month=val.month,day=val.day)

  @property
  def activityEndTime(self) -> WQXTime:
    """The measure of clock time when the field activity ended."""
    return self.__activityEndTime
  @activityEndTime.setter
  def activityEndTime(self, val:WQXTime) -> None:
    """The measure of clock time when the field activity ended."""
    self.__activityEndTime = None if val is None else WQXTime(val)

  @property
  def activityRelativeDepthName(self) -> ActivityRelativeDepthName:
    return self.__activityRelativeDepthName
  @activityRelativeDepthName.setter
  def activityRelativeDepthName(self, val:ActivityRelativeDepthName) -> None:
    self.__activityRelativeDepthName = None if val is None else ActivityRelativeDepthName(val)

  @property
  def activityDepthHeightMeasure(self) -> MeasureCompact:
    """A measurement of the vertical location (measured from a reference point) at which an activity occurred."""
    return self.__activityDepthHeightMeasure
  @activityDepthHeightMeasure.setter
  def activityDepthHeightMeasure(self, val:MeasureCompact) -> None:
    """A measurement of the vertical location (measured from a reference point) at which an activity occurred."""
    self.__activityDepthHeightMeasure = None if val is None else MeasureCompact(val)

  @property
  def activityTopDepthHeightMeasure(self) -> MeasureCompact:
    """A measurement of the upper vertical location of a vertical location range (measured from a reference point) at which an activity occurred."""
    return self.__activityTopDepthHeightMeasure
  @activityTopDepthHeightMeasure.setter
  def activityTopDepthHeightMeasure(self, val:MeasureCompact) -> None:
    """A measurement of the upper vertical location of a vertical location range (measured from a reference point) at which an activity occurred."""
    self.__activityTopDepthHeightMeasure = None if val is None else MeasureCompact(val)

  @property
  def activityBottomDepthHeightMeasure(self) -> MeasureCompact:
    """A measurement of the lower vertical location of a vertical location range (measured from a reference point) at which an activity occurred."""
    return self.__activityBottomDepthHeightMeasure
  @activityBottomDepthHeightMeasure.setter
  def activityBottomDepthHeightMeasure(self, val:MeasureCompact) -> None:
    """A measurement of the lower vertical location of a vertical location range (measured from a reference point) at which an activity occurred."""
    self.__activityBottomDepthHeightMeasure = None if val is None else MeasureCompact(val)

  @property
  def activityDepthAltitudeReferencePointText(self) -> DepthAltitudeReferencePointText:
    """The reference used to indicate the datum or reference used to establish the depth/altitude of an activity."""
    return self.__activityDepthAltitudeReferencePointText
  @activityDepthAltitudeReferencePointText.setter
  def activityDepthAltitudeReferencePointText(self, val:DepthAltitudeReferencePointText) -> None:
    """The reference used to indicate the datum or reference used to establish the depth/altitude of an activity."""
    self.__activityDepthAltitudeReferencePointText = None if val is None else DepthAltitudeReferencePointText(val)

  @property
  def projectIdentifier(self) -> ProjectIdentifier:
    return self.__projectIdentifier
  @projectIdentifier.setter
  def projectIdentifier(self, val:ProjectIdentifier) -> None:
    self.__projectIdentifier = None if val is None else ProjectIdentifier(val)

  @property
  def activityConductingOrganizationText(self) -> List[ActivityConductingOrganizationText]:
    return self.__activityConductingOrganizationText
  @activityConductingOrganizationText.setter
  def activityConductingOrganizationText(self, val:Union[ActivityConductingOrganizationText,List[ActivityConductingOrganizationText]]) -> None:
    if val is None:
      self.__activityConductingOrganizationText = []
    elif isinstance(val, list):
      r:List[ActivityConductingOrganizationText] = []
      for x in val:
        r.append(ActivityConductingOrganizationText(x))
      self.__activityConductingOrganizationText = r
    else:
      self.__activityConductingOrganizationText = [ActivityConductingOrganizationText(val)]

  @property
  def monitoringLocationIdentifier(self) -> MonitoringLocationIdentifier:
    return self.__monitoringLocationIdentifier
  @monitoringLocationIdentifier.setter
  def monitoringLocationIdentifier(self, val:MonitoringLocationIdentifier) -> None:
    self.__monitoringLocationIdentifier = None if val is None else MonitoringLocationIdentifier(val)

  @property
  def samplingComponentName(self) -> SamplingComponentName:
    return self.__samplingComponentName
  @samplingComponentName.setter
  def samplingComponentName(self, val:SamplingComponentName) -> None:
    self.__samplingComponentName = None if val is None else SamplingComponentName(val)

  @property
  def activityCommentText(self) -> CommentText:
    """General comments concerning the activity."""
    return self.__activityCommentText
  @activityCommentText.setter
  def activityCommentText(self, val:CommentText) -> None:
    """General comments concerning the activity."""
    self.__activityCommentText = None if val is None else CommentText(val)

  def generateXML(self, name:str = 'ActivityDescription') -> str:
    doc = Doc()
    asis = doc.asis
    line = doc.line
    tag = doc.tag

    with tag(name):
      if self.__activityIdentifier is None:
        raise WQXException("Attribute 'activityIdentifier' is required.")
      line('ActivityIdentifier', self.__activityIdentifier)
      if self.__activityIdentifierUserSupplied is not None:
        line('ActivityIdentifierUserSupplied', self.__activityIdentifierUserSupplied)
      if self.__activityTypeCode is None:
        raise WQXException("Attribute 'activityTypeCode' is required.")
      line('ActivityTypeCode', self.__activityTypeCode)
      if self.__activityMediaName is None:
        raise WQXException("Attribute 'activityMediaName' is required.")
      line('ActivityMediaName', self.__activityMediaName)
      if self.__activityMediaSubdivisionName is not None:
        line('ActivityMediaSubdivisionName', self.__activityMediaSubdivisionName)
      if self.__activityStartDate is None:
        raise WQXException("Attribute 'activityStartDate' is required.")
      line('ActivityStartDate', str(self.__activityStartDate))
      if self.__activityStartTime is not None:
        asis(self.__activityStartTime.generateXML('ActivityStartTime'))
      if self.__activityEndDate is not None:
        line('ActivityEndDate', str(self.__activityEndDate))
      if self.__activityEndTime is not None:
        asis(self.__activityEndTime.generateXML('ActivityEndTime'))
      if self.__activityRelativeDepthName is not None:
        line('ActivityRelativeDepthName', self.__activityRelativeDepthName)
      if self.__activityDepthHeightMeasure is not None:
        asis(self.__activityDepthHeightMeasure.generateXML('ActivityDepthHeightMeasure'))
      if self.__activityTopDepthHeightMeasure is not None:
        asis(self.__activityTopDepthHeightMeasure.generateXML('ActivityTopDepthHeightMeasure'))
      if self.__activityBottomDepthHeightMeasure is not None:
        asis(self.__activityBottomDepthHeightMeasure.generateXML('ActivityBottomDepthHeightMeasure'))
      if self.__activityDepthAltitudeReferencePointText is not None:
        line('ActivityDepthAltitudeReferencePointText', self.__activityDepthAltitudeReferencePointText)
      if self.__projectIdentifier is None or len(self.__projectIdentifier) < 1:
        raise WQXException("Attribute 'projectIdentifier' must be a list of 1 or more ProjectIdentifier objects.")
      line('ProjectIdentifier', self.__projectIdentifier)
      for x in self.__activityConductingOrganizationText:
        line('ActivityConductingOrganizationText', x)
      if self.__monitoringLocationIdentifier is not None:
        line('MonitoringLocationIdentifier', self.__monitoringLocationIdentifier)
      if self.__samplingComponentName is not None:
        line('SamplingComponentName', self.__samplingComponentName)
      if self.__activityCommentText is not None:
        line('ActivityCommentText', self.__activityCommentText)

    return doc.getvalue()
