Ext.ux.RowExpander = function(config){
    Ext.apply(this, config);

    this.addEvents({
        beforeexpand : true,
        expand: true,
        beforecollapse: true,
        collapse: true
    });

    Ext.ux.RowExpander.superclass.constructor.call(this);

    if(this.tpl){
        if(typeof this.tpl == 'string'){
            this.tpl = new Ext.Template(this.tpl);
        }
        this.tpl.compile();
    }

    this.state = {};
    this.bodyContent = {};
};

Ext.extend(Ext.ux.RowExpander, Ext.util.Observable, {
    header: "",
    width: 20,
    sortable: false,
    fixed:true,
    menuDisabled:true,
    dataIndex: '',
    id: 'expander',
    lazyRender : true,
    enableCaching: false,

    getRowClass : function(record, rowIndex, p, ds){
        p.cols = p.cols-1;
        var content = this.bodyContent[record.id];
        if(!content && !this.lazyRender){
            content = this.getBodyContent(record, rowIndex);
        }
        if(content){
            p.body = content;
        }
        return this.state[record.id] ? 'x-grid3-row-expanded' : 'x-grid3-row-collapsed';
    },

    init : function(grid){
        this.grid = grid;

        var view = grid.getView();
        view.getRowClass = this.getRowClass.createDelegate(this);

        view.enableRowBody = true;

        grid.on('render', function(){
            view.mainBody.on('mousedown', this.onMouseDown, this);
        }, this);
    },

    getBodyContent : function(record, index){
				if (record.data.time) {
					return '<p>Hier hast Du schon abgestimmt...</p>';
				}
				else {
					return '<p>Noch abstimmen!</p>';
				}
/*  		if(!this.enableCaching){
            return this.tpl.apply(record.data);
        }
        var content = this.bodyContent[record.id];
        if(!content){
            content = this.tpl.apply(record.data);
            this.bodyContent[record.id] = content;
        }
        return content;
*/  },

    onMouseDown : function(e, t){
        if(t.className == 'x-grid3-row-expander'){
            e.stopEvent();
            var row = e.getTarget('.x-grid3-row');
            this.toggleRow(row);
        }
    },

    renderer : function(v, p, record){
        p.cellAttr = 'rowspan="2"';
        return '<div class="x-grid3-row-expander">&#160;</div>';
    },

    beforeExpand : function(record, body, rowIndex){
        if(this.fireEvent('beforeexpand', this, record, body, rowIndex) !== false){
  					var cont = this.getBodyContent( record, rowIndex );
						if (typeof cont == 'string') {
	  					body.innerHTML = cont;							
						}
						else {
							cont.render(body);
						}

 /*        		if(this.tpl && this.lazyRender){
                body.innerHTML = this.getBodyContent(record, rowIndex);
            }
*/            return true;
        }else{
            return false;
        }
    },

    toggleRow : function(row){
        if(typeof row == 'number'){
            row = this.grid.view.getRow(row);
        }
        this[Ext.fly(row).hasClass('x-grid3-row-collapsed') ? 'expandRow' : 'collapseRow'](row);
    },

    expandRow : function(row){
        if(typeof row == 'number'){
            row = this.grid.view.getRow(row);
        }
        var record = this.grid.store.getAt(row.rowIndex);
        var body = Ext.DomQuery.selectNode('tr:nth(2) div.x-grid3-row-body', row);
        if(this.beforeExpand(record, body, row.rowIndex)){
            this.state[record.id] = true;
            Ext.fly(row).replaceClass('x-grid3-row-collapsed', 'x-grid3-row-expanded');
            this.fireEvent('expand', this, record, body, row.rowIndex);
        }
    },

    collapseRow : function(row){
        if(typeof row == 'number'){
            row = this.grid.view.getRow(row);
        }
        var record = this.grid.store.getAt(row.rowIndex);
        var body = Ext.fly(row).child('tr:nth(1) div.x-grid3-row-body', true);
        if(this.fireEvent('beforcollapse', this, record, body, row.rowIndex) !== false){
            this.state[record.id] = false;
            Ext.fly(row).replaceClass('x-grid3-row-expanded', 'x-grid3-row-collapsed');
            this.fireEvent('collapse', this, record, body, row.rowIndex);
        }
    }
});





Ext.ns( 'vote' );

vote.root = 'http://'+document.location.host+'/studentenschaft/code/vote/';

vote.exp = new Ext.ux.RowExpander();

vote.Votestore = function(config) {
	var config = config || {};
	Ext.applyIf(config, {
		proxy: new Ext.data.HttpProxy({
		    url: vote.root + 'runByUser.php'
		}),	
		reader: new Ext.data.JsonReader({	
	    		root: 'runs',
	    		idProperty: 'id'
			}, [
				'id','name', 'text',
				{name: 'till', type: 'date', dateFormat: 'Y-m-d h:i:s'},
				{name: 'time', type: 'date', dateFormat: 'timestamp'}, 'type'
		]),
		baseParams: {limit:20}
	});
	// call the superclass's constructor
	vote.Votestore.superclass.constructor.call(this, config);
};
Ext.extend(vote.Votestore, Ext.data.Store);

