classdef pins < handle & matlab.mixin.SetGet & matlab.mixin.Copyable & matlab.mixin.CustomDisplay
% pins creates the pins object w.r.t the InputType in the board.
%
% p = pins(pobj) creates the pins object which takes pcbFileRead as input 
% and returns the pins of the respective InputType in the board. 
% 
% p = pins(pobj,'Cadnet','Cadnetname') takes pcbFileRead as input and 
% creates the pins object w.r.t. the Cadnetname.
%
% p = pins(pobj,'Layer',1) takes pcbFileRead as an input and creates the
% pins object for the 1st metal layer.
%
% p = pins(pobj,'Layer','LayerName') takes pcbFileRead and creates 
% the pins object w.r.t. the LayerName.
%
% pins properties:
%
%   pcBoard       - pcbFileRead object.
%   InputType     - Type of the input to get the pins. The choices
%                   are 'Layer' or 'Cadnet'. 
%                   The default InputType is 'layer'. 
%   NumPins       - Number of pins w.r.t the InputType.
%   NumComponents - Number of components w.r.t the InputType.
%   NumParts      - Number of parts w.r.t the InputType.
%
%   If InputType = 'Layer'
%   LayerNumber  - Index/Position of the layer numeber in the stack. It 
%                  accepts the scalar value. The default layer number is
%                  first metal layer in the stack.
%   or
%
%   LayerName    - Name of the layer in the stack. It accepts the string.   
%   PinInfo      - Info table of the pins in a respective layer. Returns the
%                  table with below fields.                 
%
%   If InputType = 'Cadnet'
%   CadnetName   - Name of the cadnet. 
%   PinInfo      - Info table of the pins of a respective cadnet. Returns
%                  the table with below fields.
%                  PinIndex       : The index of each pin in a cadnet.
%                                   Max(PinIndex) is the count of pins in 
%                                   a cadnet.
%                  ComponentName  : Name of the component.
%                  PinNumber      : Pin Number of the component.
%                  ComponentType  : Type of the component.
%                  Value          : Value of the component.
%                  PartName       : Part name.
%                  PadStackName   : name of the padstack.
%                  LayerName      : layer name.
%                  LayerNumber    : layer number.
%
%
% pins methods:
%   
%   shapes       - Returns the shape of the pins w.r.t the InputType
%   pinData      - Returns the data of the pin w.r.t the InputType
%

