function [] = run_experiments(folder,k,tau,threshold,minClusterSize,reruns)
% runs the experiments for a directory like 'vary_l'

	global algos;
	algos = {'pcv', 'message', 'lfm', 'lim'};
	%algos = {'pcv'};

	disp(['Running algos: ', algos])

	files = dir(folder);
	for file = files'
		% skip hidden files
		if isequal(file.name, '.') | isequal(file.name, '..') | isequal(file.name, '.DS_Store') | ... 
				isequal(file.name, 'results.mat') | isequal(file.name, 'figLeft.png') | ...
				isequal(file.name, 'figRight.png') | isequal(file.name, 'figTimes.png')
			continue
		end

		parameter = str2num(file.name)
		run_experiments_for_parameter( strcat(file.folder, filesep, file.name),k,tau,threshold,minClusterSize,reruns,parameter);
	end
end

function [] = run_experiments_for_parameter(folder,k,tau,threshold,minClusterSize,reruns,param)
% runs the experiments for a given parameter, e.g., 'l = 30'
	files = dir(folder);
	for file = files'
		% skip hidden files
		if isequal(file.name, '.') | isequal(file.name, '..') | isequal(file.name, '.DS_Store')
			continue;
		end

		exp_dir = strcat(file.folder, filesep, file.name);
		run_and_evaluate_experiments_from_folder(exp_dir,k,tau,threshold,  minClusterSize,reruns,param);
	end
end

function[] = run_and_evaluate_experiments_from_folder(folder,k,tau,threshold, ...
				minClusterSize,reruns,param)
	% load patterns and data
	patterns = zeros(1);
	leftTruth = zeros(1);
	data = zeros(1);
	inputfile = '';

	files = dir(folder);
	for file = files'
		if strfind(file.name, 'patterns')
			path = strcat(file.folder, filesep, file.name);
			patterns = sparse(csvread(path));
		elseif strfind(file.name, 'data')
			path = strcat(file.folder, filesep, file.name);
			data = sparse(csvread(path));
			inputfile = path;
		elseif strfind(file.name, 'leftClusters')
			path = strcat(file.folder, filesep, file.name);
			leftTruth = sparse(csvread(path));
		end
	end

	qs = containers.Map();
	qsLeft = containers.Map();
	ks = containers.Map();
	Cs = containers.Map();
	CsLeft = containers.Map();
	times = containers.Map();
	
	global algos;
	for algo = algos
		algochar = char(algo);
		qs(algochar) = 0;
		qsLeft(algochar) = 0;
		ks(algochar) = 0;
		times(algochar) = 0;
		Cs(algochar) = zeros(1);
		CsLeft(algochar) = zeros(1);
	end

	% from the value of the parameter we conclude which setting we current have
	% in the experiments. According to this, we set the correct parameters.
	if param >= 10 % vary_l
		clusSize = idivide( int32(param), int32(4), 'floor' );
		rows = 8 * double(param);
		p_x_1 = (1*rows) / (8*rows);
		p_y_1 = (8*8) / (1000 * 8);
		p_0_given_0 = 0.97;
		p_1_given_1 = 0.5;

		pLim = 0.5;
		qLim = 0.03;
	else
		clusSize = minClusterSize;
	end

	% experiments for vary_p
	if param < 1
		q = 0.03;
		thresh = log2( (1-q)/(1-param) ) / log2( param*(1-q) / q / (1-param));

		pLim = param;
		qLim = q;

		% set up stuff for message
		p_x_1 = (1*560) / (8*560);
		p_y_1 = (8*8) / (1000 * 8);
		p_0_given_0 = 0.97;
		p_1_given_1 = param;
		% if param < 0.501
		% 	p_1_given_1 = 0.501;
		% end
	else
		thresh = threshold;
	end

	% experiments for vary_size
	if param >= 1 & param <= 12
		% k = 12; % WRONG PARAMETER
		if param == 1 | param == 2
			t = 8; % random clustering: t = 0.2;
			% t = 12; % WRONG PARAMETER 
		elseif param == 3 | param == 4 | param == 5
			t = 8; % random clustering: tau = 0.25;
			% t = 12; % WRONG PARAMETER 
		else
			t = 8;
			%t = 12; % WRONG PARAMETER 
		end
		thresh = 0.1812; % WRONG PARAMETER

		p_x_1 = (1*560) / (8*560);
		p_y_1 = (param*8) / (1000 * 8);
		%p_0_given_0 = 0.99; % WRONG PARAMETER
		%p_1_given_1 = 0.6; % WRONG PARAMETER
		p_0_given_0 = 0.97;
		p_1_given_1 = 0.4;

		pLim = 0.4;
		qLim = 0.03;
		%pLim = 0.6; % WRONG PARAMETER
		%qLim = 0.01; % WRONG PARAMETER
	else
		t = tau;
	end

	%%%%%%%%%%%%%%%%%%%%% Run PCV
	if runAlgo('pcv')
		disp('running pcv')
		tic
		[C, leftC] = proj_wrapper(inputfile,k,'simple',t,0,thresh,clusSize);
		times('pcv') = toc;

		Cs('pcv') = unique(C, 'rows');
		CsLeft('pcv') = leftC;
		qs('pcv') = qualityMeasure(patterns,Cs('pcv'));
		qsLeft('pcv') = qualityMeasure(leftTruth,CsLeft('pcv'));
	end

	%%%%%%%%%%%%%%%%%%%%%%%%%%%% Run lfm multiple times
	for i = 1:reruns
		if runAlgo('lfm')
			disp('running lfm')
			tic
			[Clfm, leftClustersLFM] = lfm_wrapper(inputfile, k, 0.5);
			time = toc;
			qlfm = qualityMeasure(patterns,Clfm);

			if qlfm > qs('lfm')
				qs('lfm') = qlfm;
				Cs('lfm') = Clfm;
				CsLeft('lfm') = leftClustersLFM;
				qsLeft('lfm') = qualityMeasure(leftTruth,CsLeft('lfm'));
				times('lfm') = time;
			end

		end
	end

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Run Lim et al.
	if runAlgo('lim')
		disp('running lim')

		W = log(pLim/qLim) * data + log((1-pLim)/(1-qLim))*(1-data);

		% we run the algorithm with different parameters for lambda
		for lambda = [20, 25, 30, 35, 40, 45]
			tic
			[C, leftClusters] = bicluster_kmeans(W,k,lambda);
			time = toc;
			qlim = qualityMeasure(patterns, C);

			if qlim > qs('lim')
				qs('lim') = qlim;
				Cs('lim') = C;
				CsLeft('lim') = leftClusters;
				qsLeft('lim') = qualityMeasure(leftTruth,CsLeft('lim'));
				times('lim') = time;
			end
		end
	end

	%%%%%%%%%%%%%%%%%%%%%%%%%%%%% Run Message
	if runAlgo('message')
		disp('running message')
		tic
		[C, leftClusters] = message_wrapper(inputfile,k,p_x_1,p_y_1,p_0_given_0,p_1_given_1);
		times('message') = toc;
		Cs('message') = C;
		qs('message') = qualityMeasure(patterns,Cs('message'));
		CsLeft('message') = leftClusters;
		qsLeft('message') = qualityMeasure(leftTruth,CsLeft('message'));
	end

	% put results into a format good format for saving
	for algo = algos
		algochar = char(algo);
		ks(algochar) = size(Cs(algochar),1);
	end

	save( strcat(file.folder,filesep,'results'), 'qs', 'ks', 'Cs', 'times', 'CsLeft', 'qsLeft' );
end

