/**
 * This file contains the custom plugins written for the CEP
 * portal.
 *
 * @version 1.0
 * @author Rikki Carroll
 */

// The closure creates a private area which will not conflict with any other
// javascript. We accept a parameter $ which the jQuery object is passed through
// which will allow us to use other libraries using the $ namespace while in
// this closure using the $ to reference jQuery.
(function($) {

    /**
     * jQuery plugin which, when given a form element will
     * make its initial value the default value. If the user clicks
     * the textfield, the default text will disappear. If they
     * deselect the field and the field is empty the initial value
     * will reappear.
     *
     * @version 1.0
     * @author Rikki Carroll
     */
    $.fn.inputDefaults = function() {
        // Apply the plugin behaviour to all the elements found by jQuery
        // and return the elements for chaining.
        return $(this).each(function() {
            // grab the label
            var input = $(this);

            // get the label value and corresponding form field
            var defaultValue = input.val();

            // now put the default value in a custom attrib
            input.attr('defaultValue', defaultValue);

            input.css('color', '#666');

            // add the focus handler
            input.focus(function() {
                // grab a jQuery reference to the input
                var el = $(this);

                // grab the elements default value
                var defaultVal = el.attr('defaultValue');

                // if the element contains the default value, strip it
                if (el.val() == defaultVal) {
                    el.val('');
                }

                // darken the text color indicating the element is now active
                el.css('color', '#333');
            });

            // add the blur handler
            input.blur(function() {
                // grab a jQuery reference to the selected input element
                var el = $(this);

                // if the input is empty, put the default value back into the field
                if ($.trim(el.val()) == '') {
                    el.val(el.attr('defaultValue'));
                }

                // lighten the text color, indicating that the element is no longer active
                el.css('color', '#666');
            });
        });
    }


    /**
     * jQuery plugin to make groups of content collapsable.
     *
     * @version 1.0
     * @author Rikki Carroll
     */
    $.fn.togglePanels = function() {
        // Apply the plugin behaviour to all the elements found by jQuery
        // and return the elements for chaining.
        return $(this).each(function() {
            // grab a jquery reference to the current collapsable panel
            var container = $(this);
            
            // hide the contents of collapsable panel
            $('.pad', container).hide();
            
            // add click and hover behaviours to the h3
            $('h3', container).click(function() {
                // when the h3 is clicked open or close the contents
                $(this).parent().find('.pad').slideToggle(200);

                // add the open class to the clicked h3
                $(this).toggleClass('open');
            }).hover(
                function() {// add the hover class, changing the appearence
                    $(this).addClass('hover');
                },
                function() {
                    // remove the hover class restoring its original appearence
                    $(this).removeClass('hover');
                }
            );
        });
    }


    /**
     * jQuery plugin making it easy to make javascript tabs as long as their
     * html has a given format. The format needs to be as follows:
     * <code>
     *  <div class="tabname">
     *      <div class="tab-navigation">
     *          <ul>
     *              <li><a href="#tab1">Tab 1</a></li>
     *              <li><a href="#tab2">Tab 2</a></li>
     *          </ul>
     *      </div>
     *
     *      <div id="tab1" class="tab-content">
     *          tab 1 contents here
     *      </div>
     *
     *      <div id="tab2" class="tab-content">
     *          tab 2 contents here
     *      </div>
     *  </div>
     * </code>
     * 
     * Example usage:
     *  <code>$('#tabs').cepTabs();</code>
     *
     * @version 1.0
     * @author Rikki Carroll
     */
    $.fn.cepTabs = function() {
        // first lets grab a reference to the tab container
        var tabContainer = $(this);

        // if a hash is specified in the URL open that tab
        if (window.location.hash != '') {
            var tab = $('.tab-navigation li a[href*="'+window.location.hash+'"', tabContainer);

            if (tab.length > 0) {
                showTab(tab);
            }
            else {
                // show the first tab if the tab could not be found
                showTab($('.tab-navigation li a:first', tabContainer));
            }
        }
        // otherwise show the first tab
        else {
            showTab($('.tab-navigation li a:first', tabContainer));
        }

        // add a click event handler to show the corresponding area
        $('.tabs .tab-navigation li a').click(function() {
                showTab($(this));

                // prevent the default action which is to skip the the anchor on the page with the corresponding hash
                return false;
        });

        // given a jquery object to a link will open the tab for that link
        function showTab(jq)
        {
                hideAll();

                // add the current class to the tab that was clicked
                jq.parent('li').addClass('current');
                
                // show the content area for the current tab item
                $(jq.attr('href')).show();
        }

        function hideAll()
        {
                // remove the current class from all tabs
                $('.tab-navigation li', tabContainer).removeClass('current');

                // hide all the content areas
                $('.tab-content', tabContainer).hide();
        }
    }


    /**
     * Used for reloading search results. Sets up each ordering link to reload
     * the results section.
	 * 
     * @version 1.0
     * @author Justice Addison
     */
    $.fn.searchOrderTagReload = function() {
        // first lets grab a reference to the tab container
        var tag = $(this);
		
		//for each link, set its href attribute to # (so it doesnt reload the page),
		//then add a click function that reloads the results section
		tag.find('a.search-order-by-link').each(function(){
			var link = $(this).attr('href');
			$(this).attr('href', '#');
			$(this).bind('click', function(){
				tag.load(link + ' #' + tag.attr('id'), function(){
					//replace the content of the original tag with that of newly loaded tag
					//to avaid tag duplication.					
					tag.html($(this).find("#"+tag.attr('id')).html());
					
					//re-run this function on the newly loaded 
					tag.searchOrderTagReload();
				});
				
				
			});
		});
		
		//alert(links[1]);
		//alert(tag.attr('id'));
		
    }
	
	
	/**
     * Used to set an element to hold a man for a geometic coordinate element
	 * 
     * @version 1.0
     * @author Justice Addison
     */
    $.fn.createGeoMap = function() {
		// Inputs I have to play with
		var coorInput = $(this);
		var postcodeElement;
		var countryElement;
		var regionElement;
		var localityElement;
		var routeElement;
		
		var mapHolder;
		var map;
		var geocoder;
		var infowindow = new google.maps.InfoWindow();
		var marker;
		
		mapHolder = $('<div></div>');
		mapHolder.addClass('geoMapHolder');
		
		if($('#'+coorInput.attr('postcodeElementID'))) postcodeElement = $('#'+coorInput.attr('postcodeElementID'));
		if($('#'+coorInput.attr('countryElementID'))) countryElement = $('#'+coorInput.attr('countryElementID'));
		if($('#'+coorInput.attr('regionElementID'))) regionElement = $('#'+coorInput.attr('regionElementID'));
		if($('#'+coorInput.attr('localityElementID'))) localityElement = $('#'+coorInput.attr('localityElementID'));
		if($('#'+coorInput.attr('routeElementID'))) routeElement = $('#'+coorInput.attr('routeElementID'));
		
		coorInput.removeAttr('postcodeElementID');
		coorInput.removeAttr('countryElementID');
		coorInput.removeAttr('regionElementID');
		coorInput.removeAttr('localityElementID');
		coorInput.removeAttr('routeElementID');

		function initialize() {
		
			//use default coordinate first
			var myLatlng = new google.maps.LatLng(51.27963576689547, 1.0806084929199642);
			
			//geocoding object
			geocoder = new google.maps.Geocoder();
			
			var myOptions = {
				zoom: 4,
				center: myLatlng,
				mapTypeId: google.maps.MapTypeId.ROADMAP
			}
			
			map = new google.maps.Map(mapHolder.get(0), myOptions);
			
			marker = new google.maps.Marker({
				position: myLatlng, 
				map: map,
				draggable: true
			});
			
			google.maps.event.addListener(marker, 'dragend', function(event) {
				setInputsFromLocation(event.latLng);
				map.setCenter(event.latLng);
				
			});
			
			// try to update marker with coordinate input
			myLatlng = getLocationFromCoordinateString(coorInput.val());
			if(myLatlng){
				placeMarker(myLatlng);
			}
			
			//if no coordinate available, try to use the post code
			else {
				if(postcodeElement){
					if(postcodeElement.val() != ''){
						getLocationFromPostcode(postcodeElement.val(), coorInput);
					}
				}
			}
			
			coorInput.parent().append(mapHolder);
		}
		
		function  setInputsFromLocation(latlng){
			coorInput.val(latlng.lat() + ', ' + latlng.lng());
			getAddressFromLocation(latlng);
		}
		
		function getAddressFromLocation(latlng){
			
			//clear fields in preparation for a new ones
			postcodeElement.val('');
			countryElement.val('');
			regionElement.val('');
			localityElement.val('');
			routeElement.val('');
			
			//do the reverse geocoding
			geocoder.geocode({'latLng': latlng}, function(results, status) {
				if (status == google.maps.GeocoderStatus.OK) {
					if (results[0]) {
						if(results[0].address_components){
							$.each(results[0].address_components, function(index1, component){
								if($.inArray('postal_code', component.types) != -1){
									if(postcodeElement){
										//the first returned postcode is usually the most accurate so ignore all others
										if(postcodeElement.val() == ''){
											postcodeElement.val(component.long_name);
										}
									}
								}
								else if($.inArray('country', component.types) != -1){
									if(countryElement){
										countryElement.val(component.short_name);
									}
								}
								else if($.inArray('administrative_area_level_2', component.types) != -1){
									if(regionElement){
										if(regionElement.val() == ''){
											regionElement.val(component.long_name);
										}
									}
								}
								else if($.inArray('locality', component.types) != -1){
									if(localityElement){
										if(localityElement.val() == ''){
											localityElement.val(component.long_name);
										}
									}
								}
								else if($.inArray('route', component.types) != -1){
									if(routeElement){
										if(routeElement.val() == ''){
											routeElement.val(component.long_name);
										}
									}
								}
								else{
									//alert(component.types+': '+component.long_name)
								}
								
								
								
							});
						}
					}
				}
			});
		}
		
		function getLocationFromPostcode(postCode, coorInput){
			
			//clear postcode in preparation for a new one
			coorInput.val('');
			
			//do the geocoding
			geocoder.geocode({'address':postCode}, function(results, status) {
				if (status == google.maps.GeocoderStatus.OK) {
					var latlng = results[0].geometry.location;
					coorInput.val(latlng.lat() + ', ' + latlng.lng());
					placeMarker(latlng);
				}
			});
			
		}
		
		
		function getLocationFromCoordinateString(coorString){
			if(coorString){
				var input = coorString;
				var latlngStr = input.split(",",2);
				var lat = parseFloat(latlngStr[0]);
				var lng = parseFloat(latlngStr[1]);
				var latlng = new google.maps.LatLng(lat, lng);
				return latlng;
			}
			return false;
		}
  
		function placeMarker(latlng) {
			marker.setPosition(latlng);
			map.setCenter(latlng);
		}
		
		coorInput.change(function() {
			var latlng = getLocationFromCoordinateString($(this).val());
			if(latlng.lat()){
				placeMarker(latlng);
				getAddressFromLocation(latlng);
			}
		});
		
		if(postcodeElement){
			postcodeElement.change(function() {
				if($(this).val() != ''){
					getLocationFromPostcode($(this).val(), coorInput);
				}
			});
		}
		
		initialize();
	}
    
    
    // automatically run some of the plugins
    $(document).ready(function() {
        $('.collapsable').togglePanels();

        $('a.popup').fancybox({
            'hideOnContentClick': true,
            'overlayShow': true
        });
		
		$('.geoMapInput').createGeoMap();
    });

})(jQuery); // run the contents of the closure immediatly passing the jquery object
