var $id = function(id){
    return document.getElementById(id);
}

var $create = function(name){
    return document.createElement(name);
}

$hasClass = function(ele,cls) {
    try{
		 var has = (ele.className) ? ele.className.match(new RegExp('(\\s|^)'+cls+'(\\s|$)','g')) : false;
		 return has;
    }
    catch(e){
        throw "element has no class attribute";
    }
}

$toggleClass = function(ele,cls) {
    if($hasClass(ele,cls)){
        $removeClass(ele,cls);
    }
    else{
        $appendClass(ele,cls);
    }
}

$appendClass = function(ele,cls) {
	if (!$hasClass(ele,cls)) {
		ele.className += ((!ele.className.length) ? '':" ")+cls;
	}
}

$removeClass = function(ele,cls) {
    if ($hasClass(ele,cls)) {
        var reg = new RegExp('(\\s|^)'+cls+'(\\s|$)','g');
        ele.className = ele.className.replace(reg,' ');
    }
}

function insertAfter(node, referenceNode) {
  referenceNode.parentNode.insertBefore(node, referenceNode.nextSibling);
}

function deepObjCopy(dupeObj) {
    var retObj = new Object();
    if (typeof(dupeObj) == 'object') {
        if (typeof(dupeObj.length) != 'undefined')
            var retObj = new Array();
        for (var objInd in dupeObj) {   
            if (typeof(dupeObj[objInd]) == 'object') {
                retObj[objInd] = deepObjCopy(dupeObj[objInd]);
            } else if (typeof(dupeObj[objInd]) == 'string') {
                retObj[objInd] = dupeObj[objInd];
            } else if (typeof(dupeObj[objInd]) == 'number') {
                retObj[objInd] = dupeObj[objInd];
            } else if (typeof(dupeObj[objInd]) == 'boolean') {
                ((dupeObj[objInd] == true) ? retObj[objInd] = true : retObj[objInd] = false);
            }
        }
    }
    return retObj;
}

Object.extend(Date, {
  parseToObject: function(string) {
    var date = Date.parse(string);
    if (!date) return null;
    date = new Date(date);
    return (date == 'Invalid Date' || date == 'NaN') ? null : date.neutral();
  }
});

Object.extend(Date.prototype, {
  // modified from http://alternateidea.com/blog/articles/2008/2/8/a-strftime-for-prototype
  strftime: function(format) {
    var day = this.getDay(), month = this.getMonth();
    var hours = this.getHours(), minutes = this.getMinutes();
    function pad(num) { return num.toPaddedString(2); };

    return format.gsub(/\%([aAbBcdHImMpSwyY])/, function(part) {
      switch(part[1]) {
        case 'a': return Locale.get('dayNames').invoke('substring', 0, 3)[day].escapeHTML(); break;
        case 'A': return Locale.get('dayNames')[day].escapeHTML(); break;
        case 'b': return Locale.get('monthNames').invoke('substring', 0, 3)[month].escapeHTML(); break;
        case 'B': return Locale.get('monthNames')[month].escapeHTML(); break;
        case 'c': return this.toString(); break;
        case 'd': return pad(this.getDate()); break;
        case 'H': return pad(hours); break;
        case 'I': return (hours % 12 == 0) ? 12 : pad(hours % 12); break;
        case 'm': return pad(month + 1); break;
        case 'M': return pad(minutes); break;
        case 'p': return hours >= 12 ? 'PM' : 'AM'; break;
        case 'S': return pad(this.getSeconds()); break;
        case 'w': return day; break;
        case 'y': return pad(this.getFullYear() % 100); break;
        case 'Y': return this.getFullYear().toString(); break;
      }
    }.bind(this));
  },

  neutral: function() {
    return new Date(this.getFullYear(), this.getMonth(), this.getDate(), 12);
  }
});


