*! version 0.10	25aug2009 	beta written by William D. MacMillan, Jude Hays, and Rob Franzese.
*! version 0.11	27aug2009	beta
*! version 0.20	14dec2009	beta fixed bug with tscs
*! version 0.22	01feb2009	beta, really fixed the bug this time
*! version 0.23	10mar2011	beta, fixed typo

program define spreg, eclass
	version 9.0
	syntax varlist [if] [in] , SPAtialvars(varlist) ID(varname)   ///
	ROWID(varname) COLID(varname) [ Time(varname) SPATime(varname) ROBUST NOLOG PREMADEW * ]
	preserve
	marksample touse
	mlopts mlopts, `options'
	gettoken y rhs : varlist 				// seperate y, rhs


								// Create Unit ID's

	tempvar uniqueid rid cid
	gsort - `touse'
	qui gen `uniqueid'=_n if `touse'
	qui sum `uniqueid'
	local max = r(max)
	qui count if `touse'
	local d = r(N)

	display in yellow "Building ID markers..." _continue

	if "`time'" ~= "" {
		qui gen `rid' = .
		qui gen `cid' = .
		forvalues i = 1/`max' {
			qui levelsof `id' if `uniqueid'==`i', local(unitid)
			qui levelsof `time' if `uniqueid'==`i', local(timeid)
			qui replace `rid' = `i' if `rowid'==`unitid'&`spatime'==`timeid'
			qui replace `cid' = `i' if `colid'==`unitid'&`spatime'==`timeid'
		}
	}


	if "`time'" == "" {
		qui gen `rid' = .
		qui gen `cid' = .
		forvalues i = 1/`max' {
			qui levelsof `id' if `uniqueid'==`i'
			local unitid = r(levels)
			qui replace `rid' = `i' if `rowid'==`unitid'
			qui replace `cid' = `i' if `colid'==`unitid'
		}
	}

	display in yellow "done."

	local numw = 0
	foreach var of varlist `spatialvars' { 			// generate W's in Mata
		local numw = `numw' + 1
		capture drop SL`numw'
	}
	display in yellow "Building W matrices..." _continue
	mata: wmaker(`d', "`rid'", "`cid'", "`spatialvars'", `numw', "`y'", "`touse'")
	display in yellow "done."

	qui regress `y' `rhs'					// Produce starting values
	matrix OLSb=e(b)
	local OLSsigma=e(rmse)

	if `numw'==1 {
		ml model lf spreg_ll_1 ( `y' = `rhs') /rho1 /sigma if `touse', maximize `robust' `nolog'	///
		init(OLSb sigma:_cons=`OLSsigma') `mlopts'
	}
	if `numw'==2 {
		ml model lf spreg_ll_2 ( `y' = `rhs') /rho1 /rho2 /sigma if `touse', maximize `robust' `nolog'	///
		init(OLSb sigma:_cons=`OLSsigma') `mlopts'
	}
	if `numw'==3 {
		ml model lf spreg_ll_3 ( `y' = `rhs') /rho1 /rho2 /rho3 /sigma if `touse', maximize `robust' `nolog'	///
		init(OLSb sigma:_cons=`OLSsigma') `mlopts'
	}
	if `numw'==4 {
		ml model lf spreg_ll_4 ( `y' = `rhs') /rho1 /rho2 /rho3 /rho4 /sigma if `touse', maximize `robust' `nolog'	///
		init(OLSb sigma:_cons=`OLSsigma') `mlopts'
	}
	if `numw'==5 {
		ml model lf spreg_ll_5 ( `y' = `rhs') /rho1 /rho2 /rho3 /rho4 /rho5 /sigma if `touse', maximize `robust' `nolog'	///
		init(OLSb sigma:_cons=`OLSsigma') `mlopts'
	}
	if `numw'==6 {
		ml model lf spreg_ll_6 ( `y' = `rhs') /rho1 /rho2 /rho3 /rho4 /rho5 /rho6 /sigma if `touse', maximize `robust' `nolog'	///
		init(OLSb sigma:_cons=`OLSsigma') `mlopts'
	}
	if `numw'==7 {
		ml model lf spreg_ll_7 ( `y' = `rhs') /rho1 /rho2 /rho3 /rho4 /rho5 /rho6 /rho7 /sigma if `touse', maximize `robust' `nolog'	///
		init(OLSb sigma:_cons=`OLSsigma') `mlopts'
	}
	if `numw'==8 {
		ml model lf spreg_ll_8 ( `y' = `rhs') /rho1 /rho2 /rho3 /rho4 /rho5 /rho6 /rho7 /rho8 /sigma if `touse', maximize `robust' `nolog'	///
		init(OLSb sigma:_cons=`OLSsigma') `mlopts'
	}
	if `numw'==9 {
		ml model lf spreg_ll_9 ( `y' = `rhs') /rho1 /rho2 /rho3 /rho4 /rho5 /rho6 /rho7 /rho8 /rho9 /sigma if `touse', maximize `robust' `nolog'	///
		init(OLSb sigma:_cons=`OLSsigma') `mlopts'
	}
	if `numw'==10 {
		ml model lf spreg_ll_10 ( `y' = `rhs') /rho1 /rho2 /rho3 /rho4 /rho5 /rho6 /rho7 /rho8 /rho9 /rho10 /sigma if `touse', maximize `robust' `nolog'	///
		init(OLSb sigma:_cons=`OLSsigma') `mlopts'
	}

	ml display
	dis "Weighting variables, in order: `spatialvars'"
	restore

end