
function dynamic_content(cfg) 
{

	cfg = cfg || {};
	this.items = cfg.items || {} ; //{ 'dyn-text': ['one','two','three'], 'dyn-img': ['img1','img2','img3'], 'dyn-cite': ['cite1','cite2','cite3']};
	this.item_num = 0;
	this.num_runs = 0;
	this.msg_count = 0;
	this.num_repeats = ( typeof(cfg.num_repeats) != 'undefined' ) ? cfg.num_repeats : 1; // how many times to run function before it stops
	this.num_items = 0; // determine number of items from first array in cfg.items
	this.duration =  cfg.duration || 5;
	this.shuffle = cfg.shuffle || 0;
	this.suffled_indices = [];
	this.callback = null;
	this.img_base_dir = cfg.img_base_dir;
	this.debug_el = null; // HTML element that displays debugging output
	this.debug_el_id = 'debug';
	this.do_debug = false;	
	this.timer = 0;
	this.stopped = false;
	this.is_running = false;
	this.curr_items = {};
	
	this.init();
} 

dynamic_content.prototype.set_on_complete_callback = function(func)
{
	this.oncomplete_func = func;
}

dynamic_content.prototype.get_data_item = function(item)
{
	return this.items[item] || null;
}


dynamic_content.prototype.set_num_repeats = function(num)
{
	this.num_repeats = num || 1;
}

dynamic_content.prototype.get_num_repeats = function(num)
{
	return this.num_repeats;
}

dynamic_content.prototype.set_duration = function(rate)
{
	var speed = rate || 5;
	speed *= 1000;
	
	this.duration = speed;
}

dynamic_content.prototype.get_duration = function()
{

	return this.duration;
}




dynamic_content.prototype.set_shuffle = function(s)
{
	//default value of 1;
	if( s === 0 )
	{
		this.shuffle = 0;
	}
	else
	{
		this.shuffle = 1;
	}
}


dynamic_content.prototype.set_data = function(data)
{
	this.items = data;
	this.init();
	
}

dynamic_content.prototype.get_data = function(data)
{
	return this.items;	
}


dynamic_content.prototype.set_callback = function(callback)
{
	
		
		var callback_type = typeof(callback);
		var msg = ''; //debugging string
		
		if( callback_type == 'function' )
		{
			this.callback = callback;
			msg += "Callback function " + this.callback.name + "() passed by reference. Callback set!";
			
		}
		else if( callback_type == 'string')
		{
			var cb =  window[callback];
			
			if( cb )
			{
				this.callback = cb;
				msg += "Callback function name " + callback + " found. Callback set!";
			}
			else
			{
				msg += "Callback function name " + callback + " not found";
			}
		}
		else
		{
				msg += "Error! passed arg: " + callback_type;

		}
		
		msg = "set_callback(): " + msg + "\n";
		
		this.internal_on_log(msg);
}

dynamic_content.prototype.get_num_items = function()
{

	// looks at arrays in this.items object and returns length of longest array
	
	if( this.items )
	{
		var len = 0;
		
		for( i in this.items ) //retrieves length of first array in this.items
		{
			if( typeof(this.items[i]) == 'object' )
			{
				
				len = Math.max(len, this.items[i].length);
			}
		}
	}
	
	return len;
}

dynamic_content.prototype.debug = function()
{
	// takes optional string argument of debugging element's id. 
	// If no args passed default of this.debug_el_id is used
	
	var el = null;
	this.do_debug = true;
	
	if( arguments.length == 1 )
	{
		
		this.debug_el_id = arguments[0];
	}
	
	el = getEl(this.debug_el_id);

	if( el == null )
	{
		el = createEl('div', this.debug_el_id, 'debug');
		// added to keep track of el.id for debugging output on failure of debug

		if( el )
		{
			document.body.appendChild(el);
		}
	}
	

	
	if( el )
	{
		if( typeof( drag ) == 'object' )
		{
			drag.add(this.debug_el_id);
		}
		
		EventManager.Add(el,'dblclick', function(){this.style.display="none"}, false);
	}
	
	this.debug_el = el;

}

dynamic_content.prototype.load = function(val)
{
		var msg = ''; // debugging message
		
		if( this.callback )
		{
			msg += "Calling callback " + this.callback.name + "() with object\n";
			this.callback(val);
		}
		else
		{
		
			var typeof_val = typeof(val);
			
			if( typeof_val == 'object')
			{
				for( i in val )
				{
					var el = getEl(i);
				
					if( el )
					{
						el.innerHTML = val[i];
						msg += "Adding value " + val[i] +  " to HTML element of id \"" + i + "\"";
					}
					else
					{
						msg += "HTML element \"" + i + "\" not found\n";
					}

				}	
			}
			else
			{
				msg += "val is not an object: " + typeof_val;
			}
		}
		
		this.internal_on_log( "load(): " + msg + "\n");
}