function f_clientWidth() {
	return f_filterResults (
		window.innerWidth ? window.innerWidth : 0,
		document.documentElement ? document.documentElement.clientWidth : 0,
		document.body ? document.body.clientWidth : 0
	);
}
function f_clientHeight() {
	return f_filterResults (
		window.innerHeight ? window.innerHeight : 0,
		document.documentElement ? document.documentElement.clientHeight : 0,
		document.body ? document.body.clientHeight : 0
	);
}
function f_scrollLeft() {
	return f_filterResults (
		window.pageXOffset ? window.pageXOffset : 0,
		document.documentElement ? document.documentElement.scrollLeft : 0,
		document.body ? document.body.scrollLeft : 0
	);
}
function f_scrollTop() {
	return f_filterResults (
		window.pageYOffset ? window.pageYOffset : 0,
		document.documentElement ? document.documentElement.scrollTop : 0,
		document.body ? document.body.scrollTop : 0
	);
}
function f_filterResults(n_win, n_docel, n_body) {
	var n_result = n_win ? n_win : 0;
	if (n_docel && (!n_result || (n_result > n_docel)))
		n_result = n_docel;
	return n_body && (!n_result || (n_result > n_body)) ? n_body : n_result;
}

var currentNodeRefId = 'category:0';
function treeclick(e){
	targ = e.target || e.srcElement;

	//console.log(targ)

	if(targ.tagName == 'A'){
		
		// clear the class for the last link
		var par = document.getElementById(currentNodeRefId);
				par.className = '';
		
		// set the class on this link to selected
		targ.className = 'selected';
		currentNodeRefId = targ.id;
		
		// the selected is a link in level 2
		if(targ.parentNode.parentNode.parentNode.className == 'parent selected'){
			// abort here so we dont hide parent trees
			select_category_onchange(true);
			return false;
		}
		
		// the last was a link in level 2
		if(par.parentNode.parentNode.parentNode.className == 'parent selected'){
			par.parentNode.parentNode.parentNode.className = 'parent'
			// hide level 2
		}
		// the last was a link in level 1
		else {
			par.parentNode.className = 'parent'
			// hide level 1
		}
		
		// the selected is a link in level 2
		if(targ.parentNode.parentNode.parentNode.className == 'parent'){
			targ.parentNode.parentNode.parentNode.className = 'parent selected';
			// stick level 2
			select_category_onchange(true);
			return false;
		}
		// the selected is a link in level 2
		else {
			// stick level 1
			targ.parentNode.className = 'parent selected';
		}
		
		
		select_category_onchange(true)
		return false;
		/* e.stopPropagation();
		e.preventDefault();
		return false; */
		//document.getElementById(currentNodeRefId).className = ''
	}
	
}

function days_between(date1, date2) {

    // The number of milliseconds in one day
    var ONE_DAY = 1000 * 60 * 60 * 24

    // Convert both dates to milliseconds
    var date1_ms = date1.getTime()
    var date2_ms = date2.getTime()

    // Calculate the difference in milliseconds
    var difference_ms = Math.abs(date1_ms - date2_ms)
    
    // Convert back to days and return
    return Math.round(difference_ms/ONE_DAY)

}


