function mcodeConstructorLineSeries(hObj,hCode)
% Internal code generation method

% Generate code for "plot", "plot3", "loglog", & "semilog[x,y]"

% Copyright 2003-2004 The MathWorks, Inc.

% Flags used in code
is3D = ~isempty(get(hObj,'ZData'));
isVectorOutput = false;
hObjMomento = get(hCode,'MomentoRef');
ignoreProp = {};

% If 2-D plot, then see if other lineseries objects with the same parent 
% exist. Then check to see if they have the same xdata so we can consolidate
% the construction of many line handles into one call to plot as if 
% doing "plot(rand(20,20))". 
if ~is3D 
    
   % Get list of peer objects with the same parent. Momento objects
   % are created by the code generation engine and represent the object's
   % state which needs to be represented in code form.
   set(hObjMomento,'Ignore',true); 
   hParentMomento = up(hObjMomento);
   hPeerMomentoList = [];
   net_ydata = [];
   if ~isempty(hParentMomento)
       hPeerMomentoList = find(hParentMomento,'-depth',1);
       hObjPropertyList = get(hObjMomento,'PropertyObjects');
       hConstructMomentoList = hObjMomento;
       hConstructLineList = hObj;
       net_ydata = get(hObj,'YData')';
       xdata = get(hObj,'XData');
   end
   
   % Loop through peer momento objects
   for n = 2:length(hPeerMomentoList)
      hPeerMomento = hPeerMomentoList(n);
      hPeerObj = get(hPeerMomento,'ObjectRef');
      if isa(hPeerObj,'graph2d.lineseries')
          peer_xdata = get(hPeerObj,'XData');
      
          % If the momento object is a lineseries with the same 
          % xdata as this object.
          if ~isequal(hPeerObj,hObj) && ...
              ~get(hPeerMomento,'Ignore') && ...
              isequal(xdata,peer_xdata)

              % Add handle to list of constructor output handles 
              hConstructMomentoList = [hPeerMomento; hConstructMomentoList];
              hConstructLineList = [hPeerObj; hConstructLineList];
              net_ydata = [net_ydata,get(hPeerObj,'ydata')'];
              % Mark the monento to be ignored by the code generation engine 
              % since this momento object is already being 
              % created by this constructor
              set(hPeerMomento,'Ignore',true);
          
              % Constructor output is now a vector of handles
              isVectorOutput = true;
          end
      end
   end % for
    
end % if 
      
% Generate call to 'plot3', 'plot', 'loglog', 'semilogx', or 'semilogy'
constructor_name = 'plot';
if is3D
  constructor_name = 'plot3';
else
  hAxes = ancestor(hObj,'axes');
  is_logx = strcmpi(get(hAxes,'XScale'),'log');
  is_logy = strcmpi(get(hAxes,'YScale'),'log');
  
  % The axes mcodeConstructor method will ignore the XScale and YScale
  % properties if it is a simple log plot.
  if (is_logx && is_logy)
      constructor_name = 'loglog';      
  elseif (is_logx)
      constructor_name = 'semilogx';   
  elseif (is_logy)
      constructor_name = 'semilogy';
  else
      constructor_name = 'plot';
  end
end

% Specify constructor name
setConstructorName(hCode,constructor_name);

% Call helper function
plotutils('makemcode',hObj,hCode);

% Ignore source and display name
ignoreProp = {ignoreProp{:},'DisplayName','XDataSource','YDataSource'};

% Make 'XData' default input argument
ignoreProp = {ignoreProp{:},'XData','XDataMode'};
if strcmp(hObj.XDataMode,'manual')
   arg = codegen.codeargument('Name','X',...
                              'Value',hObj.XData,...
                              'IsParameter',true,...
                              'Comment','vector of x data');
   addConstructorArgin(hCode,arg);
end

% Make 'YData' default input argument
ignoreProp = {ignoreProp{:},'YData'};
arg = codegen.codeargument('Name','Y',...
                           'IsParameter',true);
if isVectorOutput  
  set(arg,'Value',net_ydata,'Comment','matrix of y data');
else
  set(arg,'Value',get(hObj,'Ydata'),'Comment','vector of y data');
end

addConstructorArgin(hCode,arg);

% If 3-D plot, make 'ZData' default input argument
if is3D
   ignoreProp = {ignoreProp{:},'ZData'};
   arg = codegen.codeargument('Name','Z',...
                           'Value',hObj.ZData,...
                           'IsParameter',true,...
                           'Comment','vector of z data');
   addConstructorArgin(hCode,arg);
end

% Ignore properties that were auto-generated
if strcmp(hObj.codeGenColorMode,'auto')
    ignoreProp = {ignoreProp{:},'Color'};
end
if strcmp(hObj.codeGenLineStyleMode,'auto')
    ignoreProp = {ignoreProp{:},'LineStyle'};
end
if strcmp(hObj.codeGenMarkerMode,'auto')
    ignoreProp = {ignoreProp{:},'Marker'};
end
      
% Ignore list of properties
ignoreProperty(hCode,ignoreProp);

% Output is a vector handle, input is a matrix 
if isVectorOutput
    
   % Customize output to be a vector handle 
   hFunc = getConstructor(hCode);
   hArg = codegen.codeargument('Value',hConstructLineList,...
                               'Name',get(hFunc,'Name'));
   addArgout(hFunc,hArg);
   
   % Let user know that the output is multiple line handles
   set(hFunc,'Comment',...
       ['%% Create mutliple lines using matrix input to ',constructor_name]);
   
   % Generate calls to "set" command
   local_generate_lineseries_set(hCode,hObj,...
             hConstructLineList,hConstructMomentoList);

% Output is a scalar handle 
else
   generateDefaultPropValueSyntax(hCode);
end

%----------------------------------------------------------%
function local_generate_lineseries_set(hCode,hObj,hConstructLineList,hConstructMomentoList)
% Generates a call to "set(...)" for every object in the input momento
% list.

% Loop through peer momento object list
for n = 1:length(hConstructMomentoList)
   hPeerMomento = hConstructMomentoList(n);
   hPeerObj = get(hPeerMomento,'ObjectRef');
   hPeerPropertyList = get(hPeerMomento,'PropertyObjects');
   hGenPropList = [];
           
   % Loop through properties, cache properties that are different
   for m = 1:length(hPeerPropertyList)
       
       if ~get(hPeerPropertyList(m),'Ignore')         
             
           % Get property info
           name = get(hPeerPropertyList(m),'Name');
           value = get(hPeerPropertyList(m),'Value');
           isparameter = get(hPeerPropertyList(m),'IsParameter');
           isignore = get(hPeerPropertyList(m),'Ignore');
           
           if ~isignore && ~isparameter    
               doFlag = true;          
                                
               % Don't flag if the property is auto-generated
               switch(lower(name))
                   case {'xdatamode','ydatemode','displayname','ydatasource','xdatasource'}
                       doFlag = false;
                   case 'color'
                       if strcmp(get(hPeerObj,'codeGenColorMode'),'auto')
                           doFlag = false;
                       end
                    case 'marker'
                        if strcmp(get(hPeerObj,'codeGenMarkerMode'),'auto')
                           doFlag = false;
                        end
                    case 'linestyle'
                        if strcmp(get(hPeerObj,'codeGenLineStyleMode'),'auto')
                           doFlag = false;
                        end
                    otherwise
                        doFlag = true;
                end % switch
                
                % Save this property and value for code generation
                if doFlag
                    hGenPropList = [hGenPropList;hPeerPropertyList(m)];
                end
                
           end % if
           
       end % if
   end % for
                  
   % Generate code for properties
   if length(hGenPropList) > 0
       local_generate_lineseries_set_args(hCode,hPeerObj,hGenPropList);
   end
           
end % for
   
%----------------------------------------------------------%
function local_generate_lineseries_set_args(hCode,hObj,hGenPropList)
% Generate arguments to "set(...)"

% Generate call to "set(...)" for input 
hFunc = codegen.codefunction('Name','set','CodeRef',hCode);
addPostConstructorFunction(hCode,hFunc);

% Create first input argument: line handle
hArg = codegen.codeargument('Value',hObj,'IsParameter',true); 
addArgin(hFunc,hArg); % method

% Generate param-value syntax
generatePropValueList(hFunc,hGenPropList);