dynamic_content.prototype.init = function()
{
	//if( this.num_items === null ) // on first run count number of items
	{
	
		this.num_items = this.get_num_items();
		this.item_num = 0;
		this.num_runs = 0;
	
		if( this.timer )
		{
			clearTimeout(this.timer);
			this.timer = 0;
		}
		
		if( this.num_items && this.shuffle )
		{
			this.shuffled_indices = deal(this.num_items);

		}
		
		var msg = "init(): item_num and num_runs set to 0\n";
		msg += "num_items calculated: " + this.num_items + "\n";
		
		if( this.shuffled_indices )
		{
			msg += "shuffled_indices generated: " + this.shuffled_indices + "\n";
		}
		
		this.internal_on_log(msg);
		
	}
}

dynamic_content.prototype.run = function()
{

	this.is_running = true;
	var shuffle_str = ( this.shuffle ) ? "(shuffled)" : "";
	
	var msg = "run(): ";
	
	msg += "Run number: " + this.num_runs + "\n";
	
	if( !this.num_items )
	{
		msg += "No items: returning\n";
		this.internal_on_log(msg);
		this.is_running = false;
		this.stopped = true;
		return;
	}	

	if( this.item_num > this.num_items-1 )
	{	//reset to 0
		//reshuffle items if this.shuffle is set
		
		msg += "Num items: " + this.num_items + " Last number before reset to 0: " + this.item_num;
		var shuffle_str ='';
	
		this.internal_on_log(msg);
	
		
		this.item_num = 0;
		
		if( this.shuffle )
		{
			var last_shuffled_index = this.shuffled_indices[this.num_items-1];
			this.shuffled_indices = deal(this.num_items);
			
			while( this.shuffled_indices[0] == last_shuffled_index )
			{	// if last shuffled item is same as new shuffled item reshuffle to prevent a repeat
				this.shuffled_indices = deal(this.num_items);
			}
		}
		
		msg += "\nShuffled indices: " + this.shuffled_indices + "\n";
		
		this.curr_items = {'reset':'reset'};
		this.load({'reset':'reset'}); // pass  'reset' flag to callback
	

	}
	
	var item_index = this.item_num;
	
	if( this.shuffle )
	{
		item_index = this.shuffled_indices[this.item_num];
	}
	
	_this = this;
	/*
	
	all_items = {};
	all_items['num_items'] = this.num_items;
	all_items['file_path'] = this.file_path;
	
	*/
	this.curr_items = {};
	
	for( var i in this.items )
	{
			
		// i is each of this.items's members, eg: 'dyn-img','dyn-text','dyn-date'. Each member contains an array.
		// One value is taken from each array located at counter "item_index" (this.items.key[item_index]).
		// Each value is assigned to a new object "all_items" to a key with the smae name as that value's original containing array
		// The returned object represent a vertical slice of this.items
	
		//all_items[i] = '';
		var list = this.items[i]; // get array of values for this object member
		
		if( !is_array(list))
		{
			continue;
		}
		
		this.curr_items[i] = ( typeof(list[item_index]) != 'undefined' ) ? list[item_index] : '';

		var msg = '';

		if( this.item_num == 0 )
		{
			msg += "run: obj key: " + i + " contains below array: \n\n\t" + list.join("\n\t") + "\n\n";
		}
		
		//msg  = "run: num run: " + this.num_runs + " item num: " + this.item_num + " called callback function with " + i + ", " + val + "\n";
		
		msg += "Current item " + shuffle_str + " at obj[" + i + "][" + item_index + "]: " + this.curr_items[i] + "\n";
		msg += "Timer: " + this.timer + "\n";
		
		if( this.do_debug )
		{
			this.internal_on_log(msg);
		}
		
		//this.load(i,val); //  display the data in HTML element with id of i
	}
	

	
	this.load(); // callback
	
	if( this.num_runs + 1 < (this.num_repeats * this.num_items) )
	{
	
		this.timer = setTimeout('_this.run()',this.duration);
	}
	else
	{
			
		
		//	this.curr_items = {'reset':'reset'};	
		//	this.load();					
			this.is_running = false;
			
	}
	
	this.item_num++;
	this.num_runs++;
}

dynamic_content.prototype.internalCanMsg = function()
{
	this.msg_count++;
	return (this.do_debug && this.msg_count < 1000);
}
	
// adds message to internal log
dynamic_content.prototype.internal_on_log = function(msg)
{
	if(this.on_log && this.internalCanMsg()) 
	{
		this.on_log(msg);
	}
}

dynamic_content.prototype.on_log = function(msg)
{	
		msg = "[" + this.msg_count + "] " + msg;
		
		if( this.debug_el )
		{
			this.debug_el.innerHTML += msg;
		}
		else
		{
			if( this.msg_count < 5 )
			{
				alert( "HTML element \"" + this.debug_el_id +  "\" for debugging not found!\n\n" + msg);
			}
		}
}


dynamic_content.prototype.stop = function()
{
	if( this.timer )
	{
		clearTimeout(this.timer);
	}
	
	//this.stopped = true;
	this.is_running = false;
	//this.init(); // reset
}




