var map = null;
var map_bounds = new Array();
var map_markers = new Array();
var map_infoboxes = new Array();
var map_marker_active = null;
var map_infobox = null;
var map_infobox_clicked = false;
var map_directions = null;
var my_position = null;
var initial_location = null;
var locations_wrapper = null;
var IE = null;

var fi_cityshops_places_bounds =
{
    max_lat: 60.240,
    min_lat: 60.150,
    max_long: 25.00,
    min_long: 24.85
}

jQuery(function()
{
    jQuery('a.thickbox')
        .bind('click', function()
        {
            popup(jQuery(this).attr('href'));
            return false;
        })
        .each(function()
        {
            var src = jQuery(this).attr('href');
            
            if (!src.match(/\.(jpe?g|gif|png)$/i))
            {
                return;
            }
            
            jQuery(this).parent().set_picture_viewer();
        });
    
    jQuery('.hoverable, #navigation > ul > li').set_hoverable();
    
    if (   !jQuery('body').hasClass('fi_cityshops_shop')
        && !jQuery('body').hasClass('fi_cityshops_prospects')
        && !jQuery('body').hasClass('cc_kaktus_support')
        && !jQuery('body').hasClass('admin')
        && typeof FB != 'undefined')
    {
        FB.init
        (
            {
                appId: '182498325114715',
                status: true,
                cookie: true,
                xfbml: true
            }
        );
    }
    
    if (jQuery('#fi_cityshops_places_list').size())
    {
        if (   typeof google != 'undefined'
            && typeof google.maps != 'undefined')
        {
            jQuery('#fi_cityshops_places_list').initialize_google_maps();
        }
        else
        {
            jQuery('#fi_cityshops_places_list').initialize_google_maps();
        }
    }
    
    if (jQuery('#fi_cityshops_places_vcard').size())
    {
        jQuery('#fi_cityshops_places_vcard').initialize_google_maps();
    }
    
    // jQuery('.jsrounded').rounded_corners();
    // jQuery('.jsrounded-top').rounded_corners('top');
});

function close_popups()
{
    jQuery('#popup_wrapper, #popup_blanket, #popup_close').remove();
}

var popup = function(url, callback)
{
    if (!url)
    {
        return;
    }
    
    if (jQuery('#popup_blanket').size() == 0)
    {
        // Clear the popup
        jQuery('<div id="popup_blanket"></div>')
            .prependTo('#container')
            .bind('click', function()
            {
                if (window.location.hash)
                {
                    window.location.hash = '#';
                }
                
                close_popups();
            });
        
        jQuery('<div id="popup_wrapper"></div>')
            .addClass('loading')
            .prependTo('#container')
            .bind('click', function()
            {
                if (jQuery(this).hasClass('with-image'))
                {
                    close_popups();
                }
            });
        
        jQuery('<img src="/images/icon-close.gif" alt="X" width="22" height="22" class="close" id="popup_close" />')
            .bind('click', function()
            {
                jQuery('#popup_blanket').trigger('click');
            })
            .prependTo('#container');
    }
    
    if (   typeof callback == 'undefined'
        || !callback)
    {
        // Empty callback function
        callback = function()
        {
            jQuery('#popup_wrapper').removeClass('loading');
        }
    }
    
    // Handle the request as an image
    if (url.match(/(jpe?g|gif|png)$/i))
    {
        jQuery('#popup_wrapper').addClass('with-image');
        
        jQuery('<img src="' + url + '" alt="" />')
            .css('visibility', 'hidden')
            .bind('click', function()
            {
                close_popups();
            })
            .load(function()
            {
                max_width = jQuery(window).width() - 60;
                max_height = jQuery(window).height() - 60;
                
                width = jQuery(this).width();
                height = jQuery(this).height();
                
                if (width > max_width)
                {
                    height = height * max_width / width;
                    width = max_width;
                }
                
                if (height > max_height)
                {
                    width = width * max_height / height;
                    height = max_height;
                }
                
                margin_top = Math.round(height / 2 + 10);
                margin_left = Math.round(width / 2 + 10);
                
                jQuery(this)
                    .css
                    (
                        {
                            'visibility': 'visible',
                            'position': 'absolute',
                            'top': '50%',
                            'left': '50%',
                            'width': width + 'px',
                            'height': height + 'px',
                            'margin-top': '-' + margin_top + 'px',
                            'margin-left': '-' + margin_left + 'px'
                        }
                    );
                
                jQuery('#popup_close')
                    .css
                    (
                        {
                            'top': '50%',
                            'left': '50%',
                            'margin-top': '-' + (margin_top + 10) + 'px',
                            'margin-left': margin_left + 'px'
                        }
                    );
                
                callback();
            })
            .addClass('popup_image')
            .appendTo('#popup_wrapper');
        
        return true;
    }
    
    window.location.hash = '#!' + url
    
    if (url.match(/\?/))
    {
        url += '&ajax';
    }
    else
    {
        url += '?ajax';
    }
    
    jQuery('#popup_wrapper')
        .load
        (
            url,
            null,
            function()
            {
                callback();
                jQuery('#popup_wrapper').removeClass('loading');
            }
        );
}

