*! version 1.1.0  10feb2000
program define stsplit2
	version 6
	if _caller() < 6 {
		ztspli_5 `0'
		exit
	}

	st_is 2 analysis

	if `"`_dta[st_id]'"' == "" {
		di in red /*
		*/ "stsplit requires you have previously stset an id() variable"
		exit 198
	}

	local origN = _N
	syntax newvarname [=exp] [if] [, AT(string) TRIM *]
	if `"`exp'"' == "" {
		Breakt `0'
	}
	else	Breakv `0'
	di in gr "(" _N-`origN' " observation" /*
		*/ cond(_N-`origN'!=1,"s","") " created)"

	if "`trim'"!="" {
		tokenize `at'
		local n : word count `at'
		qui count if _st
		local cur = _N
		qui count if float(`varlist')<float(`1') & _st
		local lb = r(N)
		qui count if float(`varlist')==float(``n'') & _st
		local ub = r(N)
		if `lb' | `ub' {
			qui replace _st = 0 if float(`varlist')<float(`1') /*
				*/ | float(`varlist')==float(``n'')
			di in gr "(" `lb' " + " `ub' /*
			*/ " obs. trimmed due to lower and upper bounds)"
			if `lb' & `ub' {
				st_note /*
				*/ `"`varlist'<=`1' & `varlist'>``n'' trimmed"'
			}
			else if `lb' {
				st_note `"`varlist'<=`1' trimmed"'
			}
			else 	st_note `"`varlist'>``n'' trimmed"'
		}
		else 	di in gr /*
			*/ "(no obs. trimmed because none out of range)"
	}
end


program define FindFail, sclass
	sret clear
	syntax [if]

	tempvar touse
	mark `touse' `if'
	qui replace `touse' = 0 if _st==0
	qui replace `touse' = 0 if _d==0

	preserve
	quietly {
		keep if `touse'
		sort _t
		quietly by _t: keep if _n==1
	}
	local s = cond(_N==1,"","s")
	di in gr "(" _N " failure time`s')"
	local len 0
	local maxlen = cond("$S_FLAVOR"=="Intercooled",18632,1000)
	local i 1
	while `i' <= _N {
		local t = _t[`i']
		local len = `len' + length("`t'") + 1
		if `len' > `maxlen' {
			di in red "too many failure times"
			exit 1001
		}
		sret local at `s(at)' `t'
		local i = `i' + 1
	}
end

program define Breakt
	syntax newvarname [if], AT(string) [noPREserve TRIM]
	local c_at = substr(`"`at'"',1,12)
	if substr("failures",1,max(1,length(`"`c_at'"'))) == `"`c_at'"' {
		FindFail `if'
		local at `s(at)'
		sret clear
	}
	else {
		syntax newvarname [if], AT(numlist >=0 sort) [noPREserve TRIM]
	}
	local c_at
	tempvar touse
	mark `touse' `if'
	qui replace `touse' = 0 if _st==0

	if "`preserv'"=="" {
		preserve
		local norest "restore, not"
	}
	quietly {
		recast double _t
		recast double _t0
	}

	tempvar res
	qui gen `typlist' `res' = .

	tokenize `at'
	local n : word count `at'
	local i 1
	local last -1e+32
	local cat 0
	while `i' <= `n' {
		BreakAt ``i'' `touse'
		LabelAt `last' ``i'' `touse' `res' `cat'
		local last ``i''
		local cat ``i''
		local i = `i' + 1
	}
	LabelAt `last' 1e+32 `touse' `res' `cat'
	rename `res' `varlist'
	quietly compress _t _t0
	`norest'
end

program define BreakAt
	args where touse
	quietly {
		tempvar br
		gen byte `br' = float(_t0)<float(`where') & /*
				*/ float(`where')<float(_t) if `touse'
		count if `br' & `touse'
		if r(N)==0 { exit }
		expand 2 if `br' & `touse'
		local id `_dta[st_id]'
		sort `touse' `id' _t `br'
		by `touse' `id' _t `br': replace `br'=0 if `br' & _n==1
		replace _d = 0 if `br'[_n+1]==1
		replace _t = `where' if `br'[_n+1]==1
		replace _t0 = `where' if `br'==1

	/* adjust user variables */
		IsVar `_dta[st_bd]'
		if `s(exists)' {
			replace `_dta[st_bd]' = . if `br'[_n+1]==1
		}
		IsVar `_dta[st_bt]'
		if `s(exists)' {
			replace `_dta[st_bt]' = /*
				*/ `where'*`_dta[st_s]' + `_dta[st_o]' /*
				*/ if `br'[_n+1]==1
		}
		IsVar `_dta[st_bt0]'
		if `s(exists)' {
			replace `_dta[st_bt0]' = /*
			*/ `where'*`_dta[st_s]' + `_dta[st_o]' /*
			*/ if `br' == 1
		}
	/* end adjust user variables */
	}
end


program define LabelAt
	args lb ub touse var label
	qui replace `var' = `label' if `touse' & /*
		*/ `lb'!=. & `ub'!=. & /*
		*/ float(`lb')<=float(_t0) & float(_t)<=float(`ub')
end

program define Breakv
	syntax newvarname =/exp [if], AT(numlist sort) [noPREserve TRIM]

	if "`time'"!="" & "`age'"!="" {
		di in red "may not specify options time and age together"
		exit 198
	}
	if "`time'"=="" & "`age'"=="" {
		local time time
	}

	tempvar touse
	mark `touse' `if'
	qui replace `touse'=0 if _st==0

	if "`t'"=="" {
		local o `_dta[st_o]'
		local s `_dta[st_s]'
	}
	else {
		local o 0
		local s 1
	}

	if "`preserv'"=="" {
		preserve
		local norest "restore, not"
	}
	quietly {
		recast double _t
		recast double _t0
	}

			/*
				v will contain the "age" at 0
				in analysis t units
			*/

	tempvar v
	quietly {
		local id `_dta[st_id]'
		sort `touse' `id' _t
		by `touse' `id': gen double `v' = `exp' if `touse'
		/* we take earliest value of time/date */
		by `touse' `id': /*
			*/ replace `v' = `v'[_n-1] if `v'[_n-1]<`v' & `touse'
		by `touse' `id': replace `v' = (`o'-`v'[_N])/`s' if `touse'
		compress `v'
	}

	tempvar where last res
	qui gen `typlist' `res' = .
	tokenize `at'
	local n : word count `at'
	local i 1
	qui gen double `last' = -1e+32 if `touse'
	local cat = cond(`1'>0, 0, `1'-1)
	local i 1
	while `i' <= `n' {
		qui gen double `where' = (``i''-`v') if `touse'
		BreakAt `where' `touse'
		LabelAt `last' `where' `touse' `res' `cat'
		local cat ``i''
		drop `last'
		rename `where' `last'
		local i = `i' + 1
	}
	LabelAt `last' 1e+32 `touse' `res' `cat'
	rename `res' `varlist'
	quietly compress _t0 _t
	`norest'
end

program define IsVar, sclass
	nobreak {
		capture confirm new var `1'
		if _rc {
			capture confirm var `1'
			if _rc==0 {
				sret local exists 1
				exit
			}
		}
	}
	sret local exists 0
end
exit