/*-------------------------------------------------------------------------------
  euse.ado: extended use; wrapper for using different dataset formats

    Copyright (C) 2012  Daniel Bela (daniel.bela@lifbi.de)

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

-------------------------------------------------------------------------------*/
*! euse.ado: extended use; wrapper for using different dataset formats
*! Daniel Bela (daniel.bela@lifbi.de), Leibniz Institute for Educational Trajectories (LIfBi), Germany
*! version 0.9 01 March 2012 - initial release
program define euse, nclass

	//preparing macros
	syntax anything(everything equalok) , [FORmat(string) CLEAR VERBOSE CASE CELLs(passthru) DELIMiter(passthru) ///
		DATEstring MISSing NOCOMPress SHEET(passthru) SHEETNum(integer -99) FIRSTrow ALLstring CELLRAnge(passthru) ///
		noNames NOVALlabels]
	quietly: extractfilename `=trim(regexr(`"`anything'"',"^using ?",""))'
	local ext `r(extension)'
	local filename `r(filename)'
	local path `r(path)'
	if "`format'"=="ooxml" | "`format'"=="excel" | inlist(`"`ext'"',"xlsx","xls") version 12
	else version 10
	local noformatgiven 0
	if `"`format'"'=="" local noformatgiven 1

	// concatenate using dataset name - cleansed for (compound) double quotes, "using " prefix and trimmed
	if `"`path'"'!="" & `"`ext'"'!="" local using `path'`c(dirsep)'`filename'.`ext'
	else if `"`path'"'!="" local using `path'`c(dirsep)'`filename'
	else if `"`ext'"'!="" local using `filename'.`ext'
	confirm file `"`using'"'

	// guess format from file extension options
	if `noformatgiven'==1 {
		if `"`ext'"'=="dta" local format "stata"
		else if `"`ext'"'=="dat" local format "ascii_tab"
		else if `"`ext'"'=="txt" local format "ascii_comma"
		else if `"`ext'"'=="csv" local format "ascii_comma"
		else if `"`ext'"'=="xpt" local format "sas"
		else if `"`ext'"'=="xml" local format "xml_excel"
		else if `"`ext'"'=="xlsx" local format "ooxml"
		else if `"`ext'"'=="xls" local format "excel"
	}

	// check for inconsistencies in options
	* format should be nonmissing by now
	if `"`format'"'=="" {
		noisily: display as error in smcl `"{bf:Warning:} file {opt format} for {it:`using'} not specified and not guessable from file extension. Assuming {it:stata} format."'
		local format stata
	}
	else if "`verbose'"=="verbose" & `noformatgiven'==1 noisily: display as text in smcl `"{bf:Info:} assuming {bf:`format'} format from file extension {it:`ext'}."'
	* don't mix up excel and ooxml format!
	if `"`format'"'=="excel" & regexm(`"`using'"',`"^.+\.xlsx$"') {
		local format "ooxml"
		noisily: display as error in smcl `"{bf:Warning:} file {it:format excel} does not match file extension of {it:`using'}. Changed to {it:ooxml} format."'
	}
	else if `"`format'"'=="ooxml" & regexm(`"`using'"',`"^.+\.xls$"') {
		local format "excel"
		noisily: display as error in smcl `"{bf:Warning:} file {it:format ooxml} does not match file extension of {it:`using'}. Changed to {it:excel} format."'
	}
	* use ascii options only when applicable
	foreach opt in case names {
		if "``opt''"!="" & !inlist("`format'","ascii_custom","ascii_tab","ascii_comma","ascii_semicolon") noisily: display as error in smcl "{bf:Warning:} option {opt `opt'} is only applicable for {it:ascii_comma}, {it:ascii_tab}, {it:ascii_semicolon} and {it:ascii_custom} formats; ignored. Refer to {help euse:help file} for details."
	}
	* use ascii_custom option only when applicable
	if "`delimiter'"!="" & `"`format'"'!="ascii_custom"  noisily: display as error in smcl "{bf:Warning:} option {opt delimiter} is only applicable for {it:ascii_custom} format; ignored. Refer to {help euse:help file} for details."
	* don't let -delimiter- be empty in ascii_custom format!
	if `"`format'"'=="ascii_custom" & "`delimiter'"=="" {
		noisily: display as error in smcl "{bf:Warning:} option {opt delimiter} is mandatory for format {it:ascii_custom}. Changed format to {it:ascii_tab}."
		local format "ascii_tab"
	}
	* use xmluse options only where applicable
	foreach opt in cells datestring missing nocompress {
		if `"``opt''"'!="" & `"`format'"'!="xml_excel" noisily: display as error in smcl "{bf:Warning:} option {opt `opt'} is only applicable for {it:xml_excel} format; ignored. Refer to {help euse:help file} for details."
	}
	* use shared xmluse/import excel options only where applicable
	foreach opt in sheet firstrow allstring {
		if `"``opt''"'!="" & !inlist(`"`format'"',"xml_excel","ooxml","excel") noisily: display as error in smcl "{bf:Warning:} option {opt `opt'} is only applicable for {it:xml_excel}, {it:ooxml} and {it:excel} formats; ignored. Refer to {help euse:help file} for details."
	}
	* use import excel options only where applicable
	foreach opt in cellrange sheetnum {
		if `sheetnum'>0 & !inlist(`"`format'"',"ooxml","excel") noisily: display as error in smcl "{bf:Warning:} option {opt `opt'} is only applicable for {it:ooxml} and {it:excel} formats; ignored. Refer to {help euse:help file} for details."
	}
	* notify that -sheetnum- and -sheet- are mutually exclusive
	if inlist(`"`format'"',"ooxml","excel") & "`sheetnum'"!="" & `"`sheet'"'!="" {
		noisily: display as error in smcl "{bf:Warning:} options {opt sheet} and {opt sheetnum} are mutually exclusive; {opt sheetnum} ignored."
		local sheetnum ""
	}

	// use target file as indicated
	if inlist(`"`format'"',"stata","stata_old") quietly: use `"`using'"', `clear'
	else if inlist(`"`format'"',"ascii_tab","ascii_comma") quietly: insheet using `"`using'"', `case' `names' `clear'
	else if `"`format'"'=="ascii_semicolon" quietly: insheet using `"`using'"', delimiter(";") `case' `names' `clear'
	else if `"`format'"'=="ascii_custom" quietly: insheet using `"`using'"', `delimiter' `case' `names' `clear'
	else if `"`format'"'=="sas" {
		if c(version)>=12 quietly: import sasxport `"`using'"', `novallabels' `clear'
		else quietly: fdause `"`using'"', `novallabels' `clear'
	}
	else if `"`format'"'=="xml_stata" quietly: xmluse `"`using'"', doctype(dta) `clear'
	else if `"`format'"'=="xml_excel" quietly: xmluse `"`using'"', doctype(excel) `cells' `sheet' `datestring' `missing' `nocompress' `firstrow' `allstring' `clear'
	else if inlist(`"`format'"',"ooxml","excel") {
		if `sheetnum'<=0 quietly: import excel using `"`using'"', `cellrange' `sheet' `firstrow' `allstring' `clear'
		else {
			quietly: import excel using `"`using'"', describe
			capture: assert inrange(`sheetnum',1,`r(N_worksheet)')
			if _rc!=0 {
				noisily: display as error in smcl "{bf:Error:} using file only contains `r(N_worksheet)' spreadsheets; cannot import sheet number {it:`sheetnum'}."
				exit 111
			}
			quietly: import excel using `"`using'"', `cellrange' sheet("`r(worksheet_`sheetnum')'") cellrange("`r(range_`sheetnum')'") `firstrow' `allstring' `clear'
		}
	}
	else {
		noisily: display as error `"{bf:Warning:} you specified the {opt format} {bf:`format'}, but it is not supported. Refer to {help euse:help file} for supported formats."'
		exit 198
	}
	exit 0
end
//EOF