jQuery(function()
{
    jQuery('#fi_cityshops_places_quicksearch').find('input[name="q"]')
        .unbind('keyup')
        .bind('keyup', function(ev)
        {
            // Stop the previous timer
            jQuery(this).stopTime('delayed');
            
            console.log(ev.keyCode);
            
            diff = 0;
            
            switch (ev.keyCode)
            {
                case 13:
                    if (jQuery(this).parents('form').find('li.selected'))
                    {
                        jQuery(this).parents('form')
                            .bind(
                                'submit',
                                function()
                                {
                                    return false;
                                }
                            );
                        window.location.href = jQuery(this).parents('form').find('li.selected').find('a:first').attr('href');
                        return false;
                    }
                    break;
                
                case 27:
                    jQuery(this)
                        .val('')
                        .trigger('blur');
                    break;
                
                case 38:
                    diff -= 2;
                    // Fall through
                
                case 40:
                    diff++;
                    var current = jQuery(this).parents('form').find('div.results').find('li.selected');
                    
                    if (!current.size())
                    {
                        if (diff > 0)
                        {
                            jQuery(this).parents('form').find('div.results').find('li:first').addClass('selected');
                        }
                        else
                        {
                            jQuery(this).parents('form').find('div.results').find('li:last').addClass('selected');
                        }
                        return;
                    }
                    
                    results = current.parents('div.results').find('li');
                    
                    index = 0;
                    for (i = 0; i < results.size(); i++)
                    {
                        if (results.eq(i).hasClass('selected'))
                        {
                            index = i;
                            console.log('index is ' + i);
                            break;
                        }
                    }
                    
                    index += diff;
                    
                    if (index < 0)
                    {
                        index = results.size() - 1;
                        console.log('index < 0');
                    }
                    else if (index >= results.size() + 1)
                    {
                        index = 0;
                        console.log('index > ' + results.size());
                    }
                    
                    console.log('index: ' + index);
                    current.removeClass('selected');
                    results.eq(index).addClass('selected');
                    return;
            }
            
            var value = jQuery(this).val();
            
            if (   !value
                || value.length < 3)
            {
                jQuery(this).parents('form').find('div.results').remove();
                return false;
            }
            
            // Start a new timer
            jQuery(this).oneTime(500, 'delayed', function()
            {
                var value = jQuery(this).val();
                
                if (   !value
                    || value.length < 3)
                {
                    return false;
                }
                
                while (value.match(/ /))
                {
                    value = value.replace(/[ ]+/, '%20');
                }
                
                var form = jQuery(this).parents('form');
                var url = form.attr('action') + value + '/';
                
                if (!form.find('div.results').size())
                {
                    jQuery('<div class="results"></div>')
                        .appendTo(form);
                }
                
                form.find('div.results').load
                (
                    url + '?ajax div.fi_cityshops_places_search_resultset',
                    function()
                    {
                        jQuery('<img src="/images/icon-close-black.gif" width="22" height="22" class="close" />')
                            .prependTo('#fi_cityshops_places_quicksearch div.results')
                            .bind('click', function()
                            {
                                jQuery('#fi_cityshops_places_quicksearch div.results').remove();
                            });
                        
                        jQuery('#fi_cityshops_places_quicksearch div.results').find('.pager a').pager_events();
                    }
                );
            });
            
            return true;
        });
    
    jQuery('#fi_cityshops_places_quicksearch')
        .bind('submit', function()
        {
            if (jQuery(this).find('li').size() == 1)
            {
                var href = jQuery(this).find('li a').attr('href');
                
                if (href)
                {
                    window.location = href;
                    return false;
                }
            }
            
            return true;
        });
    
    if (IE == 7)
    {
        jQuery('#navigation ul li')
            .each(function()
            {
                var width = jQuery(this).width() - 1;
                jQuery(this).find('> ul')
                    .css('margin-left', '-' + width + 'px');
            });
    }
    
    /*
    jQuery('a.map_link')
        .bind('click', function()
        {
            var href = jQuery(this).attr('href');
            var callback_function = function()
            {
                var width = jQuery('#popup_wrapper').width();
                var height = jQuery('#popup_wrapper').height();
                
                jQuery('#fi_cityshops_places_map')
                    .css('width', (width - 10) + 'px')
                    .css('height', (height) + 'px');
                
                jQuery('#fi_cityshops_places_list')
                    .initialize_cloudmade_maps();
            }
            
            popup(href, callback_function);
            
            return false;
        });
    /**/
    
    if (window.location.hash)
    {
        var hash = String(window.location.hash);
        
        if (hash.match(/#!/))
        {
            var href = hash.replace(/#!/, '');
            
            if (jQuery('#content-text').find('a[href="' + href + '"]').size() > 0)
            {
                jQuery('#content-text').find('a[href="' + href + '"]').trigger('click');
            }
            else if (href.match(/^(http|\/)/))
            {
                window.location = href;
            }
        }
    }
});

jQuery.fn.rounded_corners = function(location)
{
    if (   jQuery('body').hasClass('cc_kaktus_support')
        || jQuery('body').hasClass('fi_cityshops_prospects'))
    {
        return;
    }
    
    if (!location)
    {
        location = 'all';
    }
    
    for (i = 0; i < jQuery(this).size(); i++)
    {
        object = jQuery(this).eq(i);
        
        padding_left = Number(String(object.css('padding-left')).replace(/px/, ''));
        padding_right = Number(String(object.css('padding-right')).replace(/px/, ''));
        padding_top = Number(String(object.css('padding-top')).replace(/px/, ''));
        padding_bottom = Number(String(object.css('padding-bottom')).replace(/px/, ''));
        
        var offset = object.offset();
        var width = object.width();
        var height = object.height();
        
        if (location.match(/(top|all)/))
        {
            if (!object.find('._rounded._top._left').size())
            {
                jQuery('<div class="_rounded _top _left"></div>')
                    .prependTo(object);
            }
            
            if (!object.find('._rounded._top._right').size())
            {
                jQuery('<div class="_rounded _top _right"></div>')
                    .prependTo(object);
            }
            
            object.find('._rounded._top._left')
                .css
                (
                    {
                        marginTop: '-' + padding_top + 'px',
                        marginLeft: '-' + padding_left + 'px',
                        backgroundImage: 'url("/images/rounded-top-left.png")'
                    }
                );
            
            object.find('._rounded._top._right')
                .css
                (
                    {
                        marginTop: '-' + padding_top + 'px',
                        marginLeft: (width + padding_right - 10) + 'px',
                        backgroundImage: 'url("/images/rounded-top-right.png")'
                    }
                );
        }
        
        if (location.match(/(bottom|all)/))
        {
            if (!object.find('._rounded._bottom._left').size())
            {
                jQuery('<div class="_rounded _bottom _left"></div>')
                    .prependTo(object);
            }
            
            if (!object.find('._rounded._bottom._right').size())
            {
                jQuery('<div class="_rounded _bottom _right"></div>')
                    .prependTo(object);
            }
            
            object.find('._rounded._bottom._left')
                .css
                (
                    {
                        marginTop: (height + padding_bottom - 10) + 'px',
                        marginLeft: '-' + padding_left + 'px',
                        backgroundImage: 'url("/images/rounded-bottom-left.png")'
                    }
                );
            
            object.find('._rounded._bottom._right')
                .css
                (
                    {
                        marginTop: (height + padding_bottom - 10) + 'px',
                        marginLeft: (width + padding_right - 10) + 'px',
                        backgroundImage: 'url("/images/rounded-bottom-right.png")'
                    }
                );
        }
    }
}

jQuery.fn.pager_events = function()
{
    jQuery(this)
        .bind('click', function()
        {
            var id = jQuery(this).parents('div.fi_cityshops_places_search_resultset');
            var href = jQuery(this).attr('href');
            
            if (!href)
            {
                return true;
            }
            
            var result_wrapper = jQuery('#fi_cityshops_places_quicksearch div.results');
            result_wrapper
                .addClass('loading')
                .find('.fi_cityshops_places_search_resultset ol').remove();
            
            result_wrapper.find('.pager').not(':first').remove();
            
            jQuery.ajax
            (
                {
                    data:
                    {
                        ajax: true
                    },
                    dataType: 'html',
                    success: function(data)
                    {
                        var result_wrapper = jQuery('#fi_cityshops_places_quicksearch div.results');
                        result_wrapper
                            .removeClass('loading')
                            .find('.fi_cityshops_places_search_resultset').remove();
                        
                        jQuery(data).find('.fi_cityshops_places_search_resultset').appendTo(result_wrapper);
                        result_wrapper.find('.pager a').pager_events();
                    },
                    type: 'GET',
                    url: href
                }
            );
            return false;
        });
}

jQuery.fn.set_hoverable = function()
{
    jQuery(this)
        .bind('mouseover', function()
        {
            jQuery(this)
                .stopTime('hoverable')
                .addClass('hover');
            
            jQuery(this).siblings()
                .stopTime('hoverable')
                .removeClass('hover');
        })
        .bind('mouseout', function()
        {
            jQuery(this)
                .oneTime
                (
                    500,
                    'hoverable',
                    function()
                    {
                        jQuery(this).removeClass('hover');
                    }
                );
        });
}

jQuery.fn.set_picture_viewer = function()
{
    if (typeof swfobject == 'undefined')
    {
        return;
    }
    
    var src = jQuery(this).attr('href');
    
    if (!src)
    {
        var src = jQuery(this).find('a').attr('href');
    }
    
    if (!src)
    {
        return;
    }
    
    var id = jQuery(this).attr('id');
    
    if (!id)
    {
        var date = new Date();
        var id = 'fi_cityshops_places_temporary_id_' + date.getTime();
        
        jQuery(this).attr('id', id);
    }
    
  	var flashvars =
  	{
      	fill: 'true',
      	bgcolor: '0x000000',
      	picurl: src
  	};
  	
  	var params =
  	{
  		menu: 'true',
  		allowFullscreen: 'true',
  		wmode: 'transparent'
  	};
  	
  	var attributes = {};
  	attributes.id = jQuery(this).attr('id');
  	
  	// Lock the height to prevent flickering
  	jQuery(this).css('height', jQuery(this).height() + 'px');
  	
  	swfobject.embedSWF
  	(
  	    '/flash/pictureviewer.swf',
  	    jQuery(this).attr('id'),
  	    jQuery(this).width(),
  	    jQuery(this).height(),
  	    "9.0.0",
  	    false,
  	    flashvars,
  	    params,
  	    attributes
  	);
}

jQuery.fn.initialize_google_maps = function()
{
    if (   jQuery(this).find('.location').size() == 0
        || jQuery('#fi_cityshops_places_map').size() == 0)
    {
        return;
    }
    
    var options = 
    {
        zoom: 13,
        mapTypeId: google.maps.MapTypeId.ROADMAP,
        minZoom: 11,
        streetViewControl: false,
        panControl: false,
        zoomControlOptions:
        {
            style: google.maps.ZoomControlStyle.LARGE,
            position: google.maps.ControlPosition.LEFT_BOTTOM   
        }
    }
    
    if (jQuery('#fi_cityshops_places_map').hasClass('single'))
    {
        options.panControl = false;
        options.mapTypeControl = false;
        options.rotateControl = false;
        options.scaleControl = false;
        options.zoomControl = false;
    }
    
    map = new google.maps.Map
    (
        document.getElementById('fi_cityshops_places_map'),
        options
    );
    
    var position = new google.maps.LatLng(60.1645, 24.960);
    map.setCenter(position);
    
    var locations = jQuery(this).find('.location');
    
    var index = 0;
    bounds = null;
    
    for (i = 0; i < locations.size(); i++)
    {
        if (!jQuery(this).find('span.lat').size())
        {
            return;
        }
        
        var lat = Number(locations.eq(i).find('span.lat').text().replace(/,/, '.'));
        var lng = Number(locations.eq(i).find('span.lng').text().replace(/,/, '.'));
        var url = locations.eq(i).find('span.url').text();
        var title = locations.eq(i).find('span.title').text();
        var guid = locations.eq(i).find('span.guid').text();
        var street = locations.eq(i).find('span.street').text();
        var city = locations.eq(i).find('span.city').text();
        var postcode = locations.eq(i).find('span.postcode').text();
        var open_status = locations.eq(i).find('span.status').text();
        var memberships = locations.eq(i).find('span.memberships').text();
        
        if (   lat < 60
            || lng < 20)
        {
            continue;
        }
        
        icon = new google.maps.MarkerImage
        (
            '/images/map-marker-red.png',
            new google.maps.Size(13, 13),
            null,
            new google.maps.Point(6, 6)
        );
        
        // Use green dot for places that are open
        if (open_status == 'open')
        {
            icon.url = '/images/map-marker-green.png';
        }
        
        var position = new google.maps.LatLng(lat, lng);
        
        var marker = new google.maps.Marker
        (
            {
                position: position,
                map: map,
                title: title,
                guid: guid,
                street: street,
                city: city,
                postcode: postcode,
                open_status: open_status,
                icon: icon,
                _url: url,
                memberships: memberships
            }
        );
        
        map_markers.push(marker);
        /*
        google.maps.event.addListener
        (
            marker,
            'mouseover',
            function(event)
            {
                console.log(event);
            }
        );
        */
        
        // Use click and mouseover events only when in big mode
        if (!jQuery('#fi_cityshops_places_map').hasClass('single'))
        {
            // Add event listener for mouseover
            google.maps.event.addListener
            (
                marker,
                'mouseover',
                function()
                {
                    if (map_infobox_clicked)
                    {
                        return;
                    }
                    
                    map_infobox = new InfoBox(this, 'hover');
                    my_position = initial_location;
                }
            );
            
            // Add event listener for click
            google.maps.event.addListener
            (
                marker,
                'click',
                function()
                {
                    map_infobox = new InfoBox(this, 'sticky');
                    map_infobox_clicked = true;
                    
                    if (!initial_location)
                    {
                        return;
                    }
                    
                    draw_directions(initial_location, this.getPosition());
                }
            );
        }
        
        if (!bounds)
        {
            bounds = new google.maps.LatLngBounds(position, position);
        }
        else
        {
            bounds.extend(position);
        }
    }
    
    bounds = new google.maps.LatLngBounds
    (
        new google.maps.LatLng(fi_cityshops_places_bounds.min_lat, fi_cityshops_places_bounds.min_long),
        new google.maps.LatLng(fi_cityshops_places_bounds.max_lat, fi_cityshops_places_bounds.max_long)
    );
    
    if (jQuery('#fi_cityshops_places_map').hasClass('single'))
    {
        google.maps.event.addListener
        (
            map,
            'click',
            function()
            {
                var root = String(window.location);
                
                if (jQuery('link[rel="canonical"]').size())
                {
                    var root = jQuery('link[rel="canonical"]').eq(0).attr('href');
                }
                
                window.location.href = root + 'map/';
            }
        );
    }
    
    if (locations.size() == 1)
    {
        map.setCenter(position);
    }
    else if (bounds)
    {
        map.fitBounds(bounds);
    }
    
    if (   typeof jQuery.cookie != 'undefined'
        && jQuery.cookie('latitude')
        && jQuery.cookie('longitude'))
    {
        return;
        initial_location = new google.maps.LatLng(jQuery.cookie('latitude'), jQuery.cookie('longitude'));
        
        if (locations.size() == 1)
        {
            map.setCenter(position);
            draw_directions(initial_location, position);
        }
        
        var bounds = map.getBounds();
        if (   bounds
            && bounds.contains(initial_location))
        {
            map.setCenter(initial_location);
        }
        
        var marker = new google.maps.Marker
        (
            {
                position: initial_location,
                title: 'Arvioitu paikkasi',
                map: map
            }
        );
        
        if (map_markers.length == 1)
        {
            draw_directions(initial_location, map_markers[0].getPosition());
        }
        
        my_position = initial_location;
    }
    else if (navigator.geolocation)
    {
        support_geolocation = true;
        navigator.geolocation.getCurrentPosition
        (
            function(position)
            {
                initial_location = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);
                
                jQuery.cookie
                (
                    'latitude',
                    String(position.coords.latitude),
                    {
                        expires: (1 / 24),
                        path: '/'
                    }
                );
                jQuery.cookie
                (
                    'longitude',
                    String(position.coords.longitude),
                    {
                        expires: (1 / 24),
                        path: '/'
                    }
                );
                
                var bounds = map.getBounds();
                if (   bounds
                    && bounds.contains(initial_location))
                {
                    map.setCenter(initial_location);
                }
                
                var marker = new google.maps.Marker
                (
                    {
                        position: initial_location,
                        title: 'Arvioitu paikkasi',
                        map: map
                    }
                );
                
                my_position = initial_location;
                
                if (map_markers.length == 1)
                {
                    draw_directions(initial_location, map_markers[0].getPosition());
                }
            },
            function()
            {
                // Do nothing
            }
        );
    }
    else if (google.gears)
    {
        support_geolocation = true;
        var geo = google.gears.factory.create('beta.geolocation');
        geo.getCurrentPosition
        (
            function(position)
            {
                initial_location = new google.maps.LatLng(position.latitude, position.longitude);
                
                var bounds = map.getBounds();
                
                if (   bounds
                    && bounds.contains(initial_location))
                {
                    map.setCenter(initial_location);
                }
                
                jQuery.cookie
                (
                    'latitude',
                    String(position.coords.latitude),
                    {
                        expires: (1 / 24),
                        path: '/'
                    }
                );
                jQuery.cookie
                (
                    'longitude',
                    String(position.coords.longitude),
                    {
                        expires: (1 / 24),
                        path: '/'
                    }
                );
                
                var marker = new google.maps.Marker
                (
                    {
                        position: initial_location,
                        title: 'Arvioitu paikkasi',
                        map: map
                    }
                );
            },
            function()
            {
                // Do nothing
            }
        );
    }
    else
    {
        support_geolocation = false;
    }
}

// Initialize a null class in case Google Maps JavaScript API
// isn't loaded
if (typeof google == 'undefined')
{
    var google = 
    {
        maps:
        {
            OverlayView: function()
            {
            }
        }
    }
}

/**
 * An InfoBox is like an info window, but it displays
 * under the marker, opens quicker, and has flexible styling.
 * @param {GLatLng} latlng Point to place bar at
 * @param {Map} map The map on which to display this InfoBox.
 * @param {Object} options Passes configuration options - content,
 *   offsetVertical, offsetHorizontal, className, height, width
 */
function InfoBox(marker, type)
{
    jQuery('.fi_cityshops_places_master_view').css('display', 'none');
    
    options =
    {
        latlng: marker.getPosition(),
        map: map,
        guid: marker.guid,
        url: marker._url,
        title: marker.title,
        street: marker.street,
        postcode: marker.postcode,
        city: marker.city
    }
    
    if (jQuery('#fi_cityshops_places_close_infobox').size())
    {
        jQuery('#fi_cityshops_places_close_infobox').trigger('click');
    }
    
    google.maps.OverlayView.call(this);
    
    if (map_infobox)
    {
        jQuery(map_infobox._div).remove();
    }
    
    this._marker = marker;
    this._latlng = options.latlng;
    this._map = options.map;
    this._offsetVertical = -1;
    this._offsetHorizontal = 0;
    this._width = 300;
    this._height = 150;
    this._call_options = options;
    
    if (   type
        && type == 'sticky')
    {
        this.sticky = true;
    }
    else
    {
        this.sticky = false;
    }
    
    var me = this;
    map_infobox = this;
    
    this.boundsChangedListener_ =
    google.maps.event.addListener
    (
        this._map,
        'bounds_changed',
        function(ev)
        {
            return me.panMap.apply(me);
        }
    );
    
    // Once the properties of this OverlayView are initialized, set its map so
    // that we can display it.  This will trigger calls to panes_changed and
    // draw.
    this.setMap(this._map);
    
    map_infobox = this;
}

/* InfoBox extends GOverlay class from the Google Maps API
*/
InfoBox.prototype = new google.maps.OverlayView();

/* Creates the DIV representing this InfoBox
*/
InfoBox.prototype.remove = function()
{
    if (this._div)
    {
        jQuery(this._div)
            .remove();
        
        this._div = null;
    }
};

/* Redraw the Bar based on the current projection and zoom level
*/
InfoBox.prototype.draw = function()
{
    // Creates the element if it doesn't exist already.
    this.createElement();
    if (!this._div)
    {
        return;
    }
    
    // Calculate the DIV coordinates of two opposite corners of our bounds to
    // get the size and position of our Bar
    var pixPosition = this.getProjection().fromLatLngToDivPixel(this._latlng);
    
    if (!pixPosition)
    {
        return;
    }
    
    // Now position our DIV based on the DIV coordinates of our bounds
    this._div
        .css
        (
            {
                width: this._width + 'px',
                height: this._height + 'px',
                left: (pixPosition.x + this._offsetHorizontal) + "px",
                top: (pixPosition.y + this._offsetVertical) + "px"
            }
        );
};

/* Creates the DIV representing this InfoBox in the floatPane.  If the panes
* object, retrieved by calling getPanes, is null, remove the element from the
* DOM.  If the div exists, but its parent is not the floatPane, move the div
* to the new pane.
* Called from within draw.  Alternatively, this can be called specifically on
* a panes_changed event.
*/
InfoBox.prototype.createElement = function()
{
    var panes = this.getPanes();
    
    var div = this._div;
    
    if (!div)
    {
        // This does not handle changing panes.  You can set the map to be null and
        // then reset the map to move the div.
        var master = jQuery('<div class="fi_cityshops_places_master_view master"></div>')
            .css
            (
                {
                    border: 'solid 1px black',
                    position: 'absolute',
                    zIndex: 10000,
                    backgroundImage: 'url("/images/black-corner.png")',
                    backgroundRepeat: 'no-repeat',
                    backgroundPosition: 'top left',
                    backgroundColor: 'white',
                    width: this._width + 'px',
                    height: this._height + 'px'
                }
            )
            .bind('mouseover', function()
            {
                jQuery(this).stopTime('hover');
                jQuery(this).addClass('hover');
            })
            .bind('mouseout', function()
            {
                jQuery(this).oneTime(2000, 'hover', function()
                {
                    if (   jQuery(this).hasClass('hover')
                        || this.sticky
                        || map_infobox_clicked)
                    {
                        return;
                    }
                    
                    jQuery(this)
                        .fadeOut(500, function()
                        {
                            jQuery(this).css('display', 'none');
                        });
                });
                
                jQuery(this).removeClass('hover');
            })
            .oneTime(2000, 'hover', function()
            {
                jQuery(this).trigger('mouseout')
            })
            .appendTo(panes.floatPane);
        
        this._div = master;
        
        var content_html = '<a href="' + this._call_options.url + '">' + this._call_options.title + '</a><br />';
        
        if (   this._call_options.street
            && this._call_options.city)
        {
            content_html += this._call_options.street + ', ' + this._call_options.postcode + ' ' + this._call_options.city + '<br />';
        }
        
        if (my_position)
        {
            var distance = Number(google.maps.geometry.spherical.computeDistanceBetween(this._latlng, my_position));
            content_html += '<br />Etäisyys: ' + Math.round(distance  / 100) / 10 + ' km';
            
            if (initial_location)
            {
                content_html += ' | Reitti: ';
                // content_html += '<a href="#" onclick="draw_directions(null, new google.maps.LatLng(' + this._marker.getPosition().lat() + ', ' + this._marker.getPosition().lng() + '), \'' + google.maps.TravelMode.BICYCLING + '\'); return false;">pyörällä</a>, ';
                content_html += '<a href="#" onclick="draw_directions(null, new google.maps.LatLng(' + this._marker.getPosition().lat() + ', ' + this._marker.getPosition().lng() + '), \'' + google.maps.TravelMode.WALKING + '\'); return false;">kävellen</a>, ';
                content_html += '<a href="#" onclick="draw_directions(null, new google.maps.LatLng(' + this._marker.getPosition().lat() + ', ' + this._marker.getPosition().lng() + ')); return false;">autolla</a>';
            }
        }
        
        var content = jQuery('<div class="infobox_content"></div>')
            .css
            (
                {
                    padding: '10px'
                }
            )
            .html(content_html)
            .appendTo(master);
        
        var close_image = jQuery('<img id="fi_cityshops_places_close_infobox" />')
            .attr('src', 'http://gmaps-samples.googlecode.com/svn/trunk/images/closebigger.gif')
            .css
            (
                {
                    width: '32px',
                    height: '32px',
                    cursor: 'pointer',
                    float: 'right'
                }
            )
            .bind('click', function()
            {
                jQuery('.fi_cityshops_places_master_view').css('display', 'none');
                
                // Remove stickiness
                map_infobox.sticky = false;
                map_infobox_clicked = false;
                
                // Remove directions
                if (map_directions)
                {
                    // map_directions.setMap(null);
                }
            })
            .prependTo(master);
        
        // Set the info box to its correct position
        this.panMap();
    }
    else if (div.get(0).parentNode != panes.floatPane)
    {
        // The panes have changed.  Move the div.
        div.appendTo(panes.floatPane);
    }
    else
    {
        // The panes have not changed, so no need to create or move the div.
    }
}

/* Pan the map to fit the InfoBox.
*/
InfoBox.prototype.panMap = function()
{
    // if we go beyond map, pan map
    var map = this._map;
    var bounds = map.getBounds();
    if (!bounds) return;
    
    // The position of the infowindow
    var position = this._latlng;
    
    // The dimension of the infowindow
    var iwWidth = this._width;
    var iwHeight = this._height;
    
    // The offset position of the infowindow
    var iwOffsetX = this._offsetHorizontal;
    var iwOffsetY = this._offsetVertical;
    
    // Padding on the infowindow
    var padX = 40;
    var padY = 40;
    
    // The degrees per pixel
    var mapDiv = map.getDiv();
    var mapWidth = mapDiv.offsetWidth;
    var mapHeight = mapDiv.offsetHeight;
    var boundsSpan = bounds.toSpan();
    var longSpan = boundsSpan.lng();
    var latSpan = boundsSpan.lat();
    var degPixelX = longSpan / mapWidth;
    var degPixelY = latSpan / mapHeight;
    
    // The bounds of the map
    var mapWestLng = bounds.getSouthWest().lng();
    var mapEastLng = bounds.getNorthEast().lng();
    var mapNorthLat = bounds.getNorthEast().lat();
    var mapSouthLat = bounds.getSouthWest().lat();
    
    // The bounds of the infowindow
    var iwWestLng = position.lng() + (iwOffsetX - padX) * degPixelX;
    var iwEastLng = position.lng() + (iwOffsetX + iwWidth + padX) * degPixelX;
    var iwNorthLat = position.lat() - (iwOffsetY - padY) * degPixelY;
    var iwSouthLat = position.lat() - (iwOffsetY + iwHeight + padY) * degPixelY;
    
    // calculate center shift
    var shiftLng = (iwWestLng < mapWestLng ? mapWestLng - iwWestLng : 0) + (iwEastLng > mapEastLng ? mapEastLng - iwEastLng : 0);
    var shiftLat = (iwNorthLat > mapNorthLat ? mapNorthLat - iwNorthLat : 0) + (iwSouthLat < mapSouthLat ? mapSouthLat - iwSouthLat : 0);
    
    // The center of the map
    var center = map.getCenter();
    
    // The new map center
    var centerX = center.lng() - shiftLng;
    var centerY = center.lat() - shiftLat;
    
    // center the map to the new shifted center
    // map.setCenter(new google.maps.LatLng(centerY, centerX));
    
    // Remove the listener after panning is complete.
    google.maps.event.removeListener(this.boundsChangedListener_);
    this.boundsChangedListener_ = null;
};

/**
 * Draw directions on the map
 * 
 * @param google.maps.LatLng from     From location
 * @param google.maps.LatLng to       Destination object
 */
function draw_directions(from, to, mode)
{
    if (!from)
    {
        from = initial_location;
    }
    
    // Remove existing directions
    if (map_directions)
    {
        map_directions.setMap(null);
    }
    
    if (!mode)
    {
        if (jQuery.cookie('travel_mode'))
        {
            mode = jQuery.cookie('travel_mode');
        }
        else
        {
            mode = google.maps.DirectionsTravelMode.DRIVING;
        }
    }
    else
    {
        jQuery.cookie
        (
            'travel_mode',
            mode,
            {
                expires: (1 / 24),
                path: '/'
            }
        );
    }
    
    map_directions = new google.maps.DirectionsRenderer
    (
        {
            suppressMarkers: true,
            polylineOptions:
            {
                strokeColor: '#000000',
                strokeOpacity: 0.4,
                strokeWeight: 5,
                clickable: false
            }
        }
    );
    var dserv = new google.maps.DirectionsService();
    
    var request =
    {
        origin: from,
        destination: to,
        travelMode: mode
    };
    
    dserv.route(request, function(result, status)
    {
        if (status == google.maps.DirectionsStatus.OK)
        {
            map_directions.setDirections(result);
            map_directions.setMap(map);
        }
    });
}

jQuery.fn.slideshow = function(attribute)
{
    slideshow_count = jQuery(this).size();
    
    var attribute = attribute || 'img';
    
    jQuery(this).each(function(i)
    {
        if (jQuery(this).find(attribute).size() < 2)
        {
            return;
        }
        
        jQuery(this).attr('slideshow', attribute);
        
        jQuery(this).addClass('_slideshow');
        
        jQuery(this).find('img').addClass('_slideshow_image');
        jQuery(this).find('img').not(':first')
            .css('z-index', '-1');
        
        jQuery(this).oneTime(i * 500 + 50, function()
        {
            jQuery(this)
                .bind('mouseover', function()
                {
                    jQuery(this).addClass('hover');
                })
                .bind('mouseout', function()
                {
                    jQuery(this).removeClass('hover');
                })
                .everyTime(5000, 'slideshow', function()
                {
                    if (jQuery(this).hasClass('hover'))
                    {
                        return;
                    }
                    
                    var images = jQuery(this).find(jQuery(this).attr('slideshow'));
                    var index = 0;
                    
                    for (var i = 0; i < images.size(); i++)
                    {
                        if (images.eq(i).hasClass('display'))
                        {
                            index = i;
                            break;
                        }
                    }
                    
                    var count = images.size();
                    
                    if (index + 1 >= count)
                    {
                        next = 0;
                    }
                    else
                    {
                        next = index + 1;
                    }
                    
                    images.eq(index)
                        .css('z-index', 99)
                        .removeClass('display')
                        .oneTime(500, function()
                        {
                            jQuery(this).fadeOut(1000);
                        });
                    
                    images.eq(next)
                        .css('z-index', 101)
                        .fadeIn(1000, function()
                        {
                        })
                        .addClass('display');
                });
            
            jQuery(this).find(jQuery(this).attr('slideshow') + ':first')
                .addClass('display');
            
            jQuery(this).find(jQuery(this).attr('slideshow')).not(':first')
                .fadeOut(0);
        });
    });
}

// Quick'n'dirty no-Firebug error prevention
if (typeof console == 'undefined')
{
    console = 
    {
        log: function(input)
        {
            // alert(input);
        },
        warn: function(input)
        {
            this.log(input);
        },
        error: function(input)
        {
            this.log(input);
        }
    }
}


