cimport util
cdef class Estimate(util.Base):
    """
    A point estimate, consisting of a central value and an error breakdown.
    """

    cdef c.Estimate* estptr(self) except NULL:
        return <c.Estimate *> self.ptr()

    def __init__(self):
        cutil.set_owned_ptr(self, new c.Estimate())


    def copy(self):
        return cutil.set_owned_ptr(self, new c.Estimate(deref(self.estptr())))


    def setVal(self, value):
       self.estptr().setVal(value)


    def setErr(self, *es):
       source = None
       es = list(es)
       if type(es[-1]) is str:
           source = es[-1]
           es = es[:-1]
       errs = es
       if source is None:
           source = ""
       #if isinstance(source, str):
       #    source = source.encode('utf-8')
       if len(errs) == 1:
           if not hasattr(errs[0], "__iter__"):
               self.estptr().setErr(util.read_symmetric(errs[0]), <string> source)
               return
           errs = errs[0]
       self.estptr().setErr(tuple(errs), <string> source)


    def set(self, val, errs, source = ""):
       self.setVal(val)
       self.setErr(errs, source)


    def reset(self):
        """
        () -> None

        Reset the estimates to the unfilled state.
        """
        self.estptr().reset()


    def val(self):
       return self.estptr().val()

    def valMax(self, source = ""):
       return self.estptr().valMax(source)

    def valMin(self, source = ""):
       return self.estptr().valMin(source)

    def errDownUp(self, source = ""):
       return tuple(self.estptr().errDownUp(source))

    def err(self, source = ""):
       return tuple(self.estptr().err(source))

    def errNegPos(self, source = ""):
       return tuple(self.estptr().errNegPos(source))

    def errDown(self, source = ""):
       return self.estptr().errDown(source)

    def errUp(self, source = ""):
       return self.estptr().errUp(source)

    def errNeg(self, source = ""):
       return self.estptr().errNeg(source)

    def errPos(self, source = ""):
       return self.estptr().errPos(source)

    def errAvg(self, source = ""):
       return self.estptr().errAvg(source)

    def errEnv(self, source = ""):
       return self.estptr().errEnv(source)

    def relErrDownUp(self, source = ""):
       return tuple(self.estptr().relErrDownUp(source))

    def relErr(self, source = ""):
       return tuple(self.estptr().relErr(source))

    def relErrDown(self, source = ""):
       return self.estptr().relErrDown(source)

    def relErrUp(self, source = ""):
       return self.estptr().relErrUp(source)

    def relErrAvg(self, source = ""):
       return self.estptr().relErrAvg(source)

    def relErrEnv(self, source = ""):
       return self.estptr().relErrEnv(source)

    def quadSum(self, pat_match = ""):
       return tuple(self.estptr().quadSum(pat_match))

    def quadSumNeg(self, pat_match = ""):
       return self.estptr().quadSumNeg(pat_match)

    def quadSumPos(self, pat_match = ""):
       return self.estptr().quadSumPos(pat_match)

    def quadSumAvg(self, pat_match = ""):
       return self.estptr().quadSumAvg(pat_match)

    def quadSumEnv(self, pat_match = ""):
       return self.estptr().quadSumEnv(pat_match)

    def totalErr(self, pat_match = ""):
       return tuple(self.estptr().totalErr(pat_match))

    def totalErrNeg(self, pat_match = ""):
       return tuple(self.estptr().totalErrNeg(pat_match))

    def totalErrPos(self, pat_match = ""):
       return tuple(self.estptr().totalErrPos(pat_match))

    def totalErrAvg(self, pat_match = ""):
       return self.estptr().totalErrAvg(pat_match)

    def totalErrEnv(self, pat_match = ""):
       return self.estptr().totalErrEnv(pat_match)

    def relTotalErr(self, pat_match = ""):
       return tuple(self.estptr().relTotalErr(pat_match))

    def relTotalErrNeg(self, pat_match = ""):
       return self.estptr().relTotalErrNeg(pat_match)

    def relTotalErrPos(self, pat_match = ""):
       return self.estptr().relTotalErrPos(pat_match)

    def relTotalErrAvg(self, pat_match = ""):
       return self.estptr().relTotalErrAvg(pat_match)

    def relTotalErrEnv(self, pat_match = ""):
       return self.estptr().relTotalErrEnv(pat_match)

    def hasSource(self, str source):
       return self.estptr().hasSource(<string> source)

    def sources(self):
       return self.estptr().sources()

    def numErrs(self):
       return self.estptr().numErrs()

    def rmSource(self, str source):
      return self.estptr().rmSource(<string> source)

    def rmErrs(self):
      return self.estptr().rmErrs()

    def serializeSources(self):
      return self.estptr().sources()

    def deserializeSources(self, data):
      cdef vector[string] cdata
      cdata = [ str(x) for x in data ]
      return self.estptr().deserializeSources(cdata)

    def scale(self, factor):
      self.estptr().scale(factor)

    ## In-place special methods
    def __repr__(self):
        val = self.val()
        #lo,hi = self.quadSum()
        return '<Estimate(value=%.2e)>' % val

    def __add__(Estimate self, Estimate other):
        return cutil.new_owned_cls(Estimate, new c.Estimate(deref(self.estptr()) + deref(other.estptr())))

    def __sub__(Estimate self, Estimate other):
        return cutil.new_owned_cls(Estimate, new c.Estimate(deref(self.estptr()) - deref(other.estptr())))

