/*
 * Enchance elements' prototypes
 */
Event.observe(document, 'dom:loaded', function()
{
    // define common vars
    var URL =
    {
        'validate'  : '/validate',
        'message'   : '/message'
    };

    // Extend Object
    Object.extend(Object,
    {
        isObject: function(object)
        {
            return (typeof object == 'object');
        }
    });

    Element.addMethods(
    {
        'active': function(element, status)
        {
            element = $(element);

            var active = element.retrieve('active', false);

            // getter
            if (typeof status == 'undefined')
            {
                return active;
            }

            // setter
            if (status)
            {
                active = true;
                element.addClassName('active');
            }
            else
            {
                active = false;
                element.removeClassName('active');
            }

            element.store('active', active);

            return element;
        },

        'empty': function(element, status)
        {
            element = $(element);

            var empty = element.retrieve('empty', false);

            // getter
            if (typeof status == 'undefined')
            {
                return empty;
            }

            // setter
            if (status)
            {
                empty = true;
                element.addClassName('empty');
            }
            else
            {
                empty = false;
                element.removeClassName('empty');
            }

            element.store('empty', empty);

            return element;
        },

        'isEmpty': function(element)
        {
            element = $(element);

            switch(element.tagName)
            {
                case 'INPUT':
                case 'TEXTAREA':
                    return (element.value.length == 0);
                    break;

                default:
                    return (element.innerHTML.stripTags().length == 0);
            }
        },

        'setText': function(element, text)
        {
            element = $(element);

            switch(element.tagName)
            {
                case 'INPUT':
                case 'TEXTAREA':
                    element.value = text;
                    break;

                default:
                    element.update(text); // TODO: maybe dangerous
            }
        }
    });

    // hide errors div on load
    if ($('errors'))
    {
        $('errors').hide();
    }

    Errors =
    {
        'init': function(target)
        {
                this.target = target;
        },

        // push new error message to the messages array
        // TODO: Make it as real array with representation in #errors div
        // TODO: Make it to pull error message text from db by given message handler
        'push': function(text, messageId)
        {
            // get text
            if (text.indexOf(' ') < 1)
            {
                var errors = $(document.body).retrieve('errors', []);

                if (errors[text])
                {
                    // Call itself again with new data
                    Errors.push(errors[text], messageId);
                }
                else
                {
                    requestData(URL['message'], {'message': text}, function(data)
                    {
                        // get errors array
                        var errors = $(document.body).retrieve('errors', []);

                        // store fetched message
                        errors[data['key']] = data['message'];

                        // put it back to the docuemnt
                        $(document.body).store('errors', errors);

                        // Call itself again with new data
                        Errors.push(data['message'], messageId);
                    });
                }
            }
            else
            {
                if (this.target)
                {
                    if (!(this.target.down('ul')))
                    {
                        this.target.insert({'bottom': new Element('ul')});
                    }
    
                    // remove old message if we have one
                    if (messageId && $(messageId))
                    {
                        $(messageId).remove();
                    }
                    else
                    {
                        var messageId = 'error_' + Math.floor(Math.random()*999);
                    }
    
                    this.target.down('ul').insert({top: new Element('li', {'id': messageId}).update(text)});
    
                    if (!$('errors').visible())
                    {
                        Effect.BlindDown('errors');
                    }
    
                    return messageId;
                }
                else
                {
                    alert(text);
                }
            }

            return messageId;
        },

        // pop error message by given id
        'pop': function(messageId)
        {
            var text;
            // remove old message if we have one
            if (messageId && $(messageId))
            {
                text = $(messageId).innerHTML;

                $(messageId).remove();
            }

            return text;
        }
    };


    // }}}

/* Ajax wrapper */

    // TODO: Make it as part of the framework
    window.requestData = function(url, params, callback)
    {
        var token;
    
        if (token = readCookie('session'))
        {
            params = $H(params).merge({"token": token});
        }
    
        new Ajax.Request(url+'.json',
        {
            'method': 'post',
            'parameters': params,
            'requestHeaders': {'Accept': 'application/json'},
            'onSuccess': function(transport)
            {
                // eval received json
                var jsonData = transport.responseText.evalJSON(true);
                callback(jsonData);
            }
        });
    }

/* pretty looking alert */

    // TODO: Make it as part of the framework
    window.oAlert = window.alert;

    window.alert = function(message)
    {
        if (isSet('IA') && IA.alert)
        {
            IA.alert(message);
        }
        else
        {
            oAlert(message);
        }

        return true;
    }

// done with library load
// let others to do their job

    Event.fire(document, 'core:loaded');

});

/*
 * Common functions
 */

