function out=_mainPlot(typeOfPlot,argList,varargin)

global prefViewType reqMatrixArgs defaultFigureUserData defaultAxesUserData defaultLeafUserData IMD MAXCOL

win=get('current_figure');
currentAxes=get('current_axes');
IMD=win.immediate_drawing;
win.immediate_drawing='off';

if typeof(argList(1))=='pltlibH'
  if argList(1).handle.type=='Axes'  // plotlib axes graphic handle
    currentAxes=argList(1).handle;
    argList(1)=null();
  else
    _error(sprintf('%s : handle should be an axes handle',typeOfPlot));
  end
elseif currentAxes.user_data.nextPlot=='erase'
 _cla('reset');
end

 
previous_view=currentAxes.view
currentAxes.visible='on';

_start=1;

hdl=[];
data_bounds=%inf*[1 -1 1 -1 1 -1];
_axes_ppty_value_list=list();

x_scale='n';
y_scale='n';

if currentAxes.user_data.nextPlot=='add'
   currentView=currentAxes.view;
end

while _start <= length(argList)
  _ref_size=[];
  _found_a_string=0;
  for i=_start:length(argList) // finding the number of matrix/function args
     _type(i)=type(argList(i));
     if _type(i)==10
        _found_a_string=1;
         break
     else
         _checkTypeAndDimensions(argList(i),i,typeOfPlot,[1,13]);
     end
  end

  _e=defaultLeafUserData;
  _e.typeOfPlot=typeOfPlot;
  _e.parent=currentAxes;
  _a=defaultAxesUserData;
  
  _first=_start;
  _last=i-_found_a_string;
  nb_matrix_args=_last-_first+1;
  
  if nb_matrix_args > 0 // XData, YData,... mode => nb_matrix_args == 0

    if or(typeOfPlot==['plot';'semilogx';'semilogy';'loglog']) & nb_matrix_args > 1
      _last=_start+1;
      nb_matrix_args=2;
    elseif typeOfPlot=='plot3' & nb_matrix_args > 3
      _last=_start+2;
      nb_matrix_args=3;
    end
    
    _without_xy=or(nb_matrix_args==reqMatrixArgs(typeOfPlot)(1,:)) & (size(reqMatrixArgs(typeOfPlot),1)==2);
    
    _with_opt_arg=%f;
    if size(reqMatrixArgs(typeOfPlot),2)==2
      _with_opt_arg=or(nb_matrix_args==reqMatrixArgs(typeOfPlot)(:,2)); // Optional argument is used
    end

    _matrix_args=_first:_last;

    if and(nb_matrix_args~=reqMatrixArgs(typeOfPlot)) // Checking the total number of arguments
      _errorText=string(reqMatrixArgs(typeOfPlot)(1));
      for i=2:length(reqMatrixArgs(typeOfPlot))-1
          _errorText=_errorText+', '+string(reqMatrixArgs(typeOfPlot)(i))
      end
      if length(reqMatrixArgs(typeOfPlot))>1
          _errorText=_errorText+' or '+string(reqMatrixArgs(typeOfPlot)($));
      end
      _error(sprintf('%s : expecting %s matrix arguments',typeOfPlot,_errorText));
    end

    if or(typeOfPlot==['triplot';'trimesh';'tripcolor';'trisurf';'trisurfl']); // Connectivity matrix
      _checkTypeAndDimensions(argList(_start),_start,typeOfPlot,1,[3,-1]);
     _start=_start+1;
    end

    if or(typeOfPlot==['mesh';'pcolor';'surf';'surfl';'image'])
      if _without_xy // no (_X,_Y) pair
        _checkTypeAndDimensions(argList(_start),_start,typeOfPlot,1);
        _ref_size=size(argList(_start)); // size of _Z
       _start=_start+1;
      elseif _type(_start:_start+1)==1
        if isvector(argList(_start)) & isvector(argList(_start+1)) //(_X,_Y) pair but vector type
           _ref_size=[length(argList(_start+1)),length(argList(_start))]; // size of meshgrid(_X,_Y)
           _start=_start+2;
        end      
      end
    elseif or(typeOfPlot==['quiver';'quiver3'])
      if _without_xy // no (_X,_Y) pair
        _checkTypeAndDimensions(argList(_start),_start,typeOfPlot,1);
        _ref_size=size(argList(_start)); // size of _Z
       _start=_start+1;
      end
    elseif or(typeOfPlot==['plot';'semilogx';'semilogy';'loglog'])
      if _without_xy // no _X
        _checkTypeAndDimensions(argList(_start),_start,typeOfPlot,1);
        _ref_size=size(argList(_start)); // size of _Y
       _start=_start+1;
      elseif _type(_start:_start+1)==1
        if isvector(argList(_start)) & ~isvector(argList(_start+1))
          if or(length(argList(_start))==size(argList(_start+1)))
            _ref_size=size(argList(_start+1));
            _start=_start+2;
          end
        end
      end
    end
     
    if _ref_size==[]
       _checkTypeAndDimensions(argList(_start),_start,typeOfPlot,1);
       _ref_size=size(argList(_start));
       _checkTypeAndDimensions(argList(_start+1),_start+1,typeOfPlot,1,_ref_size); // All other cases : parse (_X,_Y) of same size
       _start=_start+2;
    end

    for i=_start:_last
         
        if _with_opt_arg & or(typeOfPlot==['quiver';'quiver3']) & i==_last // looking for field factor
    
           _checkTypeAndDimensions(argList(i),i,typeOfPlot,1,[1,1]);
           
        elseif _with_opt_arg & or(typeOfPlot==['surfl']) & i==_last // looking for light vector
    
           _checkTypeAndDimensions(argList(i),i,typeOfPlot,1,[1,3;3,1;1,2;2,1]);
           
        elseif _with_opt_arg & or(typeOfPlot==['image']) & i==_last // CLim spec
          
           _checkTypeAndDimensions(argList(i),i,typeOfPlot,1,[1,2;2,1]);
        
        elseif or(typeOfPlot==['fill';'fill3']) & i==_last // vector or matrix for the color
          
           _checkTypeAndDimensions(argList(i),i,typeOfPlot,1,[1,_ref_size(2);_ref_size]);

        elseif or(typeOfPlot==['tripcolor';'trisurf']) & i==_last // vector or matrix for the color
          
           _checkTypeAndDimensions(argList(i),i,typeOfPlot,1,[1,size(argList(1),2);_ref_size]);
                                
        elseif _type(i)==1 // matrix with size of _X
           
           if typeOfPlot <> 'image' 
             _checkTypeAndDimensions(argList(i),i,typeOfPlot,1,_ref_size);
           end

