function IKnow() {
	
	var self = this;
	
	// PUBLIC METHODS
	
	this.initialize = function () {
    //initializeCollapsables();
		initializeViewsMenu();
		if (window.wiweViewMode) { // view mode detected, exit
			return; 
		}
		initializeWiWeCollapsableProject();
		initializeFileUpload();
 		initializeTextInOut();
		initializeTAC();
		initializeIssueControl();
    //initializeDelphiWiWeSelection();
		initializeFilterProjects();
		initializeFillWiWe();
		initializeInputLengthControl();
    //initializeTagCloudSwitcher();
    //initializeCFToolTip();
    if (window.cfGraphicalButtons) {
		  window.cfGraphicalButtons.refreshButtons(dojo.query('.button'));
	  }
	};
	
	this.module = {}; // object with initialized modules

	// PRIVATE METHODS
	
	function initializeCollapsables() {
		self.module.collapsables = new Collapsables();
	}

	function initializeViewsMenu() {
		dojo.query('ul.filter-minor').connect('onmouseover',function(evt) {
			dojo.addClass(this,'hover');
		});
		dojo.query('ul.filter-minor').connect('onmouseout',function(evt) {
			dojo.removeClass(this,'hover');
		});
	}

	function initializeWiWeCollapsableProject() {
		self.module.projectInteractivity = new ProjectInteractivity();
	}
	
	function initializeFileUpload() {
		
		var isFileUpload = dojo.byId(FileUpload.mainBoxId);
	    if (!isFileUpload) {
	    	return; // file upload not available
	    }
		var canUpload = dojo.byId(FileUpload.addFileAddNewId);
	    
		if (canUpload) {
			var items = dojo.query('#' + FileUpload.mainBoxId + ' tr.uploaded-item');
			dojo.forEach(items, function(item) {
				item.obj = new FileUpload(item);
			});
	
			FileUpload.addFileTemplate = dojo.query('tr.' + FileUpload.addFileName)[0];
			dojo.addClass(FileUpload.addFileTemplate, 'hidden');
			var aNew = dojo.query('#' + FileUpload.addFileAddNewId + '-button')[0];
			dojo.connect(aNew,'onclick', FileUpload.addFile);
			FileUpload.addFile(false);
		}
	}
	
	function initializeTextInOut() {
		if (typeof window.wiweTextInOut === 'object') {
			var src = dojo.query('[name="' + window.wiweTextInOut.textIn + '"]')[0];
			if (!src) {
				return; // src does not exist
			}
			src.setAttribute('id', 'wiweTextIn');
			self.module.textInOut = new TextInOut('wiweTextIn',
			    window.wiweTextInOut.textOut, window.wiweTextInOut.prefix);
		}
	}
	
	function initializeTAC() {
		if (typeof window.wiweTAC === 'string') {
			var src = dojo.query('[name="' + window.wiweTAC + '"]')[0];
			if (!src) {
				return; // src does not exist
			}
			src.setAttribute('id', 'TACInput');
			// add TAC structure
			var elDiv = document.createElement('span');
			elDiv.setAttribute('id', 'TACmain');
			elDiv.innerHTML =
				'<span id="TACOut"><span id="TACResults"></span></span>';
			src.parentNode.appendChild(elDiv, src);
			var elDiv2 = document.createElement('span');
			elDiv2.setAttribute('id', 'TACinfo');
			src.parentNode.appendChild(elDiv2);
			// initialize TAC
			self.module.TAC = new TagAutoComplete({
				elemTextInput: 'TACInput',
				elemResults: 'TACResults',
				dictionary: 'wiweTagWords',
				keyPressDelay: 0,
				delimiter: ',',
				resLimit: 10
			});
			dojo.connect(self.module.TAC, "wordCountChanged", TACWordCount);
		}
	}
	
	function TACWordCount(count) {
		var elInfo = dojo.byId('TACinfo');
		if (!elInfo) {
			return;
		}
		if (count < 5) {
			elInfo.innerHTML = '<span class="error">please enter more tags</span>';
		} else if (count < 8) {
			elInfo.innerHTML = '<span class="ok">thank you</span>';
		} else {
			elInfo.innerHTML = '<span class="error">please enter only 5 to 7 tags (' + count + ' entered)</span>';
		}
	}
	
	function initializeIssueControl() {
		var el = dojo.byId('question-5');
		if (el) {
			self.module.issueControl =
				new WiweBankIssueControl('question-5');
		}
	}
	
	function initializeDelphiWiWeSelection() {
		
		if (typeof window.cookieNameWiWeDelphiSelection !== 'string') {
			return; // not in selection page, exit
		}
		
		dojo.require('dojo.cookie');
		
		self.module.ikdEnterForm =
			new ikdEnterForm({cookieName:window.cookieNameWiWeDelphiSelection,chbxClass:'wiwe-delphi-selection'});

	}
	
	function initializeFilterProjects() {
		var isf = dojo.query('.filter-projects');
		if (isf[0]) {
			self.module.ikFilterProjects = new ikFilterProjects();
		}
	}
	
	function initializeFillWiWe() {
		var isf = dojo.query('.ikd-wiwe-fill-projects');
		if (isf[0]) {
			self.module.ikdIssuesPopup = new ikdIssuesPopup();
			self.module.ikdFillWIWEs = new ikdFillWIWEs({
				projects: '.ikd-wiwe-fill-projects',
				wiwes: '.ikd-wiwe-fill-wiwes'}
			);
		}
	}
	
	function initializeInputLengthControl() {
	    if (!window.inputLengthControlNames) {
	        return;
	    }
	    //var names = ['textarea-7-44-0-70', 'textarea-8-45-0-71'];
	    var names = window.inputLengthControlNames;
	    var src = [];
        self.module.inputLengthControl = [];
	    for (var i = 0; i < names.length; i++) {
	        src = dojo.query('textarea[name="' + names[i] + '"]')[0];
    	    if (src) {
    	        if (!dojo.attr(src, 'id')) {
    	            dojo.attr(src, 'id', names[i]);
    	        }
    	        var nel = dojo.create('span',{
    	            id: names[i] + '-info-id'
    	        });
    	        dojo.place(nel, src.parentNode, src);
        	    self.module.inputLengthControl.push(new CFInputLengthControl({
        	        inputID: dojo.attr(src, 'id'),
        	        echoID: names[i] + '-info-id',
        	        minChars: 0, 
        	        maxChars: 250,
        	        maxCrop: true,
        	        showCounts: true,
        	        showAlerts: true,
        	        minString: 'minimum of #min# characters is allowed',
        	        readyString: 'written #act# characters of #max# allowed', 
        	        maxString: 'maximum of #max# characters is allowed',
        	        minClass: 'ilc-warning', 
        	        readyClass: 'ilc-ready',
        	        maxClass: 'ilc-error'
        	   }));
    	    }
	    }
	}
	
	function initializeTagCloudSwitcher() {
	    if (!window.tagCloudSwitcher) {
	        return;
	    }
	    self.module.tagCloudSwitcher = new TagCloudSwitcher({
	        0:{title:'All tags',tags:window.tagCloudSwitcher.all},
	        1:{title:'Wild Cards',tags:window.tagCloudSwitcher.wildCards},
	        2:{title:'Weak Signals',tags:window.tagCloudSwitcher.weakSignals},
	        sel:window.tagCloudSwitcher.defSelected,
	        width: window.tagCloudSwitcher.width,
	        height: window.tagCloudSwitcher.height,
	        divId: window.tagCloudSwitcher.divId
	    });
	}
	
	function initializeCFToolTip() {
// FIXME initialize
//	    self.module.CFToolTip = new CFToolTip(null,null);
//	    self.module.CFToolTip.init({group:'default',ttclass:'cftooltip cftooltip-red',forced:false,width:0,margin:5});
//	    self.module.CFToolTip.init({group:'default',position:'T',width:0});
//	    self.module.CFToolTip.init({group:'img',query:'a',ttclass:'cftooltip cftooltip-red',position:'L',forced:false,width:0,margin:5});
	}
	
}

