__author__ = 'shenojia'
import sys
import numpy as np
from matplotlib.path import Path
from matplotlib.patches import PathPatch
sys.path.insert(0, '.')
sys.path.insert(0, '..')
from R12_36xxx.HighLayer import *
from R12_36xxx.UE import *
from R12_36xxx.TypesDefition import *
from R12_36211.RE import RE
from R12_36211.SLOT import SLOT
from R12_36211.PRB import *
from R12_math_util.pn import *
class UE_PDSCH_DMRS:
    """
    ue specific Reference Signal (UE_PDSCH_DMRS)

    """
    def __init__(self, slot:SLOT, port:int, v:int,ue:UeConfig):
        self.n__s = slot.n__s
        self.p = port
        self.v = v
        self.ue = ue
        self.res = self._initRes(slot)
        self.patch, self.codes, self.vertices = self._initPatch()
    def __repr__(self):
        return ("crs(slot:{},port:{})".format(self.n__s,self.p))

    def _sequenceGeneration(self, l:int):
        if self.p == 5:
            c__init = (floor(self.n__s/2)+1) * (2*conf.N__ID___cell+1)*2**16 + self.ue.n__RNTI
            c = PN(2*2*conf.N__RB___max_DL, c__init)
            r__n__s  = np.array(np.zeros(12*self.ue.N__RB___PDSCH), dtype=np.complex)
            #TODO:optimzation on math is expected in future, prsent detail foluma is intended for knowledge
            for m in range((12*self.ue.N__RB___PDSCH)):
                r__n__s[m] = np.complex((1/np.sqrt(2))*(1-2*c[2*m]), (1/np.sqrt(2))*(1-2*c[2*m+1]))
            return r__n__s
        else: #port in {7,8,...,6+v}
            c__init = (floor(self.n__s/2)+1) * (2*self.ue.n__ID___n__SCID+1)*2**16 + self.ue.n__SCID
            c = PN(2*2*conf.N__RB___max_DL, c__init)
            r__n__s  = np.array(np.zeros(12*self.ue.N__RB___PDSCH), dtype=np.complex)
            #TODO:optimzation on math is expected in future, prsent detail foluma is intended for knowledge
            if conf.DL_CyclicPrefixType.cyclicPrefix == 0:
                for m in range(12*conf.N__RB___max_DL):
                    r__n__s[m] = np.complex((1/np.sqrt(2))*(1-2*c[2*m]), (1/np.sqrt(2))*(1-2*c[2*m+1]))

            else:
                for m in range(16*conf.N__RB___max_DL):
                    r__n__s[m] = np.complex((1/np.sqrt(2))*(1-2*c[2*m]), (1/np.sqrt(2))*(1-2*c[2*m+1]))
            return r__n__s

    def _initRes(self, slot:SLOT):
        # v__shift = conf.N__ID___cell % 6
        # res = []
        # assert(self.p < 4)
        # if self.p == 0 or self.p == 1:
        #     for l in list((0, conf.N__symb___DL-3)):
        #         if slot.subFrameType.subFrameTypeName == 'S':
        #             if slot.n__s%2 == 0:
        #                 if l > min(conf.N__symb___DwPTS,conf.N__symb___DL):
        #                     continue
        #             else:
        #                 if l > max(conf.N__symb___DwPTS,conf.N__symb___DL) - conf.N__symb___DL:
        #                     continue
        #         r__l_n__s = self._sequenceGeneration(l)
        #
        #         v = 0
        #         if (self.p == 0 and l == 0) or (self.p == 1 and l != 0):
        #             v = 0
        #         elif (self.p == 0 and l != 0) or (self.p == 1 and l == 0):
        #             v = 3
        #         elif self.p == 2:
        #             v = 3*(slot.n__s % 2)
        #         else: #self.p == 3
        #             v = 3 + 3*(slot.n__s % 2)
        #
        #         for m in range(2*conf.N__RB___DL):
        #             m___singleQuote = m + conf.N__RB___max_DL - conf.N__RB___DL
        #             k = 6*m + (v+v__shift) % 6
        #             #TODO:how to consider different serving cell?
        #             #consider primary cell only here.
        #             re = slot.rgs[0].re(k,l)
        #             res.append(re)
        #             re().p = self.p
        #             re().a = r__l_n__s[m___singleQuote]
        #             re().t = ReType('crs')
        # else:
        #     for l in range(1,2):
        #         if slot.subFrameType.subFrameTypeName == 'S':
        #             if slot.n__s%2 == 0:
        #                 if l > min(conf.N__symb___DwPTS,conf.N__symb___DL):
        #                     continue
        #             else:
        #                 if l > max(conf.N__symb___DwPTS,conf.N__symb___DL) - conf.N__symb___DL:
        #                     continue
        #         r__l_n__s = self._sequenceGeneration(l)
        #
        #         v = 0
        #         if (self.p == 0 and l == 0) or (self.p == 1 and l != 0):
        #             v = 0
        #         elif (self.p == 0 and l != 0) or (self.p == 1 and l == 0):
        #             v = 3
        #         elif self.p == 2:
        #             v = 3*(slot.n__s % 2)
        #         else: #self.p == 3
        #             v = 3 + 3*(slot.n__s % 2)
        #
        #         for m in range(2*conf.N__RB___DL):
        #             m___singleQuote = m + conf.N__RB___max_DL - conf.N__RB___DL
        #             k = 6*m + (v+v__shift) % 6
        #             #TODO:how to consider different serving cell?
        #             #consider primary cell only here.
        #             re = slot.rgs[0].re(k,l)
        #             res.append(re)
        #             re().p = self.p
        #             re().a = r__l_n__s[m___singleQuote]
        #             re().t = ReType('crs')
        # return res
        pass


    def _initPatch(self):
        """
        get pathPatches for plotting res for CRS of dedicate port
        :return:
        """
        codes = []
        vertices = []
        for re in self.res:
            codes += re().codes
            vertices += re().vertices

        path = Path(vertices, codes)
        patch = PathPatch(path, facecolor='white', edgecolor='black', linewidth=0.2, fill='none')
        patch.set_zorder(90)
        return patch, codes, vertices