classdef Staggered1d < grid.Structured
    properties 
        grids  % Cell array of grids
        Ngrids % Number of grids
        h      % Interior grid spacing
        d      % Number of dimensions
    end

    methods

        % Accepts multiple grids and combines them into a staggered grid
        function obj = Staggered1d(varargin)

            obj.d = 1;

            obj.Ngrids = length(varargin);
            obj.grids = cell(obj.Ngrids, 1);
            for i = 1:obj.Ngrids
                obj.grids{i} = varargin{i};
            end

            obj.h = [];
        end

        % N returns the total number of points
        function o = N(obj)
            o = 0;
            for i=1:obj.Ngrids
                o = o+obj.grids{i}.size();
            end
        end

        % D returns the spatial dimension of the grid
        function o = D(obj)
            o = obj.d;
        end

        % size returns the number of points on the primal grid
        function m = size(obj)
            m = obj.grids{1}.size();
        end

        % points returns an n x 1 vector containing the coordinates for all points.
        function X = points(obj)
            X = [];
            for i = 1:obj.Ngrids
                X = [X; obj.grids{i}.points()];
            end
        end

        % matrices returns a cell array with coordinates in matrix form.
        % For 2d case these will have to be transposed to work with plotting routines.
        function X = matrices(obj)

            % There is no 1d matrix data type in matlab, handle special case
            X{1} = reshape(obj.points(), [obj.m 1]);

        end

        function h = scaling(obj)
            if isempty(obj.h)
                error('grid:Staggered1d:NoScalingSet', 'No scaling set')
            end

            h = obj.h;
        end

        % Restricts the grid function gf on obj to the subgrid g.
        % Only works for even multiples
        function gf = restrictFunc(obj, gf, g)
            error('grid:Staggered1d:NotImplemented','This method does not exist yet')
        end

        % Projects the grid function gf on obj to the grid g.
        function gf = projectFunc(obj, gf, g)
            error('grid:Staggered1d:NotImplemented','This method does not exist yet')
        end

        % Return the names of all boundaries in this grid.
        function bs = getBoundaryNames(obj)
            switch obj.D()
                case 1
                    bs = {'l', 'r'};
                case 2
                    bs = {'w', 'e', 's', 'n'};
                case 3
                    bs = {'w', 'e', 's', 'n', 'd', 'u'};
                otherwise
                    error('not implemented');
            end
        end

        % Return coordinates for the given boundary
        function X = getBoundary(obj, name)
            % Use boundaries of first grid
            X = obj.grids{1}.getBoundary(name);
        end
    end
end