function Collapsables() {
	
	var self = this;
	
	this.toggleCollapsed = function(ev) {
		var target;
		
		target = ev.target || ev.srcElement;
		while (target) {
			if (dojo.hasClass(target, 'collapsableHead')) {
				dojo.toggleClass(this, 'collapsed');
				dojo.stopEvent(ev || window.event);
				target = null;
			} else if (dojo.hasClass(target, 'collapsable')) {
				target = null;
			} else {
				target = target.parentNode;
			}
		}
	};
	
	this.unselectable = function () { // FIXME
		return false;
	};
	
	// constructor
	return function() {
		dojo.query('.collapsable').connect('onclick', self.toggleCollapsed);
	}();
	
}

function ProjectInteractivity() {
	
	var self = this;
	var selPid = 0;
	this.div = {};
	this.projects = {};
	
	function getThemesForProject(pid) {
		var themes = [];
		dojo.forEach(self.projects, function (item, idt) {
			if (1 * item.id === 1 * pid) {
				themes = item.themes; 
			}
		});
		return themes;
	}
	
	function getSubthemesForTheme(pid, tid) {
		var themes = getThemesForProject(pid);
		var subthemes = [];
		dojo.forEach(themes, function (item, idt) {
			if (1 * item.id === 1 * tid) {
				subthemes = item.subthemes; 
			}
		});
		return subthemes;
	}
	
	function buildSelectOptions(inpName, div, items, sel) {
		if (items.length) {
			var isel = dojo.query('select[name="' + inpName + '"]', div)[0];
			dojo.create('option', {value: 0, innerHTML: 'Please select...'}, isel);
			dojo.forEach(items, function (item, idt) {
				if (1 * item.id === 1 * sel) {
					dojo.create('option', {value: item.id, innerHTML: item.title,
						selected: 'selected'}, isel);
				} else {
					dojo.create('option', {value: item.id, innerHTML: item.title}, isel);
				}
			});
			return true;
		}
		return false;
	}

	function buildThemes(pid, sel) {
		var items = getThemesForProject(pid);
		removeThemes();
		showThemes(buildSelectOptions(self.div.inpThemesName, self.div.themes, items, sel));
	}

	function buildSubthemes(pid, tid, sel) {
		var items = getSubthemesForTheme(pid, tid);
		removeSubthemes();
		showSubthemes(buildSelectOptions(self.div.inpSubthemesName, self.div.subThemes, items, sel));
	}

	function getValueFromRadioGroup(inpName, div) {
		var iid = 0;
		var items = dojo.query('input[name="' + inpName + '"]', div);
		dojo.forEach(items, function(item, idp) {
			if (item.checked) {
				iid = item.value;
			}
		});
		return iid;
	}
	
	function setValueInRadioGroup(inpName, div, value) {
		var iid = 0;
		var items = dojo.query('input[name="' + inpName + '"]', div);
		dojo.forEach(items, function(item, idp) {
			item.checked = item.value === value;
		});
		return iid;
	}
	
	function getValueFromSelect(inpName, div) {
		var iid = 0;
		var item = dojo.query('select[name="' + inpName + '"]', div)[0];
		if (item.selectedIndex >= 0) {
			iid = item.options[item.selectedIndex].value;
		}
		return iid;
	}
	
	function getProject() {
		var cpid = getProjectId();
		var project = null;
		dojo.forEach(self.projects, function(item, idp) {
			if (1 * item.id === 1 * cpid) {
				project = item;
			}
		});
		return project;
	}
	
	function getProjectId() {
		return getValueFromRadioGroup(self.div.inpProjectsName, self.div.projects);
	}

	function setProjectId(pid) {
		return setValueInRadioGroup(self.div.inpProjectsName, self.div.projects, pid);
	}

	function getThemeId() {
		return getValueFromSelect(self.div.inpThemesName, self.div.themes);
	}
	
	function getSubthemeId() {
		return getValueFromSelect(self.div.inpSubthemesName, self.div.subThemes);
	}
	
	function showItem(div, show) {
		if (show) {
			dojo.removeClass(div, 'hidden');
		} else {
			dojo.addClass(div, 'hidden');
		}
	}
	
	function showAllProjectsButton(show) {
		showItem(self.div.showAll, show);
	}
	
	function showThemes(show) {
		showItem(self.div.themes, show);
	}

	function showSubthemes(show) {
		showItem(self.div.subThemes, show);
	}

	function showBoxOptional(show) {
		showItem(self.div.optional, show);
	}

	function showBoxSource(show) {
		showItem(self.div.source, show);
	}
	
	function showOneProject(pid) {
		if (selPid === pid) {
			return;
		}
		var prjs = dojo.query('label', self.div.projects);
		dojo.forEach(prjs, function(item, idx) {
			var pinp = dojo.query('input', item)[0];
			if (pinp.value === pid) {
				selPid = pid;
			} else {
				dojo.addClass(item, 'hidden');
			}
		});		
		var project = getProject();
		if (project !== null) {
			showBoxOptional(project.isOptional);
			showBoxSource(project.isSource);
		}
		showAllProjectsButton(true);
	}
	
	function showAllProjects(evt) {
		dojo.stopEvent(evt);
		var prjs = dojo.query('label', self.div.projects);
		dojo.forEach(prjs, function(item) {
			dojo.removeClass(item, 'hidden');
		});		
		showAllProjectsButton(false);		
	}
	
	function removeSelectItems(inpName, div) {
		dojo.query('select[name="' + inpName + '"] option', div).forEach(dojo.destroy);
	}

	function removeThemes() {
		removeSelectItems(self.div.inpThemesName, self.div.themes);
	}
	
	function removeSubthemes() {
		removeSelectItems(self.div.inpSubthemesName, self.div.subThemes);
	}
	
	function selectProjectChanged(evt) {
		var cpid = this.value;
		if (1 * selPid === 1 * cpid) {
			return;
		}
		// ask confirmation of resetting the Optional and Source fields
		var opt = dojo.query('textarea', self.div.optional)[0];
		var src = dojo.query('textarea', self.div.source)[0];
		if (opt.value.length || src.value.length) {
			if (!confirm('Changing project will reset References and Source fields.\nDo you wish to continue?')) {
				setProjectId(selPid);
				return;
			}
			opt.value = '';
			src.value = '';
		}
		showOneProject(cpid);
		buildThemes(cpid);
		buildSubthemes(cpid, 0);
	}

	function selectThemeChanged(evt) {
		buildSubthemes(getProjectId(), this.value);
	}

	// constructor
	return function() {
		
		if (typeof window.iKnowWiWeProjectsDefinitions === 'undefined') {
			return; // data not available, do not use this module
		}
		
		// add Show All option
		var elDiv = document.createElement('div');
		var prjs = dojo.byId(window.iKnowWiWeProjectsDefinitions.boxProjects);
		elDiv.setAttribute('id', window.iKnowWiWeProjectsDefinitions.projectsShowAll);
		elDiv.innerHTML = '<a href="javascript: void(0);" class="button">show all projects</a>';
		//prjs.appendChild(elDiv);
		dojo.place(elDiv,dojo.query('table',prjs)[0],'before');
		dojo.addClass(elDiv, 'hidden');

		// sets used elements
		self.div = {
			projects: dojo.byId(window.iKnowWiWeProjectsDefinitions.boxProjects),
			themes: dojo.byId(window.iKnowWiWeProjectsDefinitions.boxThemes),
			subThemes: dojo.byId(window.iKnowWiWeProjectsDefinitions.boxSubThemes),
			optional: dojo.byId(window.iKnowWiWeProjectsDefinitions.boxOptional),
			source: dojo.byId(window.iKnowWiWeProjectsDefinitions.boxSource),
			showAll: dojo.byId(window.iKnowWiWeProjectsDefinitions.projectsShowAll),
			inpProjectsName: window.iKnowWiWeProjectsDefinitions.inpProjectsName,
			inpThemesName: window.iKnowWiWeProjectsDefinitions.inpThemesName,
			inpSubthemesName: window.iKnowWiWeProjectsDefinitions.inpSubthemesName,
			inpOptionalName: window.iKnowWiWeProjectsDefinitions.inpOptionalName,
			inpSourceName: window.iKnowWiWeProjectsDefinitions.inpSourceName
		};
		self.projects = window.iKnowWiWeProjects;
		
		// activate project selection
		var prjs = dojo.query('input[name="' + self.div.inpProjectsName + '"]',self.div.projects);
		dojo.forEach(prjs, function(item, idp) {
			dojo.connect(item, 'onclick', selectProjectChanged);
		});
		
		// activate theme selection
		dojo.connect(dojo.query('select[name="' + self.div.inpThemesName + '"]', self.div.themes)[0], 'onchange', selectThemeChanged);

		// activate show all projects button
		dojo.connect(dojo.query('a', self.div.showAll)[0], 'onclick', showAllProjects);

		var cpid = getProjectId();
		if (cpid > 0) {
			showOneProject(cpid);
			var ctid = getThemeId();
			if (ctid > 0) {
				buildThemes(cpid, ctid);
				var csid = getSubthemeId();
				buildSubthemes(cpid, ctid, csid);
			}
		}
	}();
};