var current_page = 1;
var tries = 0;
var filters = {
    start:null,
    end:null,
    category:'0',
    city:'all',
    distance:50,
    dindex:0,
    page:1,
    
    set_category:function(category_id, category_name){
        // update only if required
        if(this.category == category_id){ 
            return;
        }
        
        this.category = category_id;
        
        this.reset_page();
        updateSet();
        
        _gaq.push(['_trackEvent', 'Events', 'Select category', category_name])
    },
    
    set_city:function(city_id, city_name){
        // update only if required
        if(this.city == city_id){ 
            return;
        }
        
        this.city = city_id;
        
        this.reset_page();
        updateSet();
        
        _gaq.push(['Events', 'Select city', city_name + ' - ' + this.distance])
    },
    
    set_distance:function(distance){
        // update only if required
        if(this.distance == distance){
            return;
        }
        
        this.distance = distance;
        
        this.reset_page();
        updateSet();
        
        _gaq.push(['Events', 'Select distance', filters.distance])
    },
    
    set_date:function(start, end, forced){
        // update only if required
        if(this.start && this.end && this.start == start && this.end == end){
            return;
        }
        
        this.start = start.strftime('%Y-%m-%d');
        this.end = end.strftime('%Y-%m-%d');
        
        this.reset_page();
        updateSet(forced);
        
        _gaq.push(['Events', 'Select date', filters.start+' - '+filters.end])
    },
    
    set_page:function(page){
        this.page = page;
        current_page = page;
        
        updateSet();
    },
    
    set_dindex:function(v){
        this.dindex = v;
    },
    
    unserialize:function(d, forced){
        if(d.start.length == 0 || d.end.length == 0){
            //console.log('Dates',d.start.length, d.end.length);
            var s = now;
            var e = future;
            this.start = s.strftime('%Y-%m-%d');
            this.end = e.strftime('%Y-%m-%d');
        }
        else {
            try{
                var s = parse_iso_date(d.start);
                var e = parse_iso_date(d.end);
            }
            catch(e){
            }
            // if start is less than now, make start now, and end in same proportion
            if(s < reset_time(now)){
                var delta = days_between(s, e)
                
                this.start = now.strftime('%Y-%m-%d')
                this.end = new Date();
                this.end.setDate(this.end.getDate() + delta);
                this.end = this.end.strftime('%Y-%m-%d')
                
                add_search_history()
            }
            else {
                this.start = d.start;
                this.end = d.end;
            }
        }
        
        
        
        
        
        this.category = d.category;
        this.city = d.city;
        this.distance = d.distance;
        this.page = d.page;
        this.dindex = d.dindex;
        
        updateSet(forced);
    },
    
    serialize:function(){
        return {
            start:this.start,
            end:this.end,
            category:this.category,
            city:this.city,
            distance:this.distance,
            page:this.page,
            dindex:this.dindex
        }
    },
    
    reset_page:function(){
        this.page = 1;
        current_page = 1;
    }
    
};

function reset_time(d){
    d.setHours(0);
    d.setMinutes(0);
    d.setSeconds(0);
    return d;
}

function parse_iso_date(s){
    var ymd = s.split('-');
    
    //console.log(parseInt(ymd[0], 10), parseInt(ymd[1], 10)-1, parseInt(ymd[2], 10))
    var d = new Date();
    d.setYear(parseInt(ymd[0], 10))
    d.setMonth(parseInt(ymd[1], 10)-1)
    d.setDate(parseInt(ymd[2], 10))
    
    return reset_time(d);
}

/* Event handlers */

function show_select_distance(){
    $id('box-select-distance').style.display = 'block';
}

function hide_select_distance(){
    $id('box-select-distance').style.display = 'none';
}

function select_city_onchange(){
    var select_city = $id('select-city');
    var city = select_city.options[select_city.selectedIndex];
    
    var city_id = city.value;
    var city_name = city.text;
    
    if(city_id == 'all'){
        hide_select_distance();
    }
    else {
        show_select_distance();
    }
    
    filters.set_city(city_id, city_name)
    
    if(city_id != 'all'){
        regeo(text);
    }
}

function select_distance_onchange(update){
    var select = document.getElementById('select-distance');
    
    filters.set_distance(select.options[select.selectedIndex].value)
}

function select_category_onchange(update){
    
    var catnode = document.getElementById(currentNodeRefId);
    
    if(!catnode){
        return false
    }
    
    var name = catnode.innerHTML;
    
    filters.set_category(currentNodeRefId.split(':')[1], name);
}

function xlat_date_range(v){
    switch(v){
        case 'today':        
            return [new Date(), new Date(), true];
        case 'tomorrow':       
            return [tomorrow, tomorrow, true];
        case 'this weekend':   
            return [thisfri, thissun, true];
        case 'this week':      
            return [new Date(), thissun, true];
        case 'next week':      
            return [nextweekstart, nextweekend, true];
        case 'this month':     
            return [new Date(), ldom, true];
        case 'next month':     
            return [fdonm, ldonm, true];
        default:
            return [startdate, future, true]
    }
}