vote.Questionstore = function(config) {
	var config = config || {};
	Ext.applyIf(config, {
		proxy: new Ext.data.HttpProxy({
		    url: vote.root + 'questionsByRun.php'
		}),	
		reader: new Ext.data.JsonReader({	
	    		root: 'questions',
	    		idProperty: 'id'
			}, [
				'number', 'name', 'max', 'text'
		])
	});
	// call the superclass's constructor
	vote.Questionstore.superclass.constructor.call(this, config);	
};
Ext.extend(vote.Questionstore, Ext.data.Store);

vote.Answerstore = function(config) {
	var config = config || {};
	Ext.applyIf(config, {
		proxy: new Ext.data.HttpProxy({
			url: vote.root + 'answersByRun.php'
		}),
		reader: new Ext.data.JsonReader({
			root: 'answers',
			idProperty: 'id'
		}, [
			'question', 'number', 'name'
		])
	});
	// call the superclass's constructor	
	vote.Answerstore.superclass.constructor.call(this, config);
};
Ext.extend(vote.Answerstore, Ext.data.Store);


vote.Votepanel = Ext.extend(Ext.FormPanel, {
	constructor: function(config) {
        Ext.apply(this, {
			anchor: '-10 -10',
			bodyStyle: 'padding: 20px 60px 60px 60px',
			autoScroll: true,
			id: 'votepanel',
			border: true,
			items: []
        });
        vote.Votepanel.superclass.constructor.apply(this, arguments);
	},
	loadData: function(idnum) {
		questionMax = [];
		this.questionStore = new vote.Questionstore({storeId:'questionStoreId'});
		this.questionStore.load({params: {run: idnum}, callback: function(records, o, s){
			data = [];
			Ext.each(records, function(rec) {
				text = '<div>';
				text += (rec.get('text') == null) ? '' : rec.get('text')+'<br/>';
				text += 'maximal '+rec.get('max')+' Stimme(n)';
			   	data.push({
					xtype: 'fieldset',
					title: rec.get('name'), 
					id: 'question.'+rec.get('number'),
					items: [
						{xtype: 'fieldset', border: false, html: text, collapsible: true, collapsed: true}
					]
				});
				questionMax[rec.get('number')] = rec.get('max');
			});
			Ext.getCmp('votepanel').add(data);
			Ext.getCmp('votepanel').add({
				xtype: 'button', 
				id: 'sendbutton',
				text:'Senden',
				minWidth: 100,
				minHeight: 40, 
				handler: function(){
					Ext.Msg.show({
					   title:'Abstimmung einsenden?',
					   msg: 'Möchtest du die Abstimmung jetzt einsenden? Änderungen sind dann nichtmehr möglich.',
					   buttons: Ext.Msg.YESNO,
					   animEl: 'sendbutton',
					   icon: Ext.MessageBox.QUESTION,
					   fn: function(button){
						if (button == 'yes') {
							Ext.getCmp('votepanel').getForm().submit({
								url:vote.root+'saveVote.php', 
								waitMsg:'Speichere Abstimmung...', 
								submitEmptyText: true, 
								success: function(form, action) {
									v.store.reload();
									Ext.getCmp('votes').getLayout().setActiveItem(0);
									Ext.getCmp('abstimmung').setText("Zur Abstimmung");	
									Ext.getCmp('abstimmung').setIconClass('iconForward');
									Ext.Msg.alert('Erfolg', action.result.msg);																										
							    },
								failure: function(form, action) {
									switch (action.failureType) {
										case Ext.form.Action.CONNECT_FAILURE:
											Ext.Msg.alert('Fehler', 'Server nicht erreichbar');															
											break;
										case Ext.form.Action.SERVER_INVALID:
											Ext.Msg.alert('Fehler', action.result.msg);	
											break;
										default: 
											Ext.Msg.alert('Fehler', 'Unbekannter Fehler');
											break;
									}
								}
							});
						}
					}
					});
	        	}
	        });
			Ext.getCmp('votepanel').add({
				xtype: 'hidden',
				name: 'run',
				value: idnum
			});
			Ext.getCmp('votepanel').doLayout();
		}});
		this.answerStore = new vote.Answerstore({storeId:'answerStoreId'});
		this.answerStore.load({params: {run: idnum}, callback: function(records, o, s){
			data = {};
			Ext.each(records, function(rec) {
				if (rec.get('question') in data) {
				} else {
					data[rec.get('question')] = [];					
				}
				data[rec.get('question')].push({
					boxLabel: rec.get('name'), 
					name: 'question.'+rec.get('question')+'.answer.'+rec.get('number'), 
					handler: function(checkbox, checked) {
						if (checked) {	
							Ext.getCmp('question.'+rec.get('question')+'.neutralcheck').setValue(0); 
						}
						boxes = Ext.getCmp('answergroup.'+rec.get('question')).items.items;
						var values = 0;
						for (box in boxes) {
				            if(boxes[box].checked){
				                values++;
				            }
							if (typeof boxes[box] != 'function') {
								boxes[box].enable();
							}								
						}
						if (values == questionMax[rec.get('question')]) {
							for (box in boxes) {
								if(!boxes[box].checked) {
									if (typeof boxes[box] != 'function') {
										boxes[box].disable();
									}
								}
							}
						}																
					}
				});
			});
			
			for (question in data) {
				Ext.getCmp('question.'+question).add({
					xtype: 'checkboxgroup',
					columns: 1,
					id: 'answergroup.'+question,
					items: data[question]
				});
				Ext.getCmp('question.'+question).add({
					xtype: 'checkbox',
					boxLabel: 'Enthaltung',
					id: 'question.'+question+'.neutralcheck',
					checked: 1,
					handler: function(checkbox, checked) {
						if (checked) {
							num = checkbox.id.split('.');
//							boxes = Ext.getCmp('answergroup.'+num[1]).items.items[0].items.items;
							boxes = Ext.getCmp('answergroup.'+num[1]).items.items
							for (box in boxes) {
								if (typeof boxes[box] != 'function') {
									boxes[box].setValue(0);									
								}
							}
						}
					}
				});
				Ext.getCmp('question.'+question).doLayout();
			}		
		}});
	}, 
	questionStore: null,
	answerStore: null
});
Ext.reg('votepanel', vote.Votepanel);