function FileUpload(item) {
	
	var self = this;
	
	var id, title, aDel, aRen, aCancel, sInput, sNewname;
	
	function deleteFile(evt) {
		dojo.stopEvent(evt);
		dojo.toggleClass(item, 'deleted');
		if (dojo.hasClass(item, 'deleted')) {
			aDel.innerHTML = 'restore';
			dojo.place('<input type="hidden" name="' + FileUpload.itemPrefix +
				'delete[]" value="' + id + '" class="iDelete" />', item);
		} else {
			aDel.innerHTML = 'delete';
			dojo.query('input.iDelete', item).orphan();
		}
	}

	function renameFile(evt) {
		dojo.stopEvent(evt);
		dojo.toggleClass(item, 'rename');
		if (dojo.hasClass(item, 'rename')) {
			dojo.place('<input type="text" value="' + title + '" class="iRenameTemp" />', sInput);
		} else {
			title = dojo.query('.iRenameTemp', item)[0].value;
			dojo.query('input.iRenameTemp', item).orphan();
			dojo.query('span.title', item)[0].innerHTML = title;
			if (dojo.query('.iRename', item)[0]) {
				dojo.query('.iRename', item)[0].value = title;
			} else {
				dojo.place('<input type="hidden" name="' + FileUpload.itemPrefix +
					'rename[' + id + ']" value="' + title + '" class="iRename" />', sNewname);
			}
		}
	}
	
	function renameFileCancel(evt) {
		dojo.stopEvent(evt);
		if (dojo.query('input.iRenameTemp', item)[0]) {
			dojo.toggleClass(item, 'rename');
			dojo.query('input.iRenameTemp', item).orphan();
		}
	}

	return function() {
		
		id = item.id.substring(FileUpload.itemPrefix.length);
		title = dojo.query('span.title', item)[0].innerHTML;

		aDel = dojo.query('span.delete a', item)[0];
		aRen = dojo.query('span.rename a', item)[0];
		aCancel = dojo.query('span.cancel a', item)[0];
		sInput = dojo.query('span.input', item)[0];
		sNewname = dojo.query('span.newname', item)[0];

		dojo.connect(aDel, 'onclick', deleteFile);
		dojo.connect(aRen, 'onclick', renameFile);
		dojo.connect(aCancel, 'onclick', renameFileCancel);

	}();
	
};

