/*	JavaScript
	============================================================
	This script comes with no warranty.
	It may be used, copied and modified
	for your own purposes as you like.

	Manfred Sorgo
	http://www.sorgo.de
	Wed Oct 10 03:39:40 2007
	============================================================
*/
//	========================================
//	CUSTOM SCRIPT SETTINGS
//	----------------------------------------
//	delays / timeouts
var delay = [
//	0: delay between image changes
	100,
//	1: delay between regular shuffles
	12000,
//	2: delay after game play
	36000,
//	3: delay before playing
	2000,
//	4: delay before first shuffle
	3000,
//	5: duration of slides
	8000,
//	6: timeout for printing
	48000,
//	7: red light display time
	800
];
//	language dependent settings
var
	bc_ttl = 'Drei in einer Reihe',
	bc_score = 'Punkte',
	bc_three = 'Dreier',
	bc_gms = 'Spiele',
	bc_zen = 'Zen',
	bc_print = '[ OK ] für Drucken ...',
	bc_play = '',
	bc_new = 'Neues Spiel',
	bc_hint = ' >> ',
	bc_no = ' NICHT Klicken',
	bc_pos = '',
	bc_ok = ' OK',
	bc_dbs = 'Klick ohne Möglichkeiten.',
	bc_mis = 'Übersehen',
	bc_rep = 'Wiederholung',
	bc_ntp = 'Ab jetzt ohne Tipps.'