vote.Votetable = Ext.extend(Ext.Viewport, {
	initComponent: function() {
		var config = {
				defaults: { border: false }
				,layout: 'ux.center'
				,items: [{
						 id: 'votes'
						,title: 'Aktuelle Wahlen und Abstimmungen'
						,iconCls: 'iconVote'
						,width: 600
						,border: true
						,bodyStyle: 'padding: 10px 10px 0 10px'
						,layout: 'card'
						,activeItem: 0
						,items: [
							{
							 	id: 'card-0'
								,border: false
								,layout: 'anchor'
								,items: [
								{
									height: 40
									,border: false
									,html: '<p>Bitte w&auml;hle die Abstimmung, die Du erf&uuml;llen willst!<br />(Klicke auf die entsprechende Zeile in der Tabelle um die zugeh&ouml;riger Abstimmung zu laden.)</p>'
								}								
								,{
									anchor: '-10 -10'
									,id: 'votegrid'
									,border: true
									,xtype: 'grid'
									,store: Ext.StoreMgr.get('voteStoreId') 
									,columns: [
										{header: 'Titel', dataIndex: 'name', width: 600}
										,{header: 'läuft bis', dataIndex: 'till', renderer: Ext.util.Format.dateRenderer('d.m h:i') }
										,{header: 'Abgestimmt am', dataIndex: 'time', renderer: Ext.util.Format.dateRenderer('d.m h:i')}
									]
									,viewConfig: {
										 forceFit: true
										,emptyText: 'Keine Wahlen/Abstimmungen gefunden' 
									}
									,sm: new Ext.grid.RowSelectionModel({singleSelect:true})
								}]
							}
							,{
								 id: 'card-1'
								,border: false
								,layout: 'anchor'
								,items: [{
										height: 40
										,border: false
										,html: '<p>Bitte w&auml;hle aus folgenden Optionen!<br />&nbsp;</p>'
									},{
										xtype: 'votepanel',
										id: 'votepanel'
									}
								]
							}
						]
						,bbar: [
							'->'
							,{
								 id: 'abstimmung'
								,text: 'Zur Abstimmung'
								,iconCls: 'iconForward'
								,handler:function() {
									if (Ext.getCmp('votes').getLayout().activeItem.id == 'card-0')
									{
										Ext.getCmp('votes').getLayout().setActiveItem(1);
										Ext.getCmp('abstimmung').setText("Übersicht");	
										Ext.getCmp('abstimmung').setIconClass('iconBack');																					
									}
									else if (Ext.getCmp('votes').getLayout().activeItem.id == 'card-1')
									{
										Ext.getCmp('votes').getLayout().setActiveItem(0);
										Ext.getCmp('abstimmung').setText("Zur Abstimmung");	
										Ext.getCmp('abstimmung').setIconClass('iconForward');																			
									}
								}
							}
							,{
								 id: 'card-prev'
								,text: 'Log-Out'
								,iconCls: 'iconOut'
								,handler: v.logout
							}
						]
					}]
		};
		
		Ext.apply(this, Ext.apply(this.initialConfig, config));		
		vote.Votetable.superclass.initComponent.apply(this, arguments);
	}
});