FileUpload.mainBoxId = 'file-upload-box';
FileUpload.itemPrefix = 'file-item-';
FileUpload.addFileName = 'file-new-upload';
FileUpload.addFileAddNewId = 'file-add-new';
FileUpload.addFileTemplate = null;
FileUpload.addFile = function(evt) {
	if (evt !== false) {
		dojo.stopEvent(evt);
	}
	var newItem = dojo.clone(FileUpload.addFileTemplate);
	dojo.removeClass(newItem, 'hidden');
	dojo.place(newItem, dojo.byId(FileUpload.addFileAddNewId), 'before');
};

function TextInOut(src, dest, prefix) {
	
	var self = this;

	// rewrite source text to final destination with prefix
	this.srcToDest = function() {
		var val = self.src.value;
		if (val.length > 0 && self.prefix !== null) {
			val = self.prefix + ' ' + val;
		}
		self.dest.innerHTML = val;
	};

	// handle key pressing
	return function() {
		self.src = dojo.byId(src);
		self.dest = dojo.byId(dest);
		if (!self.src || !self.dest) {
			return; // source and/or destination does not exist
		}
		self.prefix = prefix;
		dojo.connect(self.src, 'onkeyup', self.srcToDest);
	}();
	
}

function WiweBankIssueControl(div) {
	var self = this;

	// shows first hidden row
	this.addNextRow = function() {
		var rows = dojo.query('tr.hide',self.eDiv);
		if (rows.length) {
			dojo.removeClass(rows[0],'hide');

			// showing last row hides adding button
			if (rows.length === 1) {
				dojo.style(self.eButton,{display:'none'});
			}
		}
	};

	this.emptyRow = function(row) {
		var isEmpty = true;

		// textarea check
		dojo.query('textarea',row).forEach(function(item) {
			if (item.value.length>0) {
				isEmpty = false;
			}
		});

		// select boxes check
		dojo.query('select',row).forEach(function(item) {
			if (item.value>0) {
				isEmpty = false;
			}
		});

		return isEmpty;
	};

	// hides empty rows
	this.hideEmptyRows = function() {
		var rows = dojo.query('tr',self.eDiv);
		// closing empty rows from the end until first row
		for (var i=rows.length-1;i>1;i--) {
			// empty row check
			if (self.emptyRow(rows[i])) {
				dojo.addClass(rows[i],'hide');
			} else {
				break;
			}
		}
	};

	this.addButton = function() {
		// adds button
		var hRows = dojo.query('tr.hide',self.eDiv);
		if (hRows.length) {
			// creates button
			self.eButton = dojo.create('a',{href:'#',title:'','class':'button',innerHTML:'Add new Issue'});
			dojo.setSelectable(self.eButton,false);
			// places button to structure
			var where = dojo.query('.content-in br',self.eDiv)[0];
			dojo.place(self.eButton,where,'before');
			// handles adding button
			dojo.connect(self.eButton,'onclick',function(evt) {
				self.addNextRow();
				evt.preventDefault();
			});
		}
	};

	// constructor
	return function() {
		self.eDiv = dojo.byId(div);

		// closes empty rows
		self.hideEmptyRows();
		// adds button
		self.addButton();
	}();
}