function select_date_range_onchange(){
    var select_city = $id('select-date');
    
    var v = select_city.options[select_city.selectedIndex];
    var d = xlat_date_range(v.value);
    
    filters.set_dindex(select_city.selectedIndex)
    filters.set_date(d[0], d[1])
}

function page_move(event){
    var pageNode = window.event.srcElement || event.target
    var page = parseInt(pageNode.innerHTML);
    
    filters.set_page(page)
    _gaq.push(['Events', 'Browse event: Select page', page])
}

function page_next(){
    filters.set_page(current_page+1)
    _gaq.push(['Events', 'Browse event: Click next page'])
}   

function page_previous(){
    filters.set_page(current_page-1)
    _gaq.push(['Events', 'Browse event: Click previous page'])
}

/* Controller */


function add_search_history(){
    //historyStorage.put("filters", filters.serialize());
    addHistoryEvent([filters.start,filters.end,filters.category,filters.city,filters.distance,filters.page,filters.dindex].join(','));
}
function update_ui(filters){
    var select_city = $id('select-city');
    var select_distance = document.getElementById('select-distance');
    var select_date = $id('select-date');
    
    for(var i=0; i<select_city.options.length; i++)
        if(select_city.options[i].value == filters.city)
            select_city.selectedIndex = i;
        
    if(filters.city != 'all')
        show_select_distance()
    else
        hide_select_distance()
    
    for(var i=0; i<select_distance.options.length; i++)
        if(select_distance.options[i].value == filters.distance)
            select_distance.selectedIndex = i;
        
    select_date.selectedIndex = filters.dindex;
    
    var e = {'target':$id('category:'+filters.category)};
    treeclick(e);
}

function updateSet(forced){
    //console.log('Updating results...');
    
    try {
        document.getElementById('throbber').style.display = 'block';
        
        new Ajax.Request('/events/api/getevents',	{                         
            parameters:filters.serialize(),
            method:'get',
            asynchronous: false,
            onSuccess: function(transport, json){
                try {
                    if(!forced){
                        //console.log('not forced... adding history event')
                        add_search_history()
                    }
                    
                    document.getElementById('throbber').style.display = 'none';
                
                    var response = transport.responseText || "no response text";
                    /* alert("Success! \n\n" + response); json || */
                
                    //console.log(transport.responseJSON)
                    updateList(transport.responseJSON);
                    
                    /* var pos = Position.cumulativeOffset(document.getElementById('events-header')) */
                    //window.scroll(0,pos[1])
                    
                    var pos = Position.cumulativeOffset($id('table-event-finder'))
                    //console.log(f_scrollTop(), pos[0], pos[1])
                    if(f_scrollTop() > pos[1]-80){
                        window.scroll(0, pos[1]-80)
                    }
    
                    tries =0;
                }catch(e){
                    alert(_('There was a problem. Please try to reselect the filters')+' '+e.message)
                    //console.error(e.message)
                }
            },
            onFailure: function(){
                if(tries < 1){
                    tries++;
                    updateSet();
                    return;
                }
                document.getElementById('throbber').style.display = 'none';
                alert(_('There was a problem. Please try to reselect the filters'))
                
                
                tries = 0;
            }
        });
    }catch(e){
            //alert(e)
    }
}