vote.Controller = function() {};
vote.Controller.prototype = {
	 user: null
	,viewport: null
	,store: null
	
	,setup: function() {
		this.store = new vote.Votestore({storeId:'voteStoreId'});
		this.store.load();
		this.viewport = new vote.Votetable();
		
		//set correct active card 
		Ext.getCmp('votes').getLayout().setActiveItem(0);
		Ext.getCmp('abstimmung').setText("Zur Abstimmung");	
		Ext.getCmp('abstimmung').setIconClass('iconForward');
		
		// autoselect first element in votegrid
		Ext.getCmp('votegrid').store.on('load', function(){
			var grid = Ext.getCmp('votegrid');
			grid.getSelectionModel().selectRow(0);
			grid.fireEvent('rowclick', grid, 0)
		}, this, {
			single: true
		});

		// glue votegrid and votepanel together
		Ext.getCmp('votegrid').getSelectionModel().on("rowselect", function(model, rowIndex, record) {
			Ext.getCmp('votepanel').removeAll();
			Ext.getCmp('votepanel').loadData(record.data.id);
		}, this);
		
		// votepanel check / uncheck logic
//		doAllCheckboxes();
		
	}
		
	,ready: function() {
		Ext.QuickTips.init();
		if (Ext.get('govote') != null) {
			Ext.get('govote').on('click', function(){
				new vote.login();
			}); 
		}
		var uri = document.location.toString();
		if (uri.match('#vote')) {
			new vote.login();
		}
	}
	
	,logout: function() {
		window.location = '/';
	}
	
	,onRowSelect: function(sm, rowIdx, r) {
	}
};

var v = new vote.Controller();
Ext.onReady( v.ready, v );

Ext.ns('Ext.ux.layout');
Ext.ux.layout.CenterLayout = Ext.extend(Ext.layout.FitLayout, {
	// private
    setItemSize : function(item, size){
        this.container.addClass('ux-layout-center');
        item.addClass('ux-layout-center-item');
        if(item && size.height > 0){
            if(item.width){
                size.width = item.width;
            }
            item.setSize(size);
        }
    }
});
Ext.Container.LAYOUTS['ux.center'] = Ext.ux.layout.CenterLayout;

Ext.ns( 'vote' );
vote.login = function() {
	this.win = new Ext.Window(
	{
		 title: 'Login zu den Wahlen'
		,iconCls: 'iconUser'
		,layout: 'fit'
		,width: 320
		,height: 190
/*		,closable: false */
		,constrain: true
		,defaultButton: 0
		,modal: true
		,plain: false
		,resizable: true

		,items: [
			{
				 xtype: 'form'
				,url: vote.root+'login.php'
				,method: 'POST'
				,labelWidth: 130
				,bodyStyle: 'padding: 7px'
				,items: [
					{
						 xtype: 'textfield'
						,id: 'login-user'
						,name: 'user'
						,fieldLabel: 'Matrikelnummer'
						,anchor: '0'
						,allowBlank: false
						,blankText: 'Bitte gib Deine Matrikelnummer ein!'
					}
					,{
						 xtype: 'textfield'
						,id: 'login-password'
						,name: 'password'
						,fieldLabel: 'Internet-Passwort'
						,inputType: 'password'
						,anchor: '0'
						,allowBlank: false
						,blankText: 'Bitte gib Dein Internet-Passwort ein!'
					}
					,{
						id: 'login-desc'
						,cls: 'formdesc'
						,border: false
						,html: '<hr /><h1>Wieso Log-In?</h1><p>Die Stimmen werden absolut anonym gespeichert! Das Log-In wird ausschliesslich zur Verhinderung von Mehrfach-Stimmen verwendet.</p>'
					}
				]
			}
		]

		,buttons: [
			{
				 text: 'Log-In'
				,id: 'login-OK'
				,type: 'submit'
				,scope: this
				,handler: function( button, event ) {
					this.win.getComponent(0).form.submit({
						 waitMsg: 'Logging in...'
						,scope: this
						,success: this.onSuccess
						,failure: this.onFailure
					});
				}
			}
		]
	}
);
	this.win.show();
};

vote.login.prototype = {
	 win: null
	,onSuccess: function( form, e ) {
		v.user = e.result['userdata'];
		v.setup();
		this.win.close();
	}
			
	,onFailure: function( form, e ) {
		if (form.failureType == Ext.form.Action.CONNECT_FAILURE) {
			Ext.MessageBox.alert( 'System Failure', 'Der Login-Dienst funktioniert zur Zeit leider nicht' );
		}
		else {
			Ext.MessageBox.alert( 'Login Failure', 'Login nicht erfolgreich' );
		}
	}
};