function ikdEnterForm(opts) {
	var self = this;

	// handles box checking
	this.control = function(e) {
		// inserts or removes item
		if (e.checked) {
			self.insertItem(e.value);
		} else {
			self.removeItem(e.value);
		}
		// stores in cookie
		self.storeCookie();
	};

	// inserts item to list
	this.insertItem = function(val) {
		// looks for WI-WE id in array
		var i = dojo.indexOf(self.data,val);

		// only if not in array
		if (i === -1) {
			self.data.push(val);
		}
		return true;
	};

	// removes item from list
	this.removeItem = function(val) {
		// looks for WI-WE id in array
		var i = dojo.indexOf(self.data,val);

		// only if id is present
		if (i !== -1) {
			self.data.splice(i,1);
		}
		return true;
	};

	// stores list in cookie
	this.storeCookie = function() {
		var data = self.data.join(';');
		dojo.cookie(self.cookieName,data,{path:'/'});
	};

	// constructor
	return function() {
		// sets SID
		self.cookieName = opts.cookieName;
	 	// pre-selected data is taken from cookie
		if (dojo.cookie(self.cookieName)) {
			if (dojo.cookie(self.cookieName).length) {
				self.data = dojo.cookie(self.cookieName).split(';');
			} else {
				self.data = [];
			}
		} else {
			self.data = [];
		}

		// initialize checkboxes
		if (self.data.length) {
			dojo.query('input.'+opts.chbxClass).forEach(function(item) {
				if (dojo.indexOf(self.data,item.value) !== -1) {
					item.checked = true;
				} else {
					item.checked = false;
				}
			});
		}

		// handles checkboxes
		dojo.query('input.'+opts.chbxClass).connect('onclick',function(evt){
			self.control(this);
		});
	}();
}

