*! version 1.1.0 <22Aug2010>
*! *! author: Alex Gamma, Zurich (alex.gamma@uzh.ch)

#delimit ;
capture program drop grcomb;

program define grcomb;
version 10;

syntax anything [if] [in] , Varblock(numlist max=1 >=1 integer) [Order(string) name(passthru) Draw Feedback *];

/*
the first option is saved in `varblock', '*' are further unforseen options that'll be saved in `options'
Option 'varblock' can be abbreviated 'v' and must contain exactly 1 integer (that is greater or equal than 1)
giving the N of vars (arguments) for a single instance of the graphic command
option order(string) will return the string the user typed in in a macro called `order'
*/

marksample touse, strok;

if "`draw'" == "" {;
	local draw = "nodraw";
};
else if "`draw'" == "draw" {;
	local draw = "" ;
};

if "`order'" == "" {;
	local order = "abab";
};

if "`order'" != "abab" & "`order'" != "aabb" {;
	display as error "Option 'order' incorrectly specified. 'Order' takes only arguments 'abab' or 'aabb'";
	exit;
};


/* expanding multiplied variables */

if strpos("`anything'", "*") != 0 {;
	local j = wordcount("`anything'");
	tokenize `anything';
	local anything = "";
	forvalues k=1/`j' {;
		local pos = strpos("``k''", "*");
		if  `pos' != 0 {;
			local posp1 = `pos'+1;
			local nrep = real(substr("``k''",`posp1', .));
			if `nrep' != . {;
				local posm1 = `pos'-1;
				local repvar = substr("``k''", 1, `posm1');
				local `k' = "";
				forvalues m=1/`nrep' {;
					local `k' = "`repvar' " + "``k''";
				};
			};
		};
		local anything = "`anything'" + " ``k''";
		macro drop k;
	};
};


/* extracting the graph command */

tokenize `anything';
local w = 1;
capture qui d ``w'';
if _rc==0 {;
	display as error "Either you haven't specified a graph command or you have a variable with the same name as the graph command. In the latter case, temporarily rename that variable.";
	exit;
};
while _rc==111 {;
	local ++w;
	capture qui d ``w'';
};
local w = `w' - 1; /* w contains the number of words belonging to the graph command */


local cmd = "";

forvalues v=1/`w' {; /* loop over N names belonging to the graph command */
	local cmd = "`cmd'" + "``v'' ";
};

/* extracting the varlist */

macro shift `w';
local varlist `*';
unab varlist: `varlist';

local i = wordcount("`varlist'");

if mod(`i',`varblock') != 0 {;
	display as error "N of variables given is not a multiple of the number of variable blocks";
	exit;
};

local r = `i'/`varblock'; /* `r' is the N of varblocks = the N of single graph commands */

if "`feedback'" == "feedback" {;
	display _newline(1); display as result "Single graphs (`r'): " _continue;
};

local c = "";
forvalues b=1/`r' {; 							/* loop over N varblocks */
	local vb = "";
	forvalues v=1/`varblock' {;					/* loop over N vars per varblock */
		if "`order'" == "abab" {;
			local h = `varblock'*(`b'-1) + `v';
			local vb = "`vb'" + word("`varlist'",`h') + " " ; /* construct strings containing all the vars for a single graph command */
		};
		else if "`order'" == "aabb" {;
			local h = `b' + (`v'-1) * `r';
			local vb = "`vb'" + word("`varlist'",`h') + " " ; /* construct strings containing all the vars for a single graph command */
		};
	};
	`cmd' `vb' if `touse', `options' `draw' name(g`b', replace);	/* issue the single graph commands */
	local c = "`c'" + " g`b'";
	if "`feedback'" == "feedback" {;
			display as text "`b'... " _continue;
	};
};

if "`feedback'" == "feedback" {;
	display _newline(1); display as result "Combining graphs...";
};


local n = (tc(`c(current_date)' `c(current_time)') - tc(`c(current_date)' 00:00))/1000;	/* construct a unique name for the combined graph (N of secs since midnight) */
if "`name'" == "" {;
	local name = "name(g`n', replace)";
};

graph combine `c', altshrink `name' nocopies;	/* issue the graph combine command */


end;