"""
Reference-physical domain mappings.
"""
import numpy as nm

from sfepy.base.base import Struct

class PhysicalQPs(Struct):
    """
    Physical quadrature points in a region.
    """

    def __init__(self, igs, n_total=0, is_uniform=True):
        Struct.__init__(self, igs=igs, n_total=n_total, indx={}, rindx={},
                        n_per_group={}, shape={}, values={},
                        is_uniform=is_uniform)
        for ig in self.igs:
            self.indx[ig] = slice(None)
            self.rindx[ig] = slice(None)
            self.n_per_group[ig] = 0
            self.shape[ig] = (0, 0, 0)
            self.values[ig] = nm.empty(self.shape[ig], dtype=nm.float64)

    def get_merged_values(self):
        qps = nm.concatenate([self.values[ig] for ig in self.igs], axis=0)

        return qps

    def get_shape(self, rshape, ig=None):
        """
        Get shape from raveled shape.
        """
        if ig is None:
            if self.is_uniform:
                n_qp = self.shape[self.igs[0]][1]

            else:
                msg = 'ig argument must be given for non-uniform QPs!'
                raise ValueError(msg)

        else:
            n_qp = self.shape[ig][1]

        if (rshape[0] / n_qp) * n_qp != rshape[0]:
            raise ValueError('incompatible shapes! (n_qp: %d, %s)'
                             % (n_qp, rshape))

        shape = (rshape[0] / n_qp, n_qp) + rshape[1:]

        return shape

class Mapping(Struct):
    """
    Base class for mappings.
    """

    @staticmethod
    def from_args(region, kind='v', ig=None):
        """
        Create mapping from reference to physical entities in a given
        region, given the integration kind ('v' or 's').

        This mapping can be used to compute the physical quadrature
        points.

        Parameters
        ----------
        region : Region instance
            The region defining the entities.
        kind : 'v' or 's'
            The kind of the entities: 'v' - cells, 's' - facets.
        ig : int, optional
            The group index.

        Returns
        -------
        mapping : VolumeMapping or SurfaceMapping instance
            The requested mapping.
        """
        from sfepy.discrete.fem.domain import FEDomain
        from sfepy.discrete.iga.domain import IGDomain

        if isinstance(region.domain, FEDomain):
            import sfepy.discrete.fem.mappings as mm
            coors = region.domain.get_mesh_coors()
            if kind == 's':
                coors = coors[region.vertices]

            gel = region.domain.groups[ig].gel
            conn = region.domain.groups[ig].conn

            if kind == 'v':
                cells = region.get_cells(ig)

                mapping = 
mm.VolumeMapping(coors, conn[cells], gel=gel)