function updatePoints(points){
    var minLat = Number.MAX_VALUE;
    var maxLat = Number.MIN_VALUE;
    var minLon = Number.MAX_VALUE;
    var maxLon = Number.MIN_VALUE;
    
    //console.log(points)
    if(!points) return
    if(points.length < 2) return;
    //var polylinePoints = [];
    //1.
    //for(var i=0; i<points.length;i++)
    
    var x =0;
    for(var i in points){
        
        mapObject = points[i][0]
        //var currentLatLon = new LatLng(mapObject.latitude, mapObject.longitude);
        //polylinePoints.push(currentLatLon);
    
        if(mapObject.lat() > maxLat){
            maxLat = mapObject.lat();
        }
        if(mapObject.lat() < minLat){
            minLat = mapObject.lat();
        }
        if(mapObject.lng() > maxLon){
            maxLon = mapObject.lng();
        }
        if(mapObject.lng() < minLon){
            minLon = mapObject.lng();
        }
        x++;
    }
    
    if(x == 0) return
    if(!maxLat || !minLat || !maxLon || !minLon) return;
    //2.
    var centerPointLat = minLat + (maxLat - minLat)/2;
    var centerPointLon = minLon + (maxLon - minLon)/2;
    var centerPoint = new GLatLng(centerPointLat,centerPointLon);
    
    //3.
    var bounds = new GLatLngBounds(
    new GLatLng(minLon, minLat),
    new GLatLng(maxLon, maxLat)
    );
    
    //4.
    map.setZoom(map.getBoundsZoomLevel(bounds)-1);
    //5.
    map.setCenter(centerPoint);

}

function updateList(items){
    
    var list = document.getElementById('box-list-events');
    try {
        if(items && (items[0].count == 0 || items.length <= 1) || !items){
            document.getElementById('search-results-info').innerHTML = '&nbsp;';
            var str = [];
            str.push('<div class="notification-light">')
            str.push('<p>'+_('No events found. Please try to change your selection.')+'</p>')
            str.push('<h2>' + _('Do you have something to add?') + '</h2>')
            str.push('<p>'+_('Sign in and create and an event.')+'</p>')
            str.push('</div>')
            
            list.innerHTML = str.join('') 
            return false;
        }
        
        mgr.clearMarkers()
        
        // use item zero as the page info
        var df = document.createDocumentFragment();
        
        half = Math.round(items / 2 );
        
        var table = $create('table');
        table.className = 'table-events';
        
        
        var tbody = $create('tbody');
        
        // keep lat/lngs for ids
        var points = {}
        
        for(var i=1; i < items.length; i++){
            var ic = 0;
            if(items[i].lat != 0 && items[i].lng != 0){
                ic = getRandomIcon();
                points[items[i].id] = [new GLatLng(items[i].lat,items[i].lng),items[i],ic]
            }
            
            var is_grey = i % 2 == 0;
            tbody.appendChild(listItem(items[i], ic, is_grey))
        }
        
        table.appendChild(tbody)
        df.appendChild(table);
        
        for(var i in points){
            if(typeof points[i][0] == 'object'){
                var marker = new GMarker(points[i][0], { icon:iconcache[points[i][2]], draggable:true });
                marker.bindInfoWindowHtml('<a href="/events/'+points[i][1].id+'"><img style="margin-right:6px;float:left;height:58px" src="'+points[i][1].image+'"/></a><a href="/events/'+points[i][1].id+'">'+points[i][1].name+'</a><div>'+points[i][1].date+'</div>')
                mgr.addMarker(marker, 3);
                //map.addOverlay(marker);
                //map.addOverlay(marker);
            }
        }
        mgr.refresh()
        updatePoints(points);    
    } 
    catch(e){
        //alert('Error! '+e.message)
        //console.error(e.message)
    }
    document.getElementById('search-results-info').innerHTML = '<div>'+items[0].info[0]+'</div><div>'+items[0].info[1]+'</div>';
    
    //$id('date-info').innerHTML = items[0].info[1];
    
    list.innerHTML = '';
    list.appendChild(df);
    list.appendChild(get_page_list(items));
    
}

/* Builders */