//        elseif _type(i)==13 & ~ _without_xy // Scilab function
//          [nArgOut1,vectInput]=check3dFun(typeOfPlot,argList(i),argList(_first),argList(_first+1));
//          if ~vectInput | (nArgOut1~=1 & nArgOut1~=3)
//              _error(sprintf('%s : function must return 1 or 3 output arguments and accept matrix inputs',typeOfPlot));
//          end
        
        else
     
          _error(sprintf('%s : expecting 2 matrix arguments before function',typeOfPlot));

        end 
       
     end
     
    _start=_last+1;
   
    if or(typeOfPlot==['plot';'semilogx';'semilogy';'loglog'])

      if _without_xy
          _e.YData=argList(_matrix_args(1));
          if isvector(_e.YData)
            _e.YData=_e.YData(:);
          end
          _e.XData=1:size(_e.YData,1);
      else
          [_e.XData,_e.YData]=argList(_matrix_args(1:2));
          if isvector(_e.YData)
            _e.YData=_e.YData(:);
          end
      end
      if isvector(_e.XData)
          _e.XData=_e.XData(:);
          if length(_e.XData)==size(_e.YData,2)
             _e.YData=_e.YData';
          end
          _e.XData=_e.XData(:,ones(size(_e.YData,2),1));
      end
      _e.ZData=0*_e.YData;
      _e.CData=0*_e.YData;

      if or(typeOfPlot==['loglog';'semilogx'])
         _axes_ppty_value_list($+1)='XScale';
         _axes_ppty_value_list($+1)='log';
         x_scale='l';
      end

      if or(typeOfPlot==['loglog';'semilogy'])
         _axes_ppty_value_list($+1)='YScale';
         _axes_ppty_value_list($+1)='log';
         y_scale='l';   
      end
      
    elseif typeOfPlot=='plot3'
       
          [_e.XData,_e.YData,_e.ZData]=argList(_matrix_args(1:3));
          if isvector(_e.XData)
            _e.XData=_e.XData(:);
            _e.YData=_e.YData(:);
            _e.ZData=_e.ZData(:);
          end
          _e.CData=0*_e.ZData(:);
                 
    elseif or(typeOfPlot==['quiver';'quiver3'])

          if typeOfPlot=='quiver'
            if _without_xy
              [_e.UData,_e.VData]=argList(_matrix_args(1:2));
              [_e.XData,_e.YData]=meshgrid(1:size(_e.UData,2),1:size(_e.UData,1));
            else
              [_e.XData,_e.YData,_e.UData,_e.VData]=argList(_matrix_args(1:4));
            end
            _e.ZData=0*_e.UData;
            _e.WData=_e.ZData;
          else
            if _without_xy
              [_e.ZData,_e.UData,_e.VData,_e.WData]=argList(_matrix_args(1:4));
              [_e.XData,_e.YData]=meshgrid(1:size(_e.UData,2),1:size(_e.UData,1));
            else
              [_e.XData,_e.YData,_e.ZData,_e.UData,_e.VData,_e.WData]=argList(_matrix_args(1:6));
            end
          end
          
          if _with_opt_arg
            _e.AutoScaleFactor=argList(_matrix_args($));
          else
            _e.AutoScaleFactor=1;
          end
       
     elseif  or(typeOfPlot==['pcolor';'surf';'mesh';'surfl';'fill';'fill3';'image'])  // surface plots (plot3, quiver and quiver3 produce lines)

        if _without_xy
           _e.ZData=argList(_matrix_args(1));
           _e.XData=1:size(_e.ZData,2);
           _e.YData=1:size(_e.ZData,1);
        else
            [_e.XData,_e.YData,_e.ZData]=argList(_matrix_args(1:3));
        end
        
        if or(typeOfPlot==['mesh';'surfl'])
          _e.CData=0*_e.ZData;
        else
          _e.CData=argList(_matrix_args($));
        end
        
        if or(typeOfPlot==['pcolor'])
           _e.ZData=0*_e.ZData;
        elseif typeOfPlot=='fill'
           _e.ZData=0*_e.XData;
        end
         
        if _with_opt_arg & or(typeOfPlot==['surfl'])
          _e.light=argList(_matrix_args($));
        end  
        
        if or(typeOfPlot==['image'])
         _axes_ppty_value_list($+1)='YDir';
         _axes_ppty_value_list($+1)='reverse';
         _e.CData=_e.ZData;
         _e.ZData=0*_e.ZData;
         if _with_opt_arg
           _axes_ppty_value_list($+1)='CLim';
           _axes_ppty_value_list($+1)=argList(_matrix_args($));
         end
       end
               
     elseif or(typeOfPlot==['trimesh','trisurf','trisurfl','tripcolor'])   
       [_e.Faces,x,y,z]=argList(_matrix_args(1:4));
       _e.Faces=_e.Faces($:-1:1,:);

       if typeOfPlot=='tripcolor'
         _e.Vertices=[x(:) y(:) 0*z(:)];
         _e.FaceVertexCData=z(:);           
       else
         _e.Vertices=[x(:) y(:) z(:)];
         if typeOfPlot=='trisurf'
           _e.FaceVertexCData=argList(_matrix_args($));
         else
           _e.FaceVertexCData=0*z(:);
         end
       end
       if _with_opt_arg & or(typeOfPlot==['trisurfl'])
          _e.light=argList(_matrix_args($));
       end  
         
    elseif  typeOfPlot=='triplot'
        [_e.Faces,x,y]=argList(_matrix_args(1:3));
        _e.Faces=_e.Faces($:-1:1,:);
        _e.Vertices=[x(:) y(:) 0*x(:)];
        _e.FaceVertexCData=0*x(:);
        _e.typeOfPlot='trimesh';
     end   


   end

   // End  of matrix arguments parsing, start of property/value pairs

   [_leaf_ppty_value_list,_start]=_parse_leaf_ppty_value(_e.typeOfPlot,argList,_start);

   h=_update_leaf(_e,lstcat(_leaf_ppty_value_list,varargin));

   hdl=[hdl;h];
   
end // while _start <= length(argList)

_compute_data_bounds(currentAxes,hdl,x_scale+y_scale+'n');

if currentAxes.user_data.nextPlot=='erase'
  currentAxes.view=prefViewType(typeOfPlot);
  _update_axes(currentAxes,_axes_ppty_value_list,%t);
else
  //currentAxes.view=currentView;
end

for i=1:size(hdl,'*')
  user_data=hdl(i).user_data;
  user_data.DisplayName=sprintf('data %d',i);;
  hdl(i).user_data=user_data;
end

currentAxes.user_data.currentColor=[1 1];
currentAxes.user_data.currentLineStyle=1;

win.immediate_drawing=IMD;

out=mlist(['pltlibH','handle'],hdl);

endfunction