;
//	========================================
//	SCRIPT GENERATED PART
//	----------------------------------------
var
	b_names = ['@w2','@w1','@w0','@wr2','@wr1','@wr0'],
	s_names = ['117','120','115','116','124','113','108','105','104','103','102','101','226','223','222','220','227','233','232','230','229','219','217','216','215','214','213','212','211','210','209','208','207','206','205','204','203','202','201'],
	s_titles = ['April 2007','Oktober 2006','gut aufgelegt','Oktober 2005','Archiv','Sprengpunkte','Unter dem Hexenhammer','Große Vögel, kleine Vögel','gut aufgelegt','Soll:Bruchstelle','Underground','Kahlschlag','Shakespeare Love Songs','Stellungskriege','sleeping around','Der futurologische Kongress','Hau den Judas','Prinzessin Brummeisen','Max und Milli'],
	s_heads = ['Portraits','Fotos Bühne'],
	s_nt = [0,0,0,0,0,0,1,2,3,4,4,4,5,5,5,5,5,6,6,7,7,8,8,8,8,8,9,9,10,10,10,11,12,13,14,15,16,17,18],
	s_nh = [0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
	m_nums = [5,8,9,10,12,13,15,16,19,20,21,22,25,28,29,31,32,34,35,36,38],
	b_pre = 'images/',
	b_suf = '.gif',
	b_dummy = 'index.html',
	s_pre = 'thumbs/',
	s_suf = '.jpg',
	s_pref = 't_',
	h_pre = 'fotos_',
	h_suf = '.html',
	m_pre = 'slices/',
	m_pref = 's_',
	m_suf = '.jpg',
	cols = 3,
	rows = 3,
	m_wait = 2
;
//	----------------------------------------
//	END GENERATED PART
//	========================================
//	----------------------------------------
//	process vars
//	----------------------------------------
var
//	page elements
	e_mgr = [],
	b_mgr = [],
	a_mgr = [],
//	thumb nail and button image containers
	s_cnt = s_names.length,
	e_cnt = cols * rows,
	s_imgs = [],
	b_cnt = b_names.length - 4,
	b_imgs = [],
	b_on = [],
//	and lists
	pre_list = [],
	p_list = [],
	c_list = [],
	p_snap,
	m_curr = 0,
	r_curr = 0,
	r_play = false,
	pre_x = false,
//	mosaik vars
	m_imgs = [],
	m_cnt = m_nums.length,
	m_w = Math.min(2, m_wait),
	m_sec,
	m_n,
	m_list = [],
//	play or unique shuffle
	playing = false,
	pl_cnt = [0, 0, 0],
	pl_acc = 100,
	pl_x = true,
//	clicks and chances
	pl_chs = [],
	pl_chsx = [],
	pl_cmax = 0,
	pl_open = 0,
//	last click & zen play
	pl_cl = 0,
	pl_zen = [0, 0, 0],
//	sounds
	snds = [],
//	std
	i, j, n
;
//	----------------------------------------
//	PAGE ELEMENTS
//	----------------------------------------
//	image, anchor and text elements
function init_elems () {
//	animation images and nachors
//	- images: anim_fi01 ... e_cnt
//	- anchors: anim_fa01 ... e_cnt
	for (i = e_cnt; i--;) {
		var c = decim(i + 1, 2);
		var img = document.getElementById('anim_fi' + c);
		var a = document.getElementById('anim_fa' + c);
		if (img && a) e_mgr[i] = [a, img];
	}
//	play putton elements
//	- images: anim_bi01 ... cols
//	- anchors: anim_ba01 ... cols
//	button elements
	for (i = cols + 1; i--;) {
		var c = decim(i + 1, 2);
		var img = document.getElementById('anim_bi' + c);
		var a = document.getElementById('anim_ba' + c);
		if (img && a) {
		//	game title at page start
			if (i < cols) a.title = bc_ttl;
			a.style.cursor = 'pointer';
			b_mgr[i] = img;
			a_mgr[i] = a;
		}
	}
//	if (b_mgr[cols]) b_mgr[cols].title = '';
//	score text area
	pl_ta = document.getElementById('anim_ta');
	pf_info();
}
//	----------------------------------------
//	IMAGE LOAD / PRELOAD
//	----------------------------------------
//	play buttons
function init_buts () {
//	button images (buttons + 0 +  3 red)
	for (i = 0; i < (b_cnt + 4); i++) add_img(b_imgs, b_pre + b_names[i] + b_suf);
}
//	thumb nails on demand by given list
function mk_pre_list()
{
	if (pre_x) return;
	rndlist(pre_list, e_cnt, s_cnt);
	for (i = e_cnt; i--;) {
		n = pre_list[i];
		p_list[i] = n;
	//	image initialization on demand
		if (!s_imgs[n]) {
			var img = new Image();
			img.src = s_pre + s_pref + s_names[n] + s_suf;
			s_imgs[n] = img;
		}
	}
	pre_x = true;
}
//	mosaik section preload on demand
function mk_m_sec()
{
	if (!m_cnt) return;
//	create a new random list if necessary
	if (!m_list.length) rndlist(m_list, m_cnt);
	var m = m_list.shift();
	m_n = m_nums[m];
//	preload images
	if (!m_imgs[m]) {
		var a = [];
		var n1 = m_pre + m_pref + s_names[m_n] + '_';
		for (j = 1; j <= e_cnt; j++) add_img(a, n1 + decim(j, 2) + m_suf);
		m_imgs[m] = a;
	}
	m_sec = m_imgs[m];
}
//	add new image to a (preload) list
function add_img(a, sn)
{
	var img = new Image();
	img.src = sn;
	a.push(img);
}
//	create image link
//	- element position
//	- number of cat entry
//	- image
function mk_ilnk(p, n, img)
{
	var e = e_mgr[p];
	var ra = e[0];
	var ri = e[1];
	var t = s_titles[s_nt[n]];
	var h = s_heads[s_nh[n]];
	if (h) t = h + ' : ' + t;
	ra.href = h_pre + s_names[n] + h_suf;
	ri.title = t;
	ri.src = img.src;
}

//	----------------------------------------
//	SOUND department
//	----------------------------------------
//	events and sounds
//	0 snd_s : automatic shuffle
//	1 snd_g : start game shuffle
//	2 snd_p : play column
//	3 snd_b : bingo dialog sound

function init_snds()
{
	var a = ['s', 'g', 'p', 'b'];
	for (i = a.length; i--;) snds[i] = document.getElementById('snd_' + a[i]);
}

function play_snd(i)
{
	var w = snds[i];
	if (w) w.Play();
}


//	----------------------------------------
//	IMAGE SHUFFLING
//	----------------------------------------
//	play buttons shuffle
function shuffle_buts(p)
{
	if (p >= (b_cnt + cols -1)) {
		for (i = 0; i < cols; ++i) if (b_on[i]) b_mgr[i].src = b_imgs[0].src;
		return;
	}
	for (i = 0; i < b_cnt; ++i) {
		var s = p - i;
		if (s >= cols) continue;
		if (s < 0) break;
		b_mgr[s].src = b_imgs[i].src;
	}
	++p;
	window.setTimeout('shuffle_buts(' + p + ')', delay[0]);
}
//	the image / link shuffler
function shuffle(p, m, xa, xc)
{
	if (m < m_curr) return;
	var okn = true;
//	step
	var st = (xc ? cols : 1);
//	SHUFFLE START
//	(complete or column start)
	if (p == 0) {
		if (r_play) return next_shuffle(p, m, xa, xc, 1);
	//	sound
		play_snd(xc ? 2 : (xa ? 1 : 0));

	//	shuffle play buttons
		if (playing) shuffle_buts(0);

	//	create complete unique picture set if no column specified
		if (!xc) {
			pre_x = false;
			pf_reset();
			if (m_cnt && !xa) {
				if (m_w == 0) {
					m_w = m_wait;
					return mosaik(0, m);
				}
			}
			m_w = Math.max(0, m_w - 1);
		}
	//	otherwise (if column given)
	//	uniqueness within column aprechiated
		else {
			p = xc - 1;
			rndlist(c_list[p], rows, e_cnt);
			pf_cp_list(p);
		}
	}
//	assign new href and image
	var n = p_list[p];
	mk_ilnk(p, n, s_imgs[n]);
//	calculate new position
	p = Math.min(p + st, e_cnt) % e_cnt;
//	check for bingo at end
	if (p == 0) {
		if (xa) {
			pf_check() || pf_chances();
			pf_caps(true);
			okn = false;
		}
		xa = 0;
		xc = 0;
	}
	if (okn) next_shuffle(p, m, xa, xc, (p ? 0 : 1));
}
//	timeout of next shuffle
function next_shuffle(p, m, xa, xc, d)
{
	if (!(p || xc)) mk_pre_list();
	window.setTimeout('shuffle(' + p + ',' + m + ',' + xa + ',' + xc + ')', delay[d]);
}
//	----------------------------------------
//	MOSAIK SHUFFLE
//	----------------------------------------
function mosaik(p, m)
{
	if (m < m_curr) return;
	if (r_play && (p == 0)) return next_shuffle(0, m, 0, 0, 1);
	if (m_sec) mk_ilnk(p, m_n, m_sec[p]);
	else return next_shuffle(0, m, 0, 0, 0);
//	calculate new position
	p = (p + 1) % e_cnt;
	if (p) window.setTimeout('mosaik(' + p + ',' + m + ')', delay[0]);
	else {
		mk_m_sec();
		next_shuffle(0, m, 0, 0, 5);
	}
}

//	========================================
//	PLAY SECTION
//	----------------------------------------
//	the core: user clicks buttons
//	----------------------------------------
//	column play / new game buttons
function play(xc)
{
	if (!playing) return;
	++m_curr;
	var c = xc - 1;
//	click evaluation
	var on = b_on[c];
	var ch = pl_chs[c];
	var pbl = pf_playable();
//	zen play: was last click position kept (if possible)?
//	- all buttons on
//	- button is off (new game)
	if (pl_cl && ((pl_open == cols) || !on)) {
		++pl_zen[0];
		if (xc == pl_cl) {
			++pl_zen[1];
			++pl_zen[2];
		}
		else pl_zen[2] = 0;
	}
	pl_cl = xc;
//	lousy click alert
//	- game exit or zero chance click with chances given
	var ok = false;
	if (pl_cmax && !(on && ch)) {
		var a = [];
		for (i = cols; i--;) a = a.concat(pl_chsx[i]);
		pf_snap(c, bc_mis + ': ' + a.join(' '));
	}
//	- non playable click
	else if (on && !pbl) {
		pf_snap(c, bc_dbs);
	}
	else ok = true;
	if (!ok) pl_acc /= 2;

//	hit on playing button: unset play of button, play column
	if (on) {
		b_on[c] = false;
		--pl_open;
		shuffle(0, m_curr, 1, xc);
	}
//	non playing button pressed: switch on all players
	else pf_new();
//	game timeout
	window.setTimeout('pf_over(' + m_curr + ')', delay[2]);
}
//	snapshot replay button
function replay()
{
	pl_cl = 0;
	if (!p_snap) return;
	r_play = true;
	var
		bc = p_snap[0],
		msg = p_snap[1],
		pl = p_snap[2],
		bo = p_snap[3],
		ai = [],
		ab = []
	;
//	restore current, display snapped images
	for (var p = e_cnt; p--;) {
		var e = e_mgr[p];
		ai.push(e[1].src);
		e[1].src = s_imgs[pl[p]].src;
	}
//	restore current, display snapped buttons
	for (var c = cols; c--;) {
		var b = b_mgr[c];
		ab.push(b.src);
		b.src = b_imgs[bo[c] ? 0 : b_cnt - 1].src;
	}
	b_mgr[bc].src = b_imgs[b_cnt + (bo[bc] ? 1 : 2)].src;
	var ng = confirm(bc_rep + "\n\n" + msg + "\n\n" + bc_new + '?');
//	restore current
	if (!ng) {
		for (var p = e_cnt; p--;) e_mgr[p][1].src = ai.shift();
		for (var c = cols; c--;)  b_mgr[c].src = ab.shift();
	}
	r_play = false;
	if (ng) pf_new();
}
//	----------------------------------------
//	PLAY SUBS SECTION
//	----------------------------------------
//	play restart
function pf_new()
{
	pf_reset();
	++pl_cnt[0];
	pf_on(true);
	pf_ch_reset();
	pf_caps(true);
	mk_pre_list();
	pf_c_list();
	for (i = cols; i--;) pf_cp_list(i);
	shuffle(0, m_curr, 1, 0);
}
//	back to normal shuffle mode
function pf_over(m)
{
	if (m < m_curr) return;
	pf_on(false);
	pf_ch_reset();
	pf_caps(false);
	pl_cl = 0;
	shuffle(0, m, 0, 0);
}

//	error sbapshot and red button
function pf_snap(c, msg)
{
	++r_curr;
	a_mgr[cols].title = bc_rep;
	p_snap = [c, msg, [].concat(p_list), [].concat(b_on)];
	b_mgr[cols].src = b_imgs[b_cnt + 3].src;
	window.setTimeout('pf_red_off(' + r_curr + ')', delay[7]);
	window.setTimeout('pf_red_tt_off(' + r_curr + ')', 8000);
}
//	red button gray after short
function pf_red_off(r)
{
	if (r != r_curr) return;
	b_mgr[cols].src = b_imgs[b_cnt - 1].src;
}
//	red button off (snapshot extinguished)
function pf_red_tt_off(r)
{
	if (r != r_curr) return;
	b_mgr[cols].src = b_imgs[b_cnt].src;
	p_snap = false;
	a_mgr[cols].title = '';

}
//	complete set / unset of play buttons
function pf_on(s)
{
	for (i = cols; i--;) b_on[i] = s;
	pl_open = (s ? cols : 0);
}
//	play button captions
function pf_caps(ok)
{
	for (var c = cols; c--;) {
		if (pl_open && ok) pf_cap(c);
		else a_mgr[c].title = (ok ? bc_new : bc_ttl);
	}
}
//	one button caption sub
//	in the beginning (first 3 wins) with chances indicator
function pf_cap(c)
{
	var ht = '';
	if (pl_cnt[1] < 3)
		ht = bc_hint + (b_on[c] ?
			(pl_chs[c] ? (bc_pos + pl_chsx[c].join(' + ')) : (pl_cmax || !pf_playable() ? bc_no : bc_ok)) :
			(pl_cmax ? bc_no : bc_ok)
		);
	a_mgr[c].title = (b_on[c] ? bc_play : bc_new) + ht;
}
//	reset all current game values
function pf_reset()
{
	if (pl_x) {
		pf_info();
		pl_cnt = [0, 0, 0];
		pl_acc = 100;
		pl_zen = [0, 0, 0],
		pl_x = false;
	}
}
//	reset transfer list (game - columns)
function pf_c_list()
{
	n = 0;
	for (i = cols; i--;) {
		var a = [];
		for (j = rows; j--;) a.push(n++);
		c_list[i] = a;
	}
}
//	transfer game list to play list (using transfer list)
function pf_cp_list(c)
{
	var a = c_list[c];
	for (var j = rows; j--;) p_list[c + j * cols] = pre_list[a[j]];
}
//	----------------------------------------
//	three detection
//	----------------------------------------
//	three detection walk sub
var pl_steps = [
//	horizontal lines
	[0, 1, '--'],
//	top left to bottom right
	[1, 1, '\\'],
//	top right to bottom left
	[-1, 1, '/'],
//	vertical lines
	[1, 0, '|']
];
function pf_walk(fkt, par)
{
	for (var x = 0; x < 4; ++x) {
		var a = pl_steps[x];
		var
			sr = a[0],
			sc = a[1],
			cc = '[  ' + a[2] + '  ]';
		;
		var
			re = rows - Math.abs(sr) * (1 + sr),
			rs = Math.abs(sr) * (1 - sr),
			ce = cols - 2 * sc
		;
		for (var rx = rs; rx < re; ++rx) {
			for (var cx = 0; cx < ce; ++cx) {
				var av = [], ar = [], ac = [];
				for (var i = 0; i < 3; ++i) {
					var r = rx + i * sr;
					var c = cx + i * sc;
					var p = r * cols + c;
					ar.push(r);
					ac.push(c);
					av.push(p_list[p]);
				}
				if (!fkt(par, av, ar, ac, cc)) return;
			}
		}
	}
}


//	----------------------------------------
//	chances precalculation
//	----------------------------------------
//	three detection walk sub  - sub no. 2: chances accumulation
function pf_ch(par, av, ar, ac, cc)
{
//	column change required
	if (ac[1] == ac[0]) return false;
//	check button and surrounding columns
	for (var ib = 3; ib--;) {
		var b = ac[ib];
		if(!b_on[b]) continue;
		if (av[(ib + 1) % 3] == av[(ib + 2) % 3]) {
			++pl_chs[b];
			pl_chsx[b].push(cc);
		}
	}
	return true;
}
//	precalculation of current 1 strike win chances for each button
function pf_chances()
{
//	preconditions: 1 played, 1 to play
	pf_ch_reset();
	if (!pl_open) return;
	pf_walk(pf_ch);
	for (i = cols; i--;) pl_cmax = Math.max(pl_cmax, pl_chs[i]);
}

//	reset play chances precalculation
function pf_ch_reset()
{
	pl_cmax = 0;
	for (i = cols; i--;) {
		pl_chs[i] = 0;
		pl_chsx[i] = [];
	}
	return true;
}

//	calculation if possible chances left
//	for click evaluation:
//	must be done before decrease of pl_open
//	after calculation of strike win chances
function pf_playable()
{
//	easy:
//	- strike chance given
	if (pl_cmax) return true;
//	- strike chance given
//	- all buttons playable
	if (pl_open == cols) return true;
//	- one button left and no strike chance
	if (pl_open < 2) return false;
//	now not as easy:
//	- no current strike chance but more than 1 buttons playable
//	- easy when only 3 columns (standard)
	if (cols == 3) return true;
//	hard part for large games:
//	playable columns must be neighbours with no more gap than 1 column between
	var a = [];
	for (i = 0; i < cols; ++i) if (b_on[i]) a.push(i);
	for (i = 1; i < a.length; ++i) if ((a[i] - a[i - 1]) <= 2) return true;
	return false;
}

//	----------------------------------------
//	game win detection
//	----------------------------------------
//	three detection walk sub  - sub no. 1: simple detection
function pf_rw(par, av, ar, ac, cc)
{
	if ((av[1] == av[0]) && (av[2] == av[1])) par.push(cc);
	return true;
}
//	check and dialog
function pf_check()
{
	var rt = [];
	pf_walk(pf_rw, rt);
	var c = rt.length;
	if (c) {
//		alert('rt = ' + rt.join(' -- '));
		play_snd(3);
		++m_curr;
		pf_on(0);
	//	win count
		pl_cnt[1] += c;
	//	score claculation
		pl_cnt[2] += (c * Math.round(pl_acc / 10) * 10);
		pl_acc = 100;
	//	zen play
		pl_cl = 0;
		if (pl_zen[2] >= 20) pl_cnt[2] += 50;

		var tx = pf_txt("\n\n");
		var at = [rt.join(' '), tx];
		if (pl_cnt[1] == 3) at.push('( ' + bc_ntp + ' )');
		at.push(bc_print);
		var pr = confirm(at.join("\n\n"));
		if (pr) {
			pf_info(pf_txt('<br>'));
			window.print();
			pl_x = true;
		}
		pf_ch_reset();
		shuffle_buts(0);
		window.setTimeout('pf_over(' + m_curr + ')', delay[pr ? 6 : 2]);
	}
	return c;
}
//	standard text for dialog and print
function pf_txt(cs)
{
	return [
		bc_ttl,
		bc_three + ': ' + pl_cnt[1],
		bc_gms + ': ' + pl_cnt[0] + ' (' + float(pl_cnt[0] /  pl_cnt[1], 1) + ')',
		bc_score + ': ' + pl_cnt[2],
	//	zen play factor
		bc_zen + ': ' + float((pl_zen[0] > 0 ? pl_zen[1] / pl_zen[0] : 1) * 100, 1)
	].join(cs);
}
//	text to html page
function pf_info(tx)
{
	if (pl_ta) pl_ta.innerHTML = (tx ? tx : '');
}

//	========================================
//	LAUNCH
//	----------------------------------------
function start_animation()
{
	init_elems();
	init_buts();
	init_snds();
	mk_m_sec();
	next_shuffle(0,0,0,0,4);
	window.setTimeout('playing=true;', delay[3]);
}
window.onload = start_animation;

//	========================================
//	STANDARD FUNCTIONS
//	----------------------------------------
//	.000 float notation
function float(r, d)
{
	var f = Math.pow(10, d);
	r = Math.round(r * f) / f;
	var i = Math.floor(r);
//	this last "Math.round" due to machine error:
	return i + '.' + decim(Math.round((r - i) * f), d);
}

//	000 integer notation
function decim(i, d)
{
	var c = '' + i;
	for (; c.length < d;) c = '0' + c;
	return c;
}

//	create a random list
function rndlist(a, s, x)
{
	if (!x) x = s;
	var u = (x >= s);
	var d = [];
	for (var i = 0; i < s; ++i)  {
		var j = a[i];
		var n = Math.floor(Math.random() * x);
		for (var k = x; (k--) && (d[n] || (n == j));) n = (n + 1) % x;
		a[i] = n;
		d[n] = u;
	}
}