%   Copyright 2023 The MathWorks, Inc.
  
    properties(SetObservable)
        % pcbFileRead object.
        pcBoard
        % Type of the input to return the pins
        InputType
        % Layer number
        LayerNumber
        % Layer name
        LayerName
        % Cadnet name 
        CadnetName
    end

    properties(SetAccess=protected, GetAccess = public)
        % Number of pins.
        NumPins
        % Number of components.
        NumComponents
        % Number of parts.
        NumParts
    end

    properties(Access=private)
        LayerNumFlag
    end

    % properties (Access=private)
    %     hUiTable
    %     hUiTableFig
    %     hTab
    %     hTable
    %     SearchCompName
    %     SearchPartName
    %     SearchTable
    % end

    properties(SetAccess = private, GetAccess = public)
        % Info table of the pin w.r.t the InputType.
        PinInfo
    end

    methods
        function obj = pins(pcBoard,InputType,value)
           parserObj = inputParser;

            % add parameters
            addRequired(parserObj,'pcBoard');
            addRequired(parserObj,'InputType');
           
            if strcmpi(InputType,'Layer')
                if isstring(value) || ischar(value)
                   addOptional(parserObj,'LayerName',value);
                else
                   addOptional(parserObj,'LayerNumber',value);
                end
            elseif strcmpi(InputType,'Cadnet')
                addOptional(parserObj,'CadnetName',value);
            end

            % parse the input
            parse(parserObj,pcBoard,InputType);
            obj.pcBoard        = pcBoard;
            if strcmpi(InputType,'Layer')
                if isstring(value) || ischar(value)
                    obj.LayerName     = parserObj.Results.LayerName;
                    getLayerNumber(obj,value);
                else
                    obj.LayerNumber     = parserObj.Results.LayerNumber;
                    getLayerName(obj,value);
                    obj.LayerNumFlag = 1;
                end
            elseif strcmpi(InputType,'Cadnet')
                obj.CadnetName         = parserObj.Results.CadnetName;
            end
            obj.InputType = InputType;
        end

        function set.pcBoard(obj,propval)
            if ~isa(propval,'pcbFileRead')
                error(message('rfpcb:rfpcberrors:Unsupported','This input',...
                    'pcBoard. Supported input is pcbFileRead object'));
            end
            if isPropertyChanged(obj,obj.pcBoard,propval)
                obj.pcBoard =  propval;
            end
        end

        function set.InputType(obj,propval)
            if ~isempty(propval)
                validatestring(propval,{'Layer','Cadnet'}, ...
                    class(obj),'InputType');
                if isPropertyChanged(obj,obj.InputType,propval)
                    if isstring(propval)
                        propval = char(propval);
                    end
                    obj.InputType =  propval;
                    CreatePinInfo(obj);
                end
            end
        end

        function set.LayerName(obj,propval)
            mustBeNonempty(propval);
            if ~isempty(propval)   
                validateLayerName(obj,propval);
                if isPropertyChanged(obj,obj.LayerName,propval)
                    if isstring(propval)
                        propval = char(propval);
                    end
                    obj.LayerName =  propval;
                    getLayerNumber(obj,obj.LayerName);
                    UpdatePinProp(obj);
                end
            end
        end

        function set.LayerNumber(obj,propval)
            mustBeNonempty(propval);
            if ~isempty(propval)
                % validate the input Layer number
                validateLayerNumber(obj,propval);
                if isPropertyChanged(obj,obj.LayerNumber,propval)
                    obj.LayerNumber =  propval;
                    getLayerName(obj,obj.LayerNumber);
                    UpdatePinProp(obj);
                end
            end
        end

        function set.CadnetName(obj,propval)
            mustBeNonempty(propval);
            if ~isempty(propval)
                if ~((ischar(propval) || isStringScalar(propval)) && strlength(propval) > 0)
                    error(message('rfpcb:rfpcberrors:PCBNameNotString','CadnetName'));
                end
                validateCadnetName(obj,propval)
                if isPropertyChanged(obj,obj.CadnetName,propval)
                    if isstring(propval)
                        propval = char(propval);
                    end
                    obj.CadnetName =  propval;
                    UpdatePinProp(obj);
                end
            end
        end

        function propVal = get.NumPins(obj)
            if strcmpi(obj.InputType,'Layer')
                Lnum = int32(obj.LayerNumber);
                pinCount = getLayerPinsCount(Lnum);
            elseif strcmpi(obj.InputType,'Cadnet')
                Cadname = obj.CadnetName;
                pinCount = getCadnetPinsCount(Cadname);
            end
            propVal = pinCount;
        end

        function propVal = get.NumComponents(obj)
            if strcmpi(obj.InputType,'Layer')
                Lnum = int32(obj.LayerNumber);
                pinCount = getLayerPinsCount(Lnum);
                % Pin Index
                PinIndex = 1:pinCount;
                CompName  = arrayfun(@(x)  getLayerPinData(Lnum,x).refdesName,int32(PinIndex),'UniformOutput',false)';
                NumComp = length(unique(CompName));
            elseif strcmpi(obj.InputType,'Cadnet')
                Cadname = obj.CadnetName;
                pinCount = getCadnetPinsCount(Cadname);
                % Pin Index
                PinIndex = 1:pinCount;
                CompName  = arrayfun(@(x)  getCadnetPinData(Cadname,x).refdesName,int32(PinIndex),'UniformOutput',false)';
                NumComp = length(unique(CompName));
            end
            propVal = NumComp;
        end

        function propVal = get.NumParts(obj)
            if strcmpi(obj.InputType,'Layer')
                LayerN = int32(obj.LayerNumber);
                pinCount = getLayerPinsCount(LayerN);
                % Pin Index
                PinIndex = 1:pinCount;
                PartNum = arrayfun(@(x)  getLayerPinData(LayerN,x).partNumberName,int32(PinIndex),'UniformOutput',false)';
                NumPar = length(unique(PartNum));
            elseif strcmpi(obj.InputType,'Cadnet')
                Cadname = obj.CadnetName;
                pinCount = getCadnetPinsCount(Cadname);
                % Pin Index
                PinIndex = 1:pinCount;
                PartNum = arrayfun(@(x)  getCadnetPinData(Cadname,x).partNumberName,int32(PinIndex),'UniformOutput',false)';
                NumPar = length(unique(PartNum)); 
            end
            propVal = NumPar;
        end
    end

    methods (Hidden)
        function UpdatePinProp(obj)
            if ~isempty(obj.InputType)
                prop = get(obj);
                CreatePinInfo(obj);
            end
        end

        function validateLayerName(obj,propval)
            mLnum = obj.pcBoard.MetalLayer;
            mLname = stackUp(obj.pcBoard,mLnum).LayerName;
            mustBeMember(propval,mLname);
        end

        function validateCadnetName(obj,propval)
            mCnetName = cadnetList(obj.pcBoard).CadnetList;
            mustBeMember(propval,mCnetName);
        end

        function validateLayerNumber(obj,propval)
            mLnum = obj.pcBoard.MetalLayer;
            mustBeMember(propval,mLnum);
        end

        function LNum = getLayerNumber(obj,LName)
            stack = stackUp(obj.pcBoard,obj.pcBoard.MetalLayer);
            Lind = strcmpi(stack.LayerName,LName);
            LNum = stack.LayerNumber(Lind);
            obj.LayerNumber = LNum;
        end

        function LName = getLayerName(obj,LNum)
            stack = stackUp(obj.pcBoard,obj.pcBoard.MetalLayer);
            Lind = find(stack.LayerNumber(:,1)==LNum);
            LName = stack.LayerName(Lind);
            LName = LName{1};
            obj.LayerName = LName;
        end

        function CreatePinInfo(obj)
            if strcmpi(obj.InputType,'Layer')
                % Get the pin data for the given layer.
                Lnum = int32(obj.LayerNumber);
                pinCount = getLayerPinsCount(int32(Lnum));
                % Pin Index
                PinIndex = 1:pinCount;
                % Get the component Name for the given layer
                CompName  = arrayfun(@(x)  getLayerPinData(Lnum,x).refdesName,int32(PinIndex),'UniformOutput',false)';
                % Get Component Pin Number for the given layer
                PinNum  = arrayfun(@(x)  getLayerPinData(Lnum,x).pinNumber,int32(PinIndex),'UniformOutput',false)';
                % Component Type (get from praveen)
                CompType = arrayfun(@(x)  getLayerPinData(Lnum,x).pinNumber,int32(PinIndex),'UniformOutput',false)';
                % Component value (get from praveen)
                CompValue = arrayfun(@(x)  getLayerPinData(Lnum,x).value,int32(PinIndex),'UniformOutput',false)';
                % Get the PartName for the given layer
                PartNum = arrayfun(@(x)  getLayerPinData(Lnum,x).partNumberName,int32(PinIndex),'UniformOutput',false)';
                % PadStackName
                PadStackN = arrayfun(@(x)  getLayerPinData(Lnum,x).padstackName,int32(PinIndex),'UniformOutput',false)';
                % Cadnet Name
                CadNname = arrayfun(@(x)  getLayerPinData(Lnum,x).cadnetName,int32(PinIndex),'UniformOutput',false)';
                % Variable names.
                varNames = {'PinIndex','ComponentName','PinNumber','ComponentType','Value','PartName','PadStackName','CadnetName'} ;
                obj.PinInfo = table(PinIndex',CompName,PinNum,CompType,CompValue,PartNum,PadStackN,CadNname);
             
            elseif strcmpi(obj.InputType,'Cadnet')
                Cname = obj.CadnetName;
                pinCount = getCadnetPinsCount(Cname);
                % Pin Index
                PinIndex = 1:pinCount;
                % Get the component Name for the given cadnet
                CompName  = arrayfun(@(x)  getCadnetPinData(Cname,x).refdesName,int32(PinIndex),'UniformOutput',false)';
                % Get Component Pin Number for the given cadnet
                PinNum  = arrayfun(@(x)  getCadnetPinData(Cname,x).pinNumber,int32(PinIndex),'UniformOutput',false)';
                % Component Type (get from praveen)
                CompType = arrayfun(@(x)  getCadnetPinData(Cname,x).pinNumber,int32(PinIndex),'UniformOutput',false)';
                % Component value (get from praveen)
                CompValue = arrayfun(@(x)  getCadnetPinData(Cname,x).value,int32(PinIndex),'UniformOutput',false)';
                % Get the PartName for the given cadnet
                PartNum = arrayfun(@(x)  getCadnetPinData(Cname,x).partNumberName,int32(PinIndex),'UniformOutput',false)';
                % PadStackName
                PadStackN = arrayfun(@(x)  getCadnetPinData(Cname,x).padstackName,int32(PinIndex),'UniformOutput',false)';
                % Start Layer Name
                StartLname = arrayfun(@(x)  getCadnetPinData(Cname,x).startLayerName,int32(PinIndex),'UniformOutput',false)';
                % Stop Layer Name
                StopLname = arrayfun(@(x)  getCadnetPinData(Cname,x).endLayerName,int32(PinIndex),'UniformOutput',false)';
                % start Layer Number
                StartLNum = cell2mat(arrayfun(@(x)  getCadnetPinData(Cname,x).startLayerNumber,int32(PinIndex),'UniformOutput',false))';
                % stop Layer Number
                StopLNum = cell2mat(arrayfun(@(x)  getCadnetPinData(Cname,x).endLayerNumber,int32(PinIndex),'UniformOutput',false))';
                % Variable names.
                varNames = {'PinIndex','ComponentName','PinNumber','ComponentType','Value','PartName','PadStackName','StartLayerName','StartLayerNumber','StopLayerName','StopLayerNumber'} ;
                obj.PinInfo = table(PinIndex',CompName,PinNum,CompType,CompValue,PartNum,PadStackN,StartLname,StartLNum,StopLname,StopLNum);
            end
            obj.PinInfo.Properties.VariableNames = varNames;
        end

        function  PcbPins = createGeometry(obj,varargin)
            Pincount = obj.NumPins;
            if(Pincount > 0)
                pinIdx = 1:Pincount;
                PcbPin = arrayfun(@(x) drawPin(obj,x),pinIdx);
            else
                PcbPin = [];
            end
            PcbPins = PcbPin;
        end
        function S = shapes(obj)
            %shapes returns all the shapes of the pins w.r.t InputType.
            %
            % S = shapes(obj) returns the shapes of the pins w.r.t InputType.
            %

            % Copyright 2023 The MathWorks, Inc.

            poly = createGeometry(obj);
            npoly = numel(poly);
            S = cell(npoly,1);
            for i = 1:npoly
                S{i} = poly(i);
            end
        end
        function pinD = pinData(obj,PinInd)
            % pinData returns the pinsdata object of a respective pin w.r.t
            % the InputType. 
            %
            % pinD = pinData(obj,PinInd) returns the data of the respective
            % pin w.r.t the InputType.
            %
            %   Input Arguments:
            %
            %       obj         : pin object.
            %       PinInd      : pin index of the pins w.r.t the
            %                     InputType. It accepts scalar or vector
            %                     values.
            %  
            %   Output Arguments:
            %  
            %       pinD : Returns the data of pin w.r.t the InputType 

            % Copyright 2023 The MathWorks, Inc.

            arguments
                obj(1,1)  pins
                PinInd {mustBeNumeric,...
                    mustBeNonNan,mustBeFinite,mustBeInteger,...
                    mustBePositive,mustBeValidPin(obj,PinInd)}=obj.PinInfo.PinIndex;
            end
            Npins = length(PinInd);
            if Npins==1
                pinD = pinsData(obj,PinInd);
            else
                for i = 1:Npins
                    pinD{i} = pinsData(obj,PinInd(i));
                end
                pinD = pinD';
            end
        end
    end

    methods(Hidden)
        function PinPoly = drawPin(obj,pinIdx)

            orig_state = warning;
            warning('off','MATLAB:polyshape:boundary3Points');
            % Create the pin polygons
            PinpolygonVertices = [nan,nan];
            Pinseparator = [nan,nan];
            if strcmpi(obj.InputType,'Layer')
                Layername = obj.LayerName;
                LayerNum = obj.LayerNumber;
                CadnetN= arrayfun(@(x) obj.PinInfo.CadnetName{x},pinIdx,'UniformOutput',false);
                [xValues, yValues, ~, ~] = getLayerPinPolygonData(int32(LayerNum),int32(pinIdx));
            elseif strcmpi(obj.InputType,'Cadnet')
                Layername = arrayfun(@(x) obj.PinInfo.StartLayerName{x},pinIdx,'UniformOutput',false);
                LayerNum = cell2mat(arrayfun(@(x) obj.PinInfo.StartLayerNumber(x),pinIdx,'UniformOutput',false));
                CadnetN = obj.CadnetName;
                [xValues, yValues, ~, ~] = getCadnetPinPolygonData(CadnetN, int32(pinIdx));
          
            end

            % Pin polygon
            pinVertices = [xValues(:), yValues(:)];
            pinPolygonVertices = [PinpolygonVertices; Pinseparator; pinVertices];
            PinPoly = antenna.Polygon("Vertices",pinPolygonVertices);
            
            % Tooltip
            Cname = strrep(CadnetN, '_', '\_');
            ToolTip = ['Pin',newline, 'Cadnet: ' char(Cname) ,newline, 'LayerName: ' char(Layername) ,newline, 'LayerNum: ' num2str(LayerNum)];
            PinPoly.Name = ToolTip;
            warning(orig_state);
        end

        function tf = isPropertyChanged(~,val1,val2)
            % Check if property values are different
            if isempty(val1)        % During constructor call
                tf = true;
            else
                tf = ~isequal(val1,val2);
            end
        end

    end

    methods(Hidden)
        % function out = search(obj,options)
        % 
        %     arguments
        %         obj
        %         options.Component
        %         options.Part
        %         %options.PartName (1,:) {mustBeA(Name,{'char','string'}), mustBeValidSearchName(obj,Name)
        %         options.Layer
        %         options.ComponentType (1,:) string
        %         options.Value (1,1) double
        %     end
        %     obj.SearchTable = obj.PinInfo;
        %     Pindata = obj.SearchTable;
        %     % if obj.SearchCompName
        %     %     idxComp = matches(Pindata.ComponentName,SearchName);
        %     %     obj.SearchTable = Pindata(idxComp,:);
        %     % elseif obj.SearchPartName
        %     %     idxComp = matches(Pindata.PartName,SearchName);
        %     %     obj.SearchTable = Pindata(idxComp,:);
        %     % end
        % 
        %     if isfield(options,'Layer')
        %         pcbL = upper(options.Layer);
        %         if isa(pcbL,"string") ||  isa(pcbL,"char")
        %             mustBeMember(cellstr(upper(pcbL)),Pindata.LayerName)
        %             idxLayer = matches(Pindata.LayerName,pcbL);
        %         elseif isa(pcbL,"double")
        %             mustBeMember(options.Layer,Pindata.LayerName)
        %             idxLayer = matches(Pindata.LayerNumber,pcbL);
        %         end
        %         searchL = Pindata;
        %         obj.SearchTable = searchL(idxLayer,:);
        %     end
        % 
        %     if isfield(options,'Part')
        %         Pname = options.Part;
        %         mustBeMember(Pname,Pindata.PartName)
        %         searchTp = obj.SearchTable;
        %         idxPart = matches(searchTp.PartName,Pname);
        %         obj.SearchTable = searchTp(idxPart,:);
        %         % Search for the respective component
        %     end
        % 
        %     if isfield(options,'Component')
        %         Cname = options.Component;
        %         mustBeMember(Cname,Pindata.ComponentName)
        %         searchTc = obj.SearchTable;
        %         idxComp = matches(searchTc.ComponentName,Cname);
        %         obj.SearchTable = searchTc(idxComp,:);
        %         % Search for the respective component
        %     end
        % 
        %     % if isfield(options,'LayerNumber')
        %     %     mustBeMember(options.Vendor,obj.Vendor)
        %     %     vendors = options.Vendor;
        %     %     idxVendor = matches(obj.Vendor,options.Vendor,IgnoreCase=true);
        %     %     vendorXMLs = obj.xmlVendor(idxVendor);
        %     % else
        %     %     vendors = obj.Vendor;
        %     %     vendorXMLs = obj.xmlVendor;
        %     % end
        % 
        %     % if isfield(options,'Value')
        %     %     mustBeMember(options.Type,obj.Type)
        %     %     idx = find(obj.Availability(matches(obj.Vendor,vendors),...
        %     %         matches(obj.Type,options.Type)));
        %     %     vendors = obj.Vendor(idx);
        %     %     vendorXMLs = obj.xmlVendor(idx);
        %     % else
        %     %     options.Type = obj.Type;
        %     % end
        %     if nargout ==0
        %         pinD = obj.SearchTable;
        %         createUITable(obj,pinD)
        %     else
        %         out = obj.SearchTable;
        %     end
        % end
        % 
        % function createUITable(obj,pinD)
        %     pos = get(0,'defaultFigurePosition');
        %     fig = figure( ...
        %         'Name', 'Pins', ...
        %         'MenuBar', 'none', ...
        %         'Position', pos, ...
        %         'Tag', 'pinSearchTable', ...
        %         'NumberTitle', 'off');
        %     obj.hUiTableFig = fig;
        %     createFigureTab(obj,pinD);
        % end
        % 
        % function createFigureTab(obj,pinD)
        %     % Create Tabbed panel
        %     % pos = obj.hUiTableFig.Position;
        %     % First table
        %     tg = uitabgroup(obj.hUiTableFig);
        %     obj.hTab = uitab(tg,'Title','Search Results');
        %     obj.hTable = pinD;
        %     createTabTable(obj);
        % 
        %     % Second table
        %     obj.hTab = uitab(tg,'Title','PinInfo');
        %     obj.hTable = obj.PinInfo;
        %     createTabTable(obj);
        % end
        % 
        % function createTabTable(obj)
        %     pos = get(0,'defaultFigurePosition');
        %     pos(1:2) = [20 20];
        %     pos(3) = pos(3)-50;
        %     pos(4) = pos(4)-50;
        %     data = table2cell(obj.hTable);
        %     name = obj.hTable.Properties.VariableNames;
        % 
        %     obj.hUiTable = uitable( ...
        %         'Parent', obj.hTab, ...
        %         'Data', data, ...
        %         'ColumnName', name, ...
        %         'ColumnEditable', false, ...
        %         'Position', pos);
        % end

    end

    methods(Access=protected)
        function group = getPropertyGroups(obj)
            title = '';
            if strcmpi(obj.InputType,'Layer')
                if obj.LayerNumFlag==1
                    p = {'pcBoard','InputType','LayerNumber','NumPins','NumComponents','NumParts','PinInfo'};
                else
                    p = {'pcBoard','InputType','LayerName','NumPins','NumComponents','NumParts','PinInfo'};
                end
                group = objectProps(obj,p,title);
            elseif strcmpi(obj.InputType,'Cadnet')
                p = {'pcBoard','InputType','CadnetName','NumPins','NumComponents','NumParts','PinInfo'};
                group = objectProps(obj,p,title);
            end
        end

        function group = objectProps(obj, propertyDisplayList,title)
            propList    = properties(obj);
            numProps    = max(size(propertyDisplayList));
            for i = 1:numProps
                if(strcmpi(propertyDisplayList{i},propList(strcmpi(propertyDisplayList{i},propList))))
                    antennaProps.(char(propertyDisplayList{i})) = get(obj,propertyDisplayList{i});
                end
            end
            group = matlab.mixin.util.PropertyGroup(antennaProps,title);
        end

    end

end

function mustBeValidPin(PinObj,value)
pinInd = value;
PinIndExp = PinObj.PinInfo.PinIndex;
if any(pinInd==PinIndExp)
    value = value;  %#ok<ASGSL>
else
    eid = 'Value:notValid';
    msg = ['Value must be among the PinIndex of pins, expected value/s are: ', num2str(PinIndExp')];
    throwAsCaller(MException(eid,msg));
end
end

% function mustBeValidSearchName(obj,Name)
% tf_comp = obj.SearchCompName;
% tf_part = obj.SearchPartName;
% 
% PinTab = obj.PinInfo;
% ExpCompName = PinTab.ComponentName;
% ExpPartName = PinTab.PartName;
% 
% % Check if the searchName is Component/part Name and enable the search flag
% tfc = all(ismember(Name, ExpCompName), 'all');
% tfp = all(ismember(Name, ExpPartName), 'all');
% if tfc== 1
%     obj.SearchCompName = 1;
%     obj.SearchPartName = 0;
% elseif tfp==1
%     obj.SearchPartName = 1;
%     obj.SearchCompName = 0;
% else
%     % Validate the Search Name
%     % searchName should be a componet or a part name
%     ExpName = [ExpCompName;ExpPartName];
%     mustBeMember(Name,ExpName);
% end
% end

% function mustBeValidLayerName(pboard,value)
% LayerName = value;
% Lid= int32([pboard.MetalLayer(1,1),pboard.MetalLayer(1,end)]);
% LayerN= arrayfun(@(x) getLayerName(x),Lid,'UniformOutput',false);
% LayerNameExp = LayerN;
%
% if ~isempty(LayerName)
%     mustBeMember(upper(LayerName),LayerNameExp);
%     % if any(LayerNum==LayerNameExp)
%     %     value = value;  %#ok<ASGSL>
%     % else
%     %     eid = 'Value:notValid';
%     %     msg = ['Value in LayerNumber must be among the metal Layer, expected value/s are: ', num2str(LayerNumExp)];
%     %     throwAsCaller(MException(eid,msg));
%     % end
% end
%end