function ikFilterProjects() {
	var self = this;

	this.showThemes = function(e) {
		dojo.query('.qf-projects').addClass('hide');
		dojo.query('.qf-themes-inspired').removeClass('hide');
		dojo.query('.qf-themes-related').addClass('hide');
		dojo.query('.qf-subthemes').addClass('hide');

		dojo.query('.qf-themes-inspired .qf-themes-item').addClass('hide');
		dojo.query('.qf-themes-inspired .'+e.rel).removeClass('hide');

		dojo.query('.qf-themes-related .qf-themes-item').addClass('hide');
		dojo.query('.qf-themes-related .'+e.rel).removeClass('hide');
	};

	this.showSubthemes = function(e) {
		dojo.query('.qf-projects').addClass('hide');
		dojo.query('.qf-themes-inspired').addClass('hide');
		dojo.query('.qf-themes-related').addClass('hide');
		dojo.query('.qf-subthemes').removeClass('hide');

		dojo.query('.qf-subthemes .qf-subthemes-item').addClass('hide');
		dojo.query('.qf-subthemes .'+e.rel).removeClass('hide');
	};

	this.switchInsRel = function() {
		var e = dojo.query('.qf-themes-inspired')[0];
		if (dojo.hasClass(e,'hide')) {
			dojo.query('.qf-themes-inspired').removeClass('hide');
			dojo.query('.qf-themes-related').addClass('hide');
		} else {
			dojo.query('.qf-themes-inspired').addClass('hide');
			dojo.query('.qf-themes-related').removeClass('hide');
		}
	};

	// constructor
	return function() {
		// project selected, show themes
		dojo.query('.qf-projects a.next').connect('onclick',function(evt) {
			self.showThemes(evt.target);
			dojo.stopEvent(evt);
		});

		// switching between Inspired / Related
		dojo.query('.qf-themes-inspired a.insrel,.qf-themes-related a.insrel').connect('onclick',function(evt) {
			self.switchInsRel();
			dojo.stopEvent(evt);
		});

		// theme selected, shows subtheme
		dojo.query('.qf-themes-inspired a.next').connect('onclick',function(evt) {
			self.showSubthemes(evt.target);
			dojo.stopEvent(evt);
		});

	}();
}

//controls filtering & checkboxes
function ikdFillWIWEs(opts) {
	var self = this;
 
	this.handleFilter = function() {
		dojo.query('a',self.eProjects).connect('onclick',function(evt) {
			var link = this;
			// highlight selected project
			dojo.query('a',self.eProjects).removeClass('active');
			dojo.addClass(this,'active');
			// shows selected project and hides other projects
			dojo.query('tr.item',self.eWiwes).forEach(function(item) {
				if (dojo.hasClass(item,link.rel) || link.rel === 'all') {
					dojo.removeClass(item,'hide');
				} else {
					dojo.addClass(item,'hide');
				}
			});
			// stops default behavior
			dojo.stopEvent(evt);
		});
	};
 
	// first checkbox unchecks the others
	this.checkNone = function(e,chBoxes) {
		if (e.checked) {
			dojo.query('input',chBoxes).forEach(function(i,key) {
				if (key>0) {
					i.checked = false;
				}
			});
		}
	};
 
	// any others checkbox unchecks first one
	this.checkOthers = function(e,chBoxes) {
		if (e.checked) {
			dojo.query('input',chBoxes)[0].checked = false;
		}
	};
 
	this.handleCheckboxes = function() {
		dojo.query('tr.item td.checkboxes',self.eWiwes).forEach(function(chBoxes) {
			dojo.query('input',chBoxes).forEach(function(e,key) {
				// first checkbox behaves differently from the others
				if (key === 0) {
					dojo.connect(e,'onclick',function(evt) {
						self.checkNone(e,chBoxes);
					});
				} else {
					dojo.connect(e,'onclick',function(evt) {
						self.checkOthers(e,chBoxes);
					});
				}
			});
		});
	};
 
	// constructor
	return function() {
		// options
		self.eProjects = dojo.query(opts.projects)[0];
		self.eWiwes = dojo.query(opts.wiwes)[0];
 
		// handlers
		self.handleCheckboxes();
		self.handleFilter();
	}();
};
 
