*! version 5.2  07jan2004
*! uses bit-parallel levenshtein distance
*! works on Stata versions 7 and greater


* define location of st_lev.plugin dll
capture display c(version)
if !(_rc) {
	if c(stata_version)>=8.1 {
		program define st_lev, plugin using("S:\SHARE\BSF\RA Manual\ado\st_lev.plugin")
	*	program define st_lev, plugin using("C:\cygwin\home\shtein\stata\st_lev.plugin")
	}
}

program define _glev, sortpreserve

	version 7.0

	* define location of lev.exe program
	local levpath "S:\Share\BSF\lev.exe"

	* obtain type for output and check for numeric
	gettoken type 0 : 0

	if substr("`type'",1,3) == "str" {
		error 108
	}

	* parse out new variable name and equals sign
	gettoken newvar 0 : 0
	gettoken eqs 0 : 0

	* parse out varlist of two string variables to compare, if in and by restrictions
	syntax varlist(string max=2 min=2) [if] [in] [, BY(varlist) ANYorder]

	gettoken var1 varlist : varlist
	gettoken var2 varlist : varlist

		
	* test for anyorder option
	if "`anyorder'"=="anyorder" {
		local anyopt "-a"
	}


	* declare tempnames and tempfiles for input/output to c
	tempname fin fout
	tempfile filein fileout

	* touse the sample
	tempvar touse

	* quietly block for tousing and creation of new variable
	quietly {

		* touse the sample
		generate byte `touse' = 0
		if `"`by'"'=="" {
			replace `touse' = 1 `in' `if'
		}
		else {
			sort `by'
			by `by': replace `touse' = 1 `in' `if'
		}

		* order observations by touse and count number of output observations
		gsort -`touse'
		count if `touse'
		local N = r(N)

		/* write the output file */
		outsheet `var1' `var2' using `"`fileout'"' if `touse', nonames nolabel noquote
		

		/* read the edit distance file and write observations */

		* determine version of stata and input accordingly
		capture display c(version)
		if !(_rc) {
		
			if c(stata_version)>=8.1 {
	
				* running version 8.1
				version 8.1
				display "here"
				* generate newvar as missing to send to dll
				generate `type' `newvar' = .
				
				/* run the levenshtein */
				plugin call st_lev `newvar' `if' `in', "`fileout'" "`anyopt'"
				
				exit
			}
		}
		else {
		
			* running version 8.0 or earlier
			display "here"
			/* run the levenshtein */
			shell `levpath' "`fileout'" "`filein'" "`anyopt'"
			
			* confirm file existence
			capture confirm file "`filein'"
			if _rc {
				display as error "error running lev.exe program, or reading in lev.exe output"
				exit 601
			}

			tempvar obs tmerge tvar
			tempfile tinput

			generate `obs' = _n if `touse'
			preserve

			insheet `tvar' using `"`filein'"', nonames tab clear
			unab tvar : *
			rename `tvar' `newvar'

			generate `obs' = _n
			sort `obs'
			save "`tinput'"

			restore
			count
			local tcount = r(N)

			sort `obs'
			merge `obs' using "`tinput'", _merge(`tmerge')
			tab `tmerge'

			count if `tmerge'==2
			if r(N) > 0 {
				display as error "error reading in lev.exe output"
				exit 601
			}

			count
			if r(N) != `tcount' {
				display as error "error reading in lev.exe output"
				exit 601
			}
		}
	}
		
end
