(function() {

var H = H || {};
H.consts = {};

var date = new Date();
date.setHours(0,0,0,0);

var TODAY = date.getTime();
var ONEDAY = (1000*60*60*24);
var ONEWEEK = ONEDAY * 7;

var _ = function(arg) {
    try { 
        console.log.apply( console, arguments ); 
    } catch(e) { 
        try { 
            opera.postError.apply( opera, arguments ); 
        } catch(er){ 
            try {
                //debugbar
                console.log(arg); 
            } catch(er){
                //fail silently
            }
        } 
    } 
};

var initializing = false,
    fnTest = /xyz/.test(function(){xyz;}) ? /\b__super\b/ : /.*/,
    window = this,
    Class = function(){};

Class.extend = function(prop) {
    var __super = this.prototype;
    initializing = true;
    var proto = new this();
    initializing = false;
    for (var name in prop) { 
        proto[name] = typeof prop[name] == "function" && 
            typeof __super[name] == "function" && fnTest.test(prop[name]) ? 
        (function(name, fn){ 
            return function() { 
                var tmp = this.__super; 
                this.__super = __super[name]; 
                var ret = fn.apply(this, arguments);       
                this.__super = tmp; 
                return ret; 
            }; 
        })(name, prop[name]) : 
        prop[name]; 
    } 
    
    function Class() {
        if ( !initializing && this.__constructor ) {
            this.__constructor.apply(this, arguments);
        }
    }
    Class.prototype = proto;
    Class.constructor = Class;
    Class.extend = arguments.callee;
    return Class;
};

var Base = Class.extend({
	event_perma: function(hash) {
		// Match "#/<source>/<source_id>/", optional trailing slash
		match = hash.match(/^#\/(\w+)\/(\d+)\/{0,1}/);
		if (match) {
			source = match[1];
			source_id = match[2];
			return {source: source, source_id: source_id}
		}
		return null;
	},
    loop : function( elem, fn ) {
        var scope = this;
        if (typeof elem == 'number') {
            elem = new Array(elem);
        }
        jQuery.each(elem, function() {
            fn.call(scope, this);
        });
        return elem;
    },
    create : function( elem, className ) {
        if (!arguments.length) {
            return document.createElement('div');
        }
        if (arguments.length == 1) {
            className = arguments[0];
            elem = 'div';
        }
        var el = document.createElement(elem);
        el.className = className;
        return el;
    },
    getElements : function( selector ) {
        var elems = {};
        elems.length = 0;
        this.loop( jQuery(selector), function(elem) {
            Array.prototype.push.call( elems, elem );
        });
        return elems;
    },
    setStyle : function( elem, css ) {
        jQuery(elem).css(css);
        return elem;
    },
    disappear : function( elem ) {
        this.setStyle(elem, {
            position: 'absolute',
            left: '-10000px'
        });
    },
    appear : function( elem ) {
        this.setStyle(elem, {
            position: 'static',
            left: '0'
        }); 
    },
    mix : function( obj, ext ) {
        return jQuery.extend(obj, ext);
    },
    proxy : function( fn, scope ) {
        if ( typeof fn !== 'function' ) {
            return function() {};
        }
        scope = scope || this;
        return function() {
            return fn.apply( scope, Array.prototype.slice.call(arguments) );
        };
    },
    cloneNode : function( elem, bool ) {
        bool = bool || false;
        return jQuery(elem).clone(bool)[0];
    },
    listen : function( elem, type, fn ) {
        jQuery(elem).bind( type, fn );
    },
    forget : function( elem, type ) {
        jQuery(elem).unbind(type);
    },
    dispatch : function( elem, type ) {
        jQuery(elem).trigger(type);
    },
    jsonp : function( url, params, success ) {
        return jQuery.ajax({
            dataType: 'jsonp',
            data: params,
            method: 'get',
            url: url,
            success: this.proxy(success),
            error: function() {
                _(arguments);
            }
        });
    },
    wait : function(fn, callback, max) {
        fn = this.proxy(fn);
        callback = this.proxy(callback);
        max = max || 3000;
        var m = 0;
        window.setTimeout(function() {
            m += 1;
            if (fn() || m >= max) {
                callback();
                return false;
            }
            window.setTimeout(arguments.callee, 10);
        }, 10);
        return this;
    }
});

var Picture = Base.extend({
    
    __constructor : function() {
        this.image = new Image();
        this.elem = this.create('image');
        this.loaded = false;
        this.setStyle( this.elem, {
            overflow: 'hidden'
        } );
        this.elem.appendChild( this.image );
    },
    
    cache: {},
    
    load: function(src, callback) {
        callback = this.proxy( callback );
        //if ( this.cache[src] ) {
        //    var newImage = document.createElement("img");
        //    newImage.src = this.cache[src].src;
        //    this.image = newImage;
        //    this.elem.innerHTML = '';
        //    this.image.removeAttribute('width');
        //    this.image.removeAttribute('height');
        //    this.image.removeAttribute('style');
        //    jQuery(this.elem).html(this.image);
        //    callback( {target: this.image, scope: this} );
        //} else {
        this.image.src = src;
        this.cache[src] = this.image;
        //}
        if (this.loaded) {
            callback( {target: this.image, scope: this} );
            return this.image;
        }
        this.wait(function() {
            return (this.image.complete && this.image.width);
        }, function() {
            this.loaded = true;
            callback({ target: this.image, scope: this });
        });
        return this.image;
    },
    
    scale: function( width, height, crop ) {
        
        //upscale = upscale === false ? false : true;
        var iw = jQuery(this.image).width() || this.image.width,
            ih = jQuery(this.image).height() || this.image.width,
            ratio = Math[ (crop ? 'max' : 'min') ](width / iw, height / ih);
            
        this.setStyle(this.elem, {
            width: width,
            height: height,
            background:'#c83'
        });
        
        this.image.width = Math.ceil(iw * ratio);
        this.image.height = Math.ceil(ih * ratio);

        this.setStyle(this.image, {
            position : 'relative',
            top :  Math.round(this.image.height * -1 / 2 + (height / 2)),
            left : Math.round(this.image.width * -1 / 2 + (width / 2))
        });
    },
    
    clear: function() {
        this.image.src = '';
    }
});

var App = window.kvApp = Base.extend({
    __constructor: function(options) {

        // save title
        this.orig_title = document.title;
        
        // options
        this.options = this.mix({
            groups_on_init: 3,
            domain: '',
            url_list: '/geosearch/',
            url_detail: '/detail/',
            occasions_limit: 5,
            loaderImage: '/media/i/loader.gif',
            username: null,
            lang: 'sv',
            group_by: 'day',
            group_label: '%l %d %F',
            group_next_label: '+ Nästa dag',
            source_category: '',
            category: '',
            days_ahead: 30,
            distance: 35
        }, options);
        
        this.groups = [];
        this.target = null;
        //this.cities = [];
        this.lists = this.create('event-lists');
        //this.filter = null;
        this.overlay = jQuery('<div id="kv-app-modal-overlay">').hide()[0];
        this.modalwindow = jQuery('<div id="kv-app-modal-window">').hide()[0];
        this.modalcontent = jQuery('<div id="kv-app-modal-content">').appendTo(this.modalwindow)[0];
        //this.select = document.createElement("select");
        this.container = this.create();
        this.container.id = 'kv-app';
        this.form = this.create('event-filter');
        //this.current = this.options.groups_per_page;
        this.current = undefined;
        this.past = undefined;
        this.loader = this.create('loader');
        this.loader.id = 'kv-app-loader';
        var i = new Image();
        i.src = this.options.domain + this.options.loaderImage;
        this.loader.appendChild(i);
        jQuery(this.loader).hide();
        
        // create pluslink
        this.anchor = document.createElement('a');
        this.anchor.href = '#';
        this.anchor.className = 'morelink';
        
        this.location = document.createElement('h2');
        this.location.className = 'kv-location';
        
        this.location_title = document.createElement('span');
        this.location_title.className = 'kv-location-title';
        
        this.location_switch = document.createElement('a');
        this.location_switch.className = 'kv-location-switch';
        this.location_switch.href = '#';
        
        this.location.appendChild(this.location_title);
        this.location.appendChild(this.location_switch);

    },
    getIntervals : function(timestamp, amount) {
        var to = timestamp;
        amount = amount || 1;
        switch (this.options.group_by) {
            case 'day':
                to = timestamp + (ONEDAY * amount);
                break;
            case 'week':
                var d = new Date(timestamp);
                var f = 7 - d.getDay();
                var sunday = timestamp + ( f * ONEDAY );
                to = sunday + (ONEWEEK * amount);
                break;
            case 'month':
                var d = new Date(timestamp);
                var m = d.getMonth();
                m += amount;
                d.setMonth(m);
                d.setDate(1);
                to = d.getTime();
                break;
        }
        return to;
    },
    run: function(selector) {
        var run = this.proxy(function() {
            
            document.body.appendChild(this.overlay);
            document.body.appendChild(this.modalwindow);
            document.body.appendChild(this.loader);
            
            this.target = this.getElements( selector )[0];
            if (!selector || !this.target) {
                _('ERROR: Selector "'+selector+'" not found.');
                return;
            }
            this.target.appendChild(this.container);
            this.container.appendChild(this.location);
            this.container.appendChild(this.form);
            this.container.appendChild(this.lists);
            this.container.appendChild(this.anchor);
            
            var to = this.getIntervals(TODAY, this.options.groups_on_init);
            
            this.listen(this.location_switch, 'click', this.proxy(function(e) {
                e.preventDefault();
                this.showModal();
                this.setStyle(this.loader, { display: 'none' });
                var content = jQuery('<div class="kv-modal-switch"></div>');
                var search = jQuery('<input type="text" value="Sök ort">');
                var submit = jQuery('<input type="submit" class="btn" value="sök">');
                var results = jQuery('<div class="kv-modal-switch-results">').hide();
                
                var searchable = false;
                search.change(function() {
                    searchable = true;
                });
                
                var form = jQuery('<form>').bind('submit', this.proxy(function(e) {
                    e.preventDefault();
                    if (!searchable || !search.val().length) {
                        results.empty().hide();
                        return false;
                    }
                    this.jsonp(this.options.domain+'/citysearch/' + search.val() + '/', {}, function(data) {
                        if (!data.length) {
                            results.empty().show().append('Inga resultat.');
                            return;
                        }
                        results.empty().show();
                        this.loop(data, function(val) {
                            var a = document.createElement('a');
                            a.href="#";
                            a.rel=val.id;
                            a.innerHTML = val.city;
                            results.append(a);
                            this.listen(a, 'click', this.proxy(function(e) {
                                this.location_title.innerHTML = jQuery(e.target).text();
                                this.city_id = e.target.rel;
                                this.hideModal();
                                this.getData();
                            }));
                        })
                    })
                }));

                form.append(search,submit);
                content.append('<h3>Sök ort inom Västra Götaland:</h3>',form,results);
                this.modalwindow.className = 'kv-narrow';
                this.setStyle(this.modalwindow, {
                    display: 'block',
                    top: jQuery(document).scrollTop() + 150
                });
                jQuery(this.modalcontent).append(content);
                search.select().focus(function() {
                    search.select();
                })
            }));
            
            
            this.getData({
                datefrom: TODAY,
                dateto: to
            }, function(data) {
                this.location_title.innerHTML = data.geocity;
                this.location_switch.innerHTML = 'Byt stad';
                // date widget
                if (this.options.group_by == 'day') {
                
                    var addOption = this.proxy(function(select, value, key) {
                        key = key || value;
                        var o = jQuery('<option>').attr('value', value).text(key);
                        jQuery(select).append(o);
                        //this.select.options.appendChild(o);
                        //Array.prototype.push.call(this.select.options, o);
                    });
                    var date = new Date();
                    var forward = 7 - date.getDay();
                    var links = {
                        'idag' : [TODAY, TODAY + ONEDAY],
                        'imorgon' : [TODAY + ONEDAY, TODAY + (ONEDAY * 2) ],
                        'denna vecka' : [TODAY, TODAY + (ONEDAY * forward) ]
                    }
                    for (var link in links) {
                        var a = document.createElement('a');
                        a.innerHTML = link;
                        a.href = '#';
                        a.className = 'btn'
                        a.rel = links[link].join('-');
                        this.listen(a, 'click', this.proxy(function(e) {
                            jQuery(e.target).addClass('btn-active').siblings('.btn-active').removeClass('btn-active');
                            var timestamps = e.target.rel.split('-');
                            e.preventDefault();
                            this.getData({
                                datefrom: timestamps[0],
                                dateto: timestamps[1] || timestamps[0]
                            });
                        }));
                        this.form.appendChild(a);
                    }
                    
                    var input = document.createElement('input');
                    input.type = "text";
                    input.className="kv-datepicker";
                    var scope = this;
                    jQuery(input).datepicker({
                        dayNames: 'söndag måndag tisdag onsdag torsdag fredag lördag'.split(' '),
                        dayNamesMin: 'sö må ti on to fr lö'.split(' '),
                        dayNamesShort: 'sön mån tis ons tors fre lör'.split(' '),
                        monthNames: 'januari februari mars april maj juni juli augusti september oktober november december'.split(' '),
                        monthNamesShort: 'jan feb mar apr maj jun jul aug sep okt nov dec'.split(' '),
                        prevText: 'Föregående',
                        nextText: 'Nästa',
                        dateFormat: 'yy-mm-dd',
                        duration: 1,
                        onSelect: function(dateText, inst) {
                            jQuery(this.form).find('.btn-active').removeClass('btn-active');
                            var date = new Date();
                            date.setFullYear(dateText.substr(0,4));
                            date.setMonth(dateText.substr(5,2) - 1);
                            date.setDate(dateText.substr(8,2));
                            date.setHours(0,0,0,0);
                            var selected = date.getTime();
                            scope.getData({
                                datefrom: selected,
                                dateto: selected + ONEDAY
                            });
                        }
                    });
                    /*
                    var select = document.createElement('select');
                    for (var i = 0; i < this.options.days_ahead; i++) {
                        var d = TODAY + (i * ONEDAY);
                        var next = new Date(d);
                        var label = H.consts.weekdays[next.getDay()].substr(0,3) + ' ' +
                                    parseInt(next.getDate()) + ' ' + 
                                    H.consts.months[next.getMonth()] + ' ' + 
                                    next.getFullYear();
                        addOption(select, d, label);
                    }
                    this.listen(select, 'change', this.proxy(function(e) {
                        var selected = parseInt(jQuery(select).find(':selected').val());
                        jQuery(this.form).find('.btn-active').removeClass('btn-active');
                        this.getData({
                            datefrom: selected,
                            dateto: selected + ONEDAY
                        });
                    }));
                    */
                    var div = document.createElement('div');
                    div.className = 'kv-choose';
                    div.innerHTML = 'Välj datum: ';
                    //div.appendChild(select);
                    div.appendChild(input);
                    this.form.appendChild(div);
                }
            });
        });
        if (document.expando) { // if IE
            jQuery(run);
        } else {
            run();
        }
    },
    
    getData: function(params, callback, clear) {
        var url = this.options.domain + this.options.url_list;
        clear = typeof clear == 'undefined' ? true : false;
        params = jQuery.extend({
            username: this.options.username,
            lang: this.options.lang,
            group_by: this.options.group_by,
            group_label: this.options.group_label,
            source_category: this.options.source_category,
            category: this.options.category.split(','),
            datefrom: this.past,
            dateto: this.current,
            distance: this.options.distance
        }, params);
        
        if (this.city_id) {
            params.city_id = this.city_id
        }
        
        callback = this.proxy(callback);
        
        if (clear) {
            this.lists.innerHTML = '';
        }
        
        this.current = parseInt(params.dateto);
        this.past = parseInt(params.datefrom);
        
        jQuery(this.anchor).hide();
        
        this.jsonp(url, params, function(data) {
            jQuery(this.anchor).show();
            
            // put groups in this.groups
            this.groups = Array.prototype.slice.call(data.groups);
            H.consts.months = Array.prototype.slice.call(data.months);
            H.consts.weekdays = Array.prototype.slice.call(data.weekdays);

            var sunday = H.consts.weekdays.pop();
            H.consts.weekdays.unshift(sunday);
            
            // check for hash
            //var current = window.location.hash.replace(/^#\//,''); // Old
			var current = this.event_perma(window.location.hash);
			if (current) {
			    this.showEvent(current.source, current.source_id);
			}
			
			if(this.groups.length) {
    			for (var i=0; this.groups[i]; i++) {
                    var list = this.buildList( this.groups[i] );
                    this.lists.appendChild( list );
                }
            } else {
                var empty = jQuery('<div>').addClass('event empty').html('<strong>Inga resultat.</strong>');
                this.lists.appendChild(empty[0]);
            }
            
            this.anchor.innerHTML = this.options.group_next_label;
            this.forget(this.anchor, 'click');
            this.listen(this.anchor, 'click', this.proxy(function(e) {
                e.preventDefault();
                this.getData({
                    datefrom: this.current,
                    dateto: this.getIntervals(this.current)
                },null,false);
            }));
            callback(data);
        });
    },
    // builds the actual list
    buildList: function( group ) {

        var list = this.create('event-list');
        var title = document.createElement('h2');
        title.innerHTML = group.label;
        list.appendChild(title);
        
        // loop the events
        this.loop( group.events, function(item) {
            var block = this.create('event');
            var body = this.create('body');
            var image = this.create('photo');
        
            if (item['event'].image != undefined) {
                var img = new Picture();
        
                jQuery(img.image).show();
                //this.disappear( img.image );
                image.appendChild(img.elem);
            
                img.load( this.options.domain + item['event'].image, function(e) {
                    jQuery(e.target).show()
                });
            }

            var h3 = document.createElement('h3');
            var title = document.createElement('a');
			var source = item['event'].source;
			var source_id = item['event'].source_id;
            title.href = '#/' + source + '/' + source_id;
            title.innerHTML = item['event'].title;
            this.listen(title, 'click', this.proxy(function(e) {
                e.preventDefault();
                this.showEvent(source, source_id);
            }));
        
            h3.appendChild(title);

            // date & time formatting
            var formatDate = function(dt) {
                var d = dt.split('-').splice(1, 2);
                return d[1] + ' ' + H.consts.months[ parseInt(d[0], 10) -1 ];
            }
            var formatTime = function(t) {
                return ' kl. ' + t.split(':').splice(0, 2).join(':');
            }
            var formatWhen = function(when) {
                s = formatDate(when.start_date);
                if (when.start_time) {
                    s += formatTime(when.start_time);
                }
                return s;
            };

            var bodystring = '<p class="desc">' + item['event'].short_description + '</p>' +
                '<div class="meta">';
                // control when
            var dtstart = formatDate(item['event'].first_date.split(' ')[0]);
            var dtend = formatDate(item['event'].last_date.split(' ')[0]);
			var readable_datetime = item.when.readable_datetime;
            if (dtstart != dtend) {
				if (item.when.has_readable_datetime)
					bodystring += '<span class="time">' + readable_datetime + ' (pågår ' + dtstart + ' - '  + dtend + ')</span>';
				else
					bodystring += '<span class="time">' + formatWhen(item.when) + ' (pågår ' + dtstart + ' - '  + dtend + ')</span>';
            } else {
				if (item.when.has_readable_datetime)
					bodystring += '<span class="time">' + readable_datetime + '</span>';
				else
					bodystring += '<span class="time">' + formatWhen(item.when) + '</span>';
            }
            bodystring += '<span class="venue">' + item.venue.title + ', ' + item.venue.city + '</span>' +
            '</div>';
            
            body.innerHTML = bodystring;
            body.insertBefore(h3, body.firstChild);

            block.appendChild(image);
            block.appendChild(body);
    
            list.appendChild(block);
        });
        return list;
    },
    showModal: function(o) {
        if (typeof o == 'number') {
            this.setStyle(this.overlay, {opacity: o})
        } else {
            this.setStyle(this.overlay, {opacity: 0.6})
        }
        this.setStyle(this.overlay, { display: 'block' });
        this.setStyle(this.loader, { display: 'block' });
        
        var close = jQuery('<a href="#">Stäng</a>').addClass('close').bind('click', this.proxy(function(e) {
            e.preventDefault();
            this.hideEvent();
        })).appendTo(this.modalcontent);
        
        this.listen(document, 'keyup', function(e) {
            var key = e.keyCode || e.which;
            if (key == 27) {
                close.trigger('click');
            }
        });
        this.listen( this.overlay, 'click', function(e) {
            close.trigger('click');
        });
    },
    hideModal: function() {
        this.forget(document, 'keyup');
        this.forget(this.overlay, 'click');
        this.modalcontent.innerHTML = '';
        this.setStyle(this.overlay, { display: 'none' });
        this.setStyle(this.modalwindow, { display: 'none' });
        this.setStyle(this.loader, { display: 'none' });
        this.modalwindow.className = '';
    },
    showEvent: function(source, source_id) {
        
        if (typeof document.body.style.maxHeight === "undefined") { //if IE 6
        	jQuery("select").hide();
        }
        
        this.showModal();
        
        this.displayEvent(source, source_id);
    },
    displayEvent: function(source, source_id) {
		var perma = source + '/' + source_id + '/';
		var detail_url = this.options.domain + this.options.url_detail + perma;
        this.jsonp(detail_url, {}, function(data) {
            window.location.hash = '/' + perma;
            document.title = data.item['event'].title;
            this.buildEvent( data.item );
        });
    },
    hideEvent: function() {
        
        if (typeof document.body.style.maxHeight === "undefined") { //if IE 6
        	jQuery("select").show();
        }

        this.hideModal();

        window.location.hash = '#/';
        document.title = this.orig_title;
    },
    buildEvent: function(item) {
        if (!item) {
            return;
        }
        var parseTime = function(time) {
            return time ? time.replace(/^([0-9:]{5}).*/,' kl.$1') : '';
        };
        var friendlyDate = function(time) {
            var day = time.substr(8,2);
            var month = time.substr(5,2);
            if (month.substr(0,1) == '0') {
                month = month.substr(1,1);
            }
            month = parseInt(month);
            var year = time.substr(0,4);
            if (month) {
                return day + ' ' + H.consts.months[month-1].substr(0,3) + ' ' + year;
            } else {
                return time;
            }
        }
        var ul = document.createElement('ul');
        ul.className = 'event-dates';
        var index = 0;
        this.loop( item.when, this.proxy(function(ev) {
            var li = document.createElement('li');
            var ical = jQuery('<a class="ical">iCal</a>').attr("href", this.options.domain + "/cal/" + ev.id + "/");
            li.innerHTML = friendlyDate(ev.start_date) + parseTime(ev.start_time);
            jQuery(li).append(ical);
            ul.appendChild(li);
            index++;
            if (index > this.options.occasions_limit) {
                this.setStyle( li, {
                    display: 'none'
                });
            }
        }));
        
        var anchor;
        if (item.when.length > this.options.occasions_limit) {
            anchor = jQuery('<a>').bind('click', function(e) {
                e.preventDefault();
                jQuery(ul).children('li:hidden').each(function(i, el) {
                    if (i > 5) { return false; }
                    jQuery(el).show();
                });
            }).attr('href','#').text('+ fler tillfällen').addClass('innermore');
        }
        
        var _event = item['event'];
        
        var desc = '<p><strong class="preamble">' + item['event'].short_description + '</strong></p>';
        desc += item['event'].description_html;

        var img = new Image();
        var src = item.images[1] || item.images[0] || null;
        var adjust = this.proxy(function() {
            this.setStyle(this.modalwindow, {
                display: 'block',
                top: jQuery(document).scrollTop() + 50
            });
        })
        if (src) {
            jQuery(img).load(adjust).error(adjust).attr('src', this.options.domain + src);
        } else {
            img = null;
            adjust();
        }
        this.setStyle(this.loader,{display:'none'});
        var body = jQuery('<div class="modal-body-col">');
        if (img) {
            body.append(img);
        }
        body.append('<h2>' + item['event'].title + '</h2>' + desc);
        var sidebar = jQuery('<div class="modal-sidebar-col">');
        
        var content = {};
        var titles = {
            notes: 'Info',
            cost: 'Pris',
            open: 'Öppettider',
            conference: 'Konferens'
        };
        for (var i in titles) {
            var tar = item['event'][i] || (item['event'].extra && item['event'].extra[i]);
            if (tar) {
                sidebar.append('<h3>' + titles[i].toString() + '</h3><p>' + tar + '</p>');
            }
        }
        sidebar.append('<h3>Tillfällen</h3>');
        sidebar.append(ul);
        sidebar.append(anchor);
        
        var address = '<h3>Spelplats</h3><p>';
        if (item.venue.title) {
            address+='<strong>'+item.venue.title+'</strong><br>';
        }
        if (item.venue.address) {
            address+=item.venue.address+'<br>';
        }
        if (item.venue.city || item.venue.zip_code) {
            address+=item.venue.zip_code + ' ' + item.venue.city;
        }
        address+='</p>';
        if (item.venue.lon && item.venue.lat) {
            address+='<p><a href="http://maps.google.se/maps?q='+item.venue.lat+','+item.venue.lon+'" target="_blank">Karta</a></p>';
        }
        
        var directions = '';
        
        if(item['event'].extra) {
            if (item['event'].extra.directions) {
                directions = '<h3>Vägbeskrivning</h3><p>'+item['event'].extra.directions+'</p>';
            }
        }
        
        var contact = '<h3>Kontaktinformation</h3><p>';
        
        if (item['event'].phone) {
            contact+='<strong>Tel:</strong> '+item['event'].phone+'<br>';
        }
        if (item['event'].email) {
            contact+='<strong>Email:</strong> '+item['event'].email+'<br>';
        }
        if (item['event'].website) {
            var link = item['event'].website.match(/http:\/\//) ? item['event'].website : 'http://'+item['event'].website;
            contact+='<a href="'+link+'" target="_blank">'+item['event'].website+'</a><br>';
        }
        contact+='</p>';
        
        sharer = '<h3>Dela</h3><p class="addthis_toolbox addthis_default_style">'+
        '<a class="addthis_button_facebook"></a>'+
        '<a class="addthis_button_email"></a>'+
        '<a class="addthis_button_favorites"></a>'+
        '<a class="addthis_button_print"></a>'+
        '<span class="addthis_separator">|</span>'+
        '<a href="http://www.addthis.com/bookmark.php?v=250&amp;username=xa-4b7e98d12d239010" class="addthis_button_expanded">Mer</a>'+
        '</p>';
        
        sidebar.append(address + directions + contact + sharer);
        jQuery(this.modalcontent).append(body);
        jQuery(this.modalcontent).append(sidebar);
        addthis.toolbox('.addthis_toolbox');

    }
});

jQuery.fn.kvApp = function(options) {
    return this.each(function() {
        var app = new kvApp(options);
        app.run(this);
    });
};

})();