//controls popups
function ikdIssuesPopup() {
	var self = this;
	this.link = null; 
 
	this.showPopup = function(e) {
		var target = dojo.query('.'+e.rel)[0];
		var popup = dojo.query('.ikd-popup')[0];
		var iframe = dojo.query('.ikd-iframe')[0];
 
		dojo.query('.ikd-overlay').removeClass('hide');
		dojo.place(target,popup,'first');
		dojo.removeClass(target,'hide');
		dojo.removeClass(popup,'hide');
 
		var box = dojo.coords(popup);
		var pSize = self.getPageSize();
		var pScroll = self.getPageScroll();
		// center box & iframe
		var left = pScroll[0] + pSize[0]/2 - box.w/2;
		var top = pScroll[1] + pSize[1]/2 - box.h/2;
		dojo.style(popup,{left:left+'px',top:top+'px'});
		dojo.style(iframe,{left:left+'px',top:top+'px'});
 
		// iframe (IE6)
		dojo.removeClass(iframe,'hide');
		dojo.style(iframe,{width:box.w+'px',height:box.h+'px'});
 
		self.link = e;
	};
 
	this.closePopup = function() {
		var popup = dojo.query('.ikd-popup')[0];
		var target = dojo.query('.'+self.link.rel)[0];
		var iframe = dojo.query('.ikd-iframe')[0];
 
		dojo.addClass(popup,'hide');		
		dojo.addClass(target,'hide');
		dojo.place(target,self.link,'after');
		dojo.addClass(iframe,'hide');
		dojo.query('.ikd-overlay').addClass('hide');
 
		self.link = null;
	};
 
	// http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
	this.getPageSize = function() {
	  var myWidth = 0, myHeight = 0;
	  if( typeof( window.innerWidth ) == 'number' ) {
	    //Non-IE
	    myWidth = window.innerWidth;
	    myHeight = window.innerHeight;
	  } else if( document.documentElement && ( document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
	    //IE 6+ in 'standards compliant mode'
	    myWidth = document.documentElement.clientWidth;
	    myHeight = document.documentElement.clientHeight;
	  } else if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
	    //IE 4 compatible
	    myWidth = document.body.clientWidth;
	    myHeight = document.body.clientHeight;
	  }
		return [myWidth,myHeight];
	};
 
	// http://www.howtocreate.co.uk/tutorials/javascript/browserwindow
	this.getPageScroll = function() {
	  var scrOfX = 0, scrOfY = 0;
	  if( typeof( window.pageYOffset ) == 'number' ) {
	    //Netscape compliant
	    scrOfY = window.pageYOffset;
	    scrOfX = window.pageXOffset;
	  } else if( document.body && ( document.body.scrollLeft || document.body.scrollTop ) ) {
	    //DOM compliant
	    scrOfY = document.body.scrollTop;
	    scrOfX = document.body.scrollLeft;
	  } else if( document.documentElement && ( document.documentElement.scrollLeft || document.documentElement.scrollTop ) ) {
	    //IE6 standards compliant mode
	    scrOfY = document.documentElement.scrollTop;
	    scrOfX = document.documentElement.scrollLeft;
	  }
	  return [ scrOfX, scrOfY ];
	};
 
	// creates overlay & popup container
	this.createPopupContainer = function() {
		var html = '<div class="ikd-overlay hide"></div>';
		html += '<iframe frameborder="0" class="ikd-iframe hide"></iframe>';
		html += '<div class="ikd-popup hide">';
		html += '<p style="margin-top:1em;text-align:center;">';
		html += '<a href="#" title="" style="font-size:18px;" class="ikd-popup-close">Close</a>';
		html += '</p>';
		html += '</div>';
		dojo.place(html,dojo.body(),'first');
	};
 
	// constructor
	return function() {
		if (dojo.query('div.ikd-wiwe-fill-wiwes a.ikd-issues-popup').length > 0) {
			self.createPopupContainer();
 
			dojo.query('div.ikd-wiwe-fill-wiwes a.ikd-issues-popup').connect('onclick',function(evt) {
				self.showPopup(this);
				dojo.stopEvent(evt);
			});
 
			dojo.query('a.ikd-popup-close,.ikd-overlay').connect('onclick',function(evt) {
				self.closePopup();
				dojo.stopEvent(evt);
			});
		}
	}();
}

// control input length
function CFInputLengthControl(params) {
    //
    var self = this;
    this.defParams = {inputID:'',echoID:'',minChars:0,maxChars:255,maxCrop:true,showCounts:true,showAlerts:true,minString:'',readyString:'#act#',maxString:'',minClass:'warning',readyClass:'ready',maxClass:'error'};
    this.items = Array();

    // initialize
    this.init = function() {
        // transform object into array with one item
        if (dojo.isObject(params) && !dojo.isArray(params)) {
            params = [params];
        }
        // load all params into self.items, adding events and first check
        var i=0;
        for (var item in params) {
            self.items[i] = Object();
            var actual = self.items[i];
            for (var param in self.defParams) {
                actual[param] = ((params[i][param]||params[i][param]===false)?params[i][param]:self.defParams[param]);
            }
            if (actual.inputID.length>0) actual.inputElem = dojo.byId(actual.inputID);
            if (actual.echoID.length>0) actual.echoElem = dojo.byId(actual.echoID);
            //
            actual.inputElem.CFInputLengthControlCheck = self.check;
            actual.inputElem.CFInputLengthControlPosition = i;
            //dojo.connect(actual.inputElem,'onkeypress',null,self.check);
            //dojo.connect(actual.inputElem,'onchange',null,self.check);
            //dojo.connect(actual.inputElem,'onkeydown',null,self.check);
            dojo.connect(actual.inputElem,'onkeyup',null,self.check);
            //dojo.connect(actual.inputElem,'onfocus',null,self.check);
            //dojo.connect(actual.inputElem,'onblur',null,self.check);
            self.check(null,actual.inputElem);
            i++;
        }
    };
      
    //
    this.check = function(e,thisElem) {
        if (e && (e.modifiers || e.ctrlKey || e.altKey || e.shiftKey)) return false;
        if (!thisElem) thisElem = this;
        var actual = self.items[thisElem.CFInputLengthControlPosition];
        var outtext = (actual.showCounts?actual.readyString:'');
        var state = true;
        dojo.addClass(actual.echoElem,actual.readyClass);
        //
        if (actual.inputElem.value.length<actual.minChars && actual.minChars>0) {
            dojo.removeClass(actual.echoElem,actual.readyClass);
            dojo.addClass(actual.echoElem,actual.minClass);
            outtext = (actual.showAlerts?actual.minString:'');
            state = false;
        } else {
            dojo.removeClass(actual.echoElem,actual.minClass);
        }
        //
        if (actual.inputElem.value.length>actual.maxChars && actual.maxChars>0) {
            dojo.removeClass(actual.echoElem,actual.readyClass);
            dojo.addClass(actual.echoElem,actual.maxClass);
            outtext = (actual.showAlerts?actual.maxString:'');
            state = false;
            if (actual.maxCrop) {
                actual.inputElem.value = actual.inputElem.value.substr(0,actual.maxChars);
            }
        } else {
            dojo.removeClass(actual.echoElem,actual.maxClass);
        }
        //
        if (actual.echoElem) {
            outtext = outtext.replace('#min#',actual.minChars);
            outtext = outtext.replace('#max#',actual.maxChars);
            outtext = outtext.replace('#act#',actual.inputElem.value.length);
            actual.echoElem.innerHTML = outtext;
        }
        return state;
    };

    // constructor
    return function() {
        self.init();
    }();
      
}