function isSet(v)
{
    if (typeof window[v] != "undefined")
    {
        return true;
    }

    return false;
}

/* from: http://www.quirksmode.org/js/cookies.html */

function createCookie(name, value, days)
{
    if (days)
    {
        var date = new Date();
        date.setTime(date.getTime()+(days*24*60*60*1000));
        var expires = "; expires="+date.toGMTString();
    }
    else
    {
        var expires = "";
    }

    document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name)
{
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');

    for (var i=0;i < ca.length;i++)
    {
        var c = ca[i];

        while (c.charAt(0)==' ')
        {
            c = c.substring(1,c.length);
        }

        if (c.indexOf(nameEQ) == 0)
        {
            return c.substring(nameEQ.length,c.length);
        }
    }

    return null;
}

function eraseCookie(name)
{
    createCookie(name, "", -1);
}

// Based on http://awardwinningfjords.com/2009/07/22/google-maps-with-jquery.html
function googleMap(element, address, options)
{
    element = $(element);

    var defaults =
    {
        'lat':  43.64443718246104,
        'long': -79.40009389999999,
        'zoom': 16,
        'mapTypeId': google.maps.MapTypeId.ROADMAP,
        'disableDefaultUI': true,
        'navigationControl': true,
        'navigationControlOptions': {'style': google.maps.NavigationControlStyle.SMALL},
        'scaleControl': false,
        'scrollwheel': false
    };

    options         = Object.extend(defaults, options || {});

    var center      = new google.maps.LatLng(options.lat, options.long);
    var map         = new google.maps.Map(element, Object.extend(options, {'center': center}));

    // store default location
    map.defaultLocation = center;

    var geocoder    = new google.maps.Geocoder();

    bounds = new google.maps.LatLngBounds(new google.maps.LatLng(43.3884577624356, -79.77880020141606), new google.maps.LatLng(44.04157565564786, -79.07018203735356));

    geocoder.geocode({ 'address': address, 'bounds': bounds }, function(results, status)
    {
        if (status == google.maps.GeocoderStatus.OK && results.length)
        {
            if (status != google.maps.GeocoderStatus.ZERO_RESULTS)
            {
                map.set_center(results[0].geometry.location);

                map.defaultLocation = map.getCenter();

                var marker = new google.maps.Marker(
                {
                    'position': map.getCenter(),
                    'map': map
                });
            }
        }
    });

    return map;
}

function googleMapShowRoute(map, from, panel)
{
    if (typeof directionsService == 'undefined')
    {
        directionsService = new google.maps.DirectionsService();
    }
    if (typeof directionsDisplay == 'undefined')
    {
        directionsDisplay = new google.maps.DirectionsRenderer();
    }

    // show panel if so
    if (panel)
    {
        panel = $(panel);
        directionsDisplay.setPanel(panel);
    }

    directionsDisplay.setMap(map);

    var geocoder    = new google.maps.Geocoder();

    bounds = new google.maps.LatLngBounds(new google.maps.LatLng(43.3884577624356, -79.77880020141606), new google.maps.LatLng(44.04157565564786, -79.07018203735356));

    geocoder.geocode({ 'address': from, 'bounds': bounds }, function(results, status)
    {
        if (status == google.maps.GeocoderStatus.OK
            && results.length
            && status != google.maps.GeocoderStatus.ZERO_RESULTS)
        {
            from = results[0].geometry.location;

            var request =
            {
                'origin': from, 
                'destination': map.defaultLocation,
                'travelMode': google.maps.DirectionsTravelMode.DRIVING
            };
        
            directionsService.route(request, function(response, status)
            {
                if (status == google.maps.DirectionsStatus.OK)
                {
                    directionsDisplay.setDirections(response);
                }
            });
        }
        else
        {
            var request =
            {
                'origin': from, 
                'destination': map.defaultLocation,
                'travelMode': google.maps.DirectionsTravelMode.DRIVING
            };
        
            directionsService.route(request, function(response, status)
            {
                if (status == google.maps.DirectionsStatus.OK)
                {
                    directionsDisplay.setDirections(response);
                }
                else
                {
                    var request =
                    {
                        'origin': from + ', Toronto, Canada', 
                        'destination': map.defaultLocation,
                        'travelMode': google.maps.DirectionsTravelMode.DRIVING
                    };
                
                    directionsService.route(request, function(response, status)
                    {
                        if (status == google.maps.DirectionsStatus.OK)
                        {
                            directionsDisplay.setDirections(response);
                        }
                        else
                        {
                            alert('Unable to find entred location.\n\nPlease refine your search string.');
                        }
                    });

                }
            });
        }
    });

}

/* set IE flag to false */
NO_FEATURES = false;