function ssw_actor, param_names, port_types, port_names, service=service, host=host, $
    def_values=def_values, extra=extra, class=class
;
;+
;   Name: ssw_actor
; 
;   Purpose: generate MOML actor for CoSEC
;
;   Input Paramters:
;      param_names - parameter names as seen by ssw service
;      param_types - port type {'input','output'} or {'I','O'} or {1,0}
;      port_names - optional for cosec port names different from param_names
;
;   Keyword_Parameters:
;      service - service cgi - full url -or- relative cgi-path 
;      host - IP of server (if SERVICE is not absolute URL) 
;      extra - (switch) - set if CoSEC 'extra' parameter is desired (inherit->SSW service)
;
;   Calling Example:
;      moml=ssw_actor('param1,param2,param1','i,i,o','start_time,stop_time,out_graphic', $
;         service='http://www.lmsal.com/cgi-diapason/ssw_service_plot_goes_xrays.sh')
;
;   History:
;      Circa Jan 2006 - S.L.Freeland 
;      29-Nov-2006 - Do Entity/class in this routine (from SERVICE) 
;
;-

if n_elements(param_names) eq 0 then begin 
    box_message,'Need at least one port...'
    return,''
endif
if data_chk(param_names,/string) and n_elements(param_names) eq 1 then param_names=str2arr(param_names)
if data_chk(port_names,/string) and n_elements(port_names) eq 1 then port_names=str2arr(port_names)
if data_chk(port_types,/string) and n_elements(port_types) eq 1 then port_types=str2arr(port_types)

nparam=n_elements(param_names)
nports=n_elements(port_names)
ntypes=n_elements(port_types)

case 1 of
   nports eq nparam:   ; user supplied all
   else: port_names=param_names
endcase
case 1 of 
   ntypes eq nparam: 
   else: begin 
      box_message,'Please supply a port type for each port
      return,''
   endcase
endcase
cosec=get_logenv('SSW_COSEC')
agents=concat_dir(cosec,'agents')
header=concat_dir(agents,'ssw_actor_temp_header.moml')

if not file_exist(header) then begin 
   box_message,'Need to install or update CoSEC branch of SolarSoft'
   return,''
endif

if n_elements(service) eq 0 then begin
   box_message,'You must supply at least service name via SERVICE keyword'
   return,''
endif
break_url,service,ip,path,cgi,http=http
if n_elements(host) eq 0 then host=ip
if http then service_name=concat_dir('/'+path,cgi) else service_name=service

retval=rd_tfile(header)
ss_service=where(strpos(retval,'SERVICE_CGI_PATH') ne -1,scnt)
if scnt eq 0  then begin 
   box_message,'?? Bad header template ??, returning..'
   returnt,''
endif
retval(ss_service)=str_replace(retval(ss_service),'SERVICE_CGI_PATH',service_name)

ss_host=where(strpos(retval,'SERVICE_HOST_IP') ne -1)
retval(ss_host)=str_replace(retval(ss_host),'SERVICE_HOST_IP',host)
ssclass=where(strpos(retval,'SolarSoftTemplate') ne -1,ccnt)
if ccnt gt 0 then begin
   break_file,service,ll,pp,ff
   class=strextract(service,'_service_','.') ; some historical assumptions
;  namely, http://...<path>/<cgi>/xxxx_service_<servicename>.<sh,csh,pl...>
   retval(ssclass)=str_replace(retval(ssclass),'SolarSoftTemplate',class)
 endif

; add ssw param -> cosec port mappings:
; 1st, see if any duplicates  (e.g. param1 input & output
allparam=all_vals(param_names)

if n_elements(allparam) ne n_elements(param_names) then begin 
   for i=0,n_elements(allparam)-1 do begin 
      ssd=where(param_names eq allparam(i),cnt) 
      if cnt gt 1 then begin
         box_message,'uniquifying duplicate parameter names..'
         sso=where(port_types(ssd) eq 'output',ocnt)
         if ocnt gt 0 then param_names(ssd(sso))=strupcase(param_names(ssd(sso))) else $
            param_names(last_nelem(ssd))=strupcase(param_names(last_nelem(ssd)))

      endif
   endfor
endif

ssmiss=where(port_names eq '' and param_names ne '',mcnt)
if mcnt gt 0 then port_names(ssmiss)=param_names(ssmiss)

ssdiff=where(param_names ne port_names,dcnt)
if dcnt gt 0 then begin 
   arg2port='<property name="argsToPorts" class="ptolemy.data.expr.Parameter" value="{ARGS2PORTS}">'
   repline=port_names(ssdiff)+'=&quot;'+param_names(ssdiff)+'&quot;'
   repline=arr2str(repline)
   arg2port=str_replace(arg2port,'ARGS2PORTS',repline)
   retval=[temporary(retval),arg2port,'</property>']
endif 

for i=0,nparam-1 do begin 
   retval=[temporary(retval),ssw_actor_newport(param_names(i),port_names(i),port_types(i))]
endfor

if keyword_set(extra) then $
   retval=[temporary(retval),ssw_actor_newport('extra','extra','i')]


retval=[temporary(retval),'</entity>']

return,retval
end