function listItem(data, ic, ig){
    var row = null;
    var cell = null;
    var link = null;
    var header = null;
    var box = null;
    var label = null;
    var span = null;
    
    var i = new Image()
        i.src = data.image
    
    // *****************
    // event listing row
    row = $create('tr');
    row.className = 'event' + (data.is_today == 1 ? ' today' : '');
    if(ig){
        row.className+= ' odd';
    }
    
    
    // *****************
    // image cell
    cell = $create('td');
    cell.className = 'cell-event-image';
    
    if(data.image){
        var imgr = document.createElement('img');
            imgr.setAttribute('src',data.image);
            
        var imglink = document.createElement('a')
            imglink.setAttribute('href','/events/'+data.id);
            imglink.appendChild(imgr);
            
        var img = document.createElement('div')
            img.className = 'flyer';
            img.appendChild(imglink);
            
        cell.appendChild(img);
    }
    else {
        cell.innerHTML = '&nbsp;';
    }
    
    row.appendChild(cell);
    
    // info cell 
    
    cell = $create('td');
    cell.className = 'cell-event-flag';
    // flag
    if(ic>=0){
        try {
        var a = $create('a');
        a.innerHTML = '';
        a.onclick =   function (e){
            try{
                var pos = Position.cumulativeOffset(document.getElementById('cell-events-map'));
                window.scroll(0,pos[1]-30);
                map.setCenter(new GLatLng(data.lat,data.lng), 14);
            }catch(e){
                //alert(e)
            }
	        
        }; 
        var flag = document.createElement('img');
        flag.className = 'flag';
        flag.src = iconcache[ic].image;
        
        //GEvent.addListener(a, "click", onflagclick);
        a.appendChild(flag)

        } catch(e){
            //alert(e)
        // console.error(e);
        }
    }
    
    cell.appendChild(a);
    row.appendChild(cell);
    
    
    // ***************
    // title/venue main cell
    cell = $create('td');
    cell.className = 'cell-event-main';
    
    // title link
    link = $create('a');
    link.href = '/events/'+data.id;
    link.innerHTML = data.name;
    // title header
    header = $create('h3');
    header.className = '';
    //header.appendChild(a);
    header.appendChild(link);
    cell.appendChild(header);
    
    cell.innerHTML+= '<div>'
    if(data.is_today == 1){
        cell.innerHTML+= '<span class="is-today"><label>'+_('Today!')+'</label></span> ';
    }
    
    if(data.recur){
        cell.innerHTML+= '<span class="recurrence">'+data.recur+'</span> ';
    }
    
    cell.innerHTML+= '<span class="date-start">'+data.date+'</span> ';
    
    if(data.date_end){
        cell.innerHTML+= '<span class="date-separator"> do </span> ';
        cell.innerHTML+= '<span class="date-end">'+data.date_end+'</span>';
    }
    cell.innerHTML+= '</div>'
    
    
    var box = $create('div')
        box.className ='category';
        box.innerHTML = /* '<label>' + _('Category') + '</label> ' +  */data.category_name;
    cell.appendChild(box);
    
    cell.innerHTML += '<div class="location-line">'
    cell.innerHTML += '<span class="venue-name"><a href="/venues/'+data.venue_id+'">' + data.venue_name +'</a></span>'
    if(data.city_name)
        cell.innerHTML += '<span class="city-name"> (' + data.city_name + ') </span>'
    
    cell.innerHTML += '</div>'
    
    
    
    if(data.price && data.price.length >0 && data.price != ' '){
        // price label
        label = $create('label');
        label.className = 'label-price';
        label.innerHTML = _('Price');
        // price value
        span = $create('span');
        span.innerHTML = data.price;
        // price box
        box = $create('div');
        box.appendChild(label);
        box.appendChild(span);
        cell.appendChild(box);
    }
    
    
     // user box
    link = $create('a');
    link.href = '/users/'+data.user_id;
    link.innerHTML = data.user_alias;
    // user box    
    box = $create('div');
    box.className='posted-by';
    /* box.innerHTML = '<label>'+_('Posted by')+'</label>'; */
    box.appendChild(link);
    cell.appendChild(box); 
    
    if (data.count > 0){
        var box = $create('div');
            box.className ='event-interests';
            box.innerHTML = '<span class="interest-count-inline">'+data.count+'</span>'+_('are interested');
        cell.appendChild(box);
    }
    
    // body
    body = $create('div')
    body.innerHTML = data.body
    cell.appendChild(body)
    
    
    row.appendChild(cell);
    
    // **************
    // date/time cell
    //cell = $create('td');
    //cell.className = 'cell-event-date';
    
    
    
    row.appendChild(cell);
    
    
    
    return row;
    /* 
    if(data.flags & 1 === 1){
        desc.innerHTML = _('You have marked this event as interesting');
    }
    else {
         var a = document.createElement('a');
            a.className = 'button-interest';
            div.appendChild(a) 
    }
    */
}