function TagCloudSwitcher(opts) {
    var self = this;
    this.block = null;
    this.flash = null;
    this.opts = 0;
    
    // generates navigation
    this._genNavigation = function(sel) {
        // generates navigation
        var html = '<table><tr><td class="tcs-all"><a href="#" title="" rel="0">'+self.opts[0].title+'</a></td><td class="tcs-wi"><a href="#" title="" rel="1">'+self.opts[1].title+'</a></td><td class="tcs-we"><a href="#" title="" rel="2">'+self.opts[2].title+'</a></td></tr></table>';
        dojo.place(html,self.block,'last');
    
        // events
        dojo.query('table a',self.block).connect('onclick',function(evt) {
            self._clickNavigation(this.rel);
            dojo.stopEvent(evt);
        });
    };
    
    this._setNavigation = function(sel) {
        // settings
        dojo.query('.tag-cloud-switcher a').removeClass('active');
        dojo.addClass(dojo.query('.tag-cloud-switcher a')[sel],'active');
    };
    
    // generates flash object
    this._genFlash = function(sel) {
        var tags = self.opts[sel].tags;
    
        // destroys
        self.flash.innerHTML = '';
        // inserts
        var so = new SWFObject("/swf/tagcloud.swf", "tagcloud", opts.width, opts.height, "7", "#fff");
        so.addParam("wmode", "transparent");
        so.addVariable("hicolor", "0xff0000");
        so.addVariable("tcolor", "0x006db9");
        so.addVariable("tcolor2", "0x0085c9");
        so.addVariable("mode", "tags");
        so.addVariable("distr", "true");
        so.addVariable("tspeed", "200");
        so.addVariable("tagcloud", "<tags>"+tags+"</tags>");
        so.write(opts.divId);
    };
    
    // generates flash object
    this._clickNavigation = function(sel) {
        //self.sel = sel;
    
        self._genFlash(sel);
        self._setNavigation(sel);
    };
    
    // constructor
    return function() {
        self.opts = opts;
        
        // tag options
        self.opts.width = opts.width ? opts.width : 250;
        self.opts.height = opts.height ? opts.height : 250;
        self.opts.divId = opts.divId ? opts.divId : 'tag-cloud-switcher';

        self.block = dojo.query('.' + opts.divId)[0];
        self.flash = dojo.byId(opts.divId);
    
        self._genNavigation(opts.sel);
        self._setNavigation(opts.sel);
        self._genFlash(opts.sel);
    }();
}

function WIWEMenu() {
	return function() {
		dojo.query('div.topmenu li.parent').forEach(function(item) {
			new WIWEMenuItem(item);
		});
	}();
}

function WIWEMenuItem(elem) {
	var self = this;
	this.timer = null;
	this.elem = null;
	this.sub = null;
	this.height = 0;
	this.anim = false;

	this._show = function() {
		clearTimeout(self.timer);
		if (!self.anim) {
			self.anim = true;
			dojo.animateProperty({node:self.sub, duration:400, properties:{height:self.height}, onEnd:function(){self.anim = false;}}).play();
		}
	};

	this._hide = function() {
		self.timer = setTimeout(function(){self._hideSub();},500);
	};

	this._hideSub = function() {
		dojo.animateProperty({node:self.sub, duration:200, properties:{height:0}}).play();
	};

	return function() {
		self.elem = elem;
		var sub = dojo.query('ul.sub',self.elem);
		if (sub.length) {
			self.sub = sub[0];
			self.height = sub[0].offsetHeight;
			dojo.style(sub[0],{height:'0px',overflow:'hidden'});
		} else {
			self.sub = null;
		}
	
		dojo.connect(self.elem,'onmouseover',function(){
			if (self.sub !== null) {
				self._show();
			}
		});

		dojo.connect(self.elem,'onmouseout',function(){
			if (self.sub !== null) {
				self._hide();
			}
		});
	}();
}

function switchQuickScan(e,cl) {
	if (cl === true || e.value === 'Quick scan') {
		e.value = '';
	} else if (e.value === '') {
		e.value = 'Quick scan';
	}
}

window.iKnow = new IKnow();
dojo.addOnLoad(window.iKnow.initialize);
dojo.addOnUnload(function(){});