function get_page_list(items){
    // items:0 has pages (total), page(current on server), count(count of all)
    
    var df = document.createDocumentFragment();
    
    page_count = items[0].pages;
    current_page = items[0].page;
    total = items[0].count;
    filters.page = current_page;

    if(page_count == 1 || page_count == 0){
        return df;
    }
    
    var span = null;
    
    left = $create('td');
    left.className = 'ui-page-navigation-previous';
    
    center = $create('td');
    center.className = 'ui-page-navigation-pages';
    
    right = $create('td')
    right.className = 'ui-page-navigation-next';
    
    if(current_page != 1){
        span = $create('a');
        span.innerHTML = _('Previous');
        span.onclick = page_previous;
        left.appendChild(span);
    }
    
    for(var i=1; i <= page_count; i++){
        span = $create('a');
        
        var clstr = [];
        
        if(filters.page == i)
            clstr.push('ui-page-navigation-current-page');
        else
            clstr.push('ui-page-navigation-page');
            
        
        span.className = clstr.join('');
        span.innerHTML = i;
        
        if(filters.page != i){
            span.onclick = page_move
        }
        center.appendChild(span)
        
    }
    
    if(current_page < page_count){
        span = $create('a');
        span.innerHTML = _('Next');
        span.onclick = page_next
        right.appendChild(span)
    }
    
    row = $create('tr');
    row.appendChild(left);
    row.appendChild(center);
    row.appendChild(right);
    
    table = $create('table');
    table.className = 'ui-page-navigation';
    
    var tbody = $create('tbody');
    tbody.appendChild(row)
    table.appendChild(tbody);
    
    
    div = $create('div');
    div.className = 'ui-page-navigation-box';
    div.appendChild(table)
    
    df.appendChild(div)
    
    return df

}

var iconmarkers = [
    '/styles/maps/mm_20_red.png'
,   '/styles/maps/mm_20_green.png'
,   '/styles/maps/mm_20_blue.png'
,   '/styles/maps/mm_20_yellow.png'
,   '/styles/maps/mm_20_orange.png'
,   '/styles/maps/mm_20_purple.png'
//,   '/styles/maps/mm_20_brown.png'
//,   '/styles/maps/mm_20_black.png'
,   '/styles/maps/mm_20_white.png'
,   '/styles/maps/mm_20_gray.png'
];
var iconcache = [];
var iconlasti = -1;

function createIconCache(){
    for(var i=0; i<iconmarkers.length; i++){
        var tinyIcon = new GIcon();
        tinyIcon.image = iconmarkers[i];
        tinyIcon.shadow = "/styles/maps/mm_20_shadow.png";
        tinyIcon.iconSize = new GSize(12, 20);
        tinyIcon.shadowSize = new GSize(22, 20);
        tinyIcon.iconAnchor = new GPoint(6, 20);
        tinyIcon.infoWindowAnchor = new GPoint(5, 1);
        iconcache.push(tinyIcon)
    }
}

/* function createIconCache(){
    colors = 'b g r'.split(' ')
    for(var j=0; j<colors.length;j++){
        for(var i=1; i<50; i++){
            var tinyIcon = new GIcon();
            tinyIcon.image = "/styles/events/flags/icon"+colors[j]+i+".png";
            tinyIcon.shadow = "/styles/events/flags/shadow50.png";
            tinyIcon.iconSize = new GSize(12, 20);
            tinyIcon.shadowSize = new GSize(22, 20);
            tinyIcon.iconAnchor = new GPoint(6, 20);
            tinyIcon.infoWindowAnchor = new GPoint(5, 1);
            iconcache.push(tinyIcon)
        }
    }
} */

function getRandomIcon(){
    
    
    var newi = Math.floor(Math.random()*(iconcache.length));
    
    // dont repeat right away
    if(newi == iconlasti){
        newi = Math.floor(Math.random()*(iconcache.length));
    }
    
    iconlasti = newi;
    return newi
}


var now = new Date();
var now_date = now.getDate();

var yesterdate = new Date();
    yesterdate.setDate(now.getDate()-1); 

var tomorrow = new Date();
    tomorrow.setDate(tomorrow.getDate()+1);

var future = new Date();
    future.setDate(future.getDate()+35);
    
var max_default = new Date();
    max_default.setDate(max_default.getDate()+25);
		
var thisweek = new Date();
    thisweek.setDate(thisweek.getDate()+7);
		
var ldom = new Date();
    ldom.setMonth(ldom.getMonth() +1)
    ldom.setDate(0);
		
var thissun = new Date()
    thissun.setDate( thissun.getDate() + (7-thissun.getDay())%7 );
    
var thismon = new Date()
    thismon.setDate( thismon.getDate() + (7+1-thismon.getDay())%7 );
		
var thisfri = new Date()
    thisfri.setDate( thisfri.getDate() + (5-thisfri.getDay())%7 );

var nextweekstart = new Date();
    nextweekstart.setDate(nextweekstart.getDate() + (7+1-nextweekstart.getDay())%7 );
    nextweekstart.setDate(nextweekstart.getDate()  + 7 )

var nextweekend = new Date();
    nextweekend.setDate(nextweekstart.getDate() +6);
    
var fdonm = new Date();
    fdonm.setMonth(fdonm.getMonth()+1)
    fdonm.setDate(1)

var ldonm = new Date();
    ldonm.setMonth(ldonm.getMonth()+2)
    ldonm.setDate(1)
    ldonm.setDate(ldonm.getDate()-1)

var startdate = now;
    
if(now.getHours() < 6){
    startdate = yesterdate;
}

    
dhtmlHistory.create({
    toJSON: function(o) {
            return Object.toJSON(o);
    }
    , fromJSON: function(s) {
            return s.evalJSON();
    }
});


var yourListener = function(newLocation, historyData) {
    //console.log('Loaded from history',newLocation);
    //console.log($id('select-date').options[0])
    
    if(newLocation && newLocation.length){
    
        var splt = newLocation.split(',');
	
        //console.warn(splt)
        
        if(splt.length == 7){
            filters.unserialize({
                start:splt[0],
                end:splt[1],
                category:splt[2],
                city:splt[3],
                distance:splt[4],
                page:splt[5],
                dindex:splt[6]
            }, true);
            var s = filters.start;
            var e = filters.end;
            
            if(s == e){
                $id('select-date').options[0].innerHTML = s;
            }
            else {
                
                $id('select-date').options[0].innerHTML = s + ' - ' + e;
            }
            
            update_ui(filters);
        }
	}
}


/* Our event handler to add history change events */
addHistoryEvent = function(name, value) {
	dhtmlHistory.add(name, value);
}

window.onload=function(){
    try{
    dhtmlHistory.initialize();
//RSH will break, especially in IE, if you try to initialize it from any flavor of DOMContentLoaded.
    dhtmlHistory.addListener(yourListener);
    }
    catch (err){
    alert(err.message)
    }
}

google.setOnLoadCallback(function() {
    createIconCache();
    initialize_map();
    
    
    
    
    
    try {
    var location = dhtmlHistory.getCurrentLocation();
    
    if(location && location.length > 0){
        yourListener(location, null);
        return;
    }
    else {
        filters.set_date(startdate, future, true);
    }
        
    }
    catch (err){
    alert(err.message)
    }
    //filters.unserialize(historyStorage.get('filters'), true);
});
