﻿var map;
var container;

    var zoomLevel = 6;          // Default level when user logged in
    var anonZoomLevel = 12;     // Zoom level for not logged in users 
    var CurrentLat;
    var CurrentLong;
    var t;
    var mapMarkers = [];
    var mapClusters = [];
    var pinImages = new Array();
    var requirements =[];
    var glocCurrent = new GLatLng(latHome, longHome);
    var msgNames = [];
    var progress;
    var progressbar;
    var progressstatus;
    var progressmessage;
    var modalHTML;
    var CurrentRequirement = 0;
    var RequirementTotal = 0;
    var PageListTotal = 0;
    var iPageSize = 20;
    var searchtimeout = 5000;
    var showwelcomebox = true;
    var control = new Array();
    var  viewportwidth;
    var  viewportheight;
    var iQARequirementID = 0;
    var volOpportunities = [];
    
    control[0] = "e.g. Banbury or MK5"; // txtlocation
    control[1] = 'e.g. Nurse or Teacher or "Sales manager" or "Technical manager" and (engineering or marine)';


    
    function pageonload(){
       
        progress = $('progress');
        progressbar = $('progressbar');
        progressstatus = $('progressstatus');
        progressmessage = $('progressmessage');
        
        if (GBrowserIsCompatible()) {

            container = $('map');
            map = new GMap2(container);

            var iZoomLevel = 0;

                CurrentLat = parseFloat(latHome);
                CurrentLong = parseFloat(longHome);

            
           glocCurrent = new GLatLng(CurrentLat, CurrentLong);

            map.setCenter(glocCurrent, anonZoomLevel);
            
            reCentre();

            map.setMapType(G_PHYSICAL_MAP); 
            map.addMapType(G_PHYSICAL_MAP);
            map.enableScrollWheelZoom();
            
            // Add the zoom controls to the map
            map.addControl(new GLargeMapControl());
            
            // Add the may type control
            map.addControl(new GHierarchicalMapTypeControl());
            
            // Set the options for the drag zoom control
            var optionsSelector = { 
              buttonStartingStyle: {background: '#FFF', paddingTop: '4px', paddingLeft: '4px', border:'1px solid black'},
              buttonHTML: '<img title="Drag to Select" src="http://static.zubed.com/images/icons/shape_group.png">',
              buttonStyle: {width:'20px', height:'20px'},
              buttonZoomingStyle: {background:'yellow',width:'75px', height:'100%'},
              backButtonEnabled: false, 
              overlayRemoveTime: 500,
              restrictedRectangleMap: false            
              } 

             // Add the DragZoom control
                map.addControl(new DragZoomControl({}, 
                               optionsSelector, 
                               {
                                    dragend:function(nw,ne,se,sw,nwpx,nepx,sepx,swpx){
                                        
                                        map.setZoom(iSelectorZoomLevel);
                                        map.setCenter(iSelectorPoint);
                                        //selectPoints(nw,ne,se,sw,nwpx,nepx,sepx,swpx);
                                        doDragzoom(nw,ne,se,sw,nwpx,nepx,sepx,swpx);
                                        return false;
                                    },
                                    dragstart:function(x,y){
                                        iSelectorZoomLevel = map.getZoom();
                                        iSelectorPoint = map.getCenter();
                                    }
                               }), new GControlPosition(G_ANCHOR_TOP_LEFT,new GSize(25,290)));
            
            
        } else {
            displayError("Browser cannot handle Google Maps");
        }
        
        if (showwelcomebox == true)
        {          
            var bubblebody = '';

            bubblebody += '<div id="demobubble" style="width: 350px;">';
            bubblebody += '<p><span class="bubble-title">Welcome</span></p>';
            bubblebody += '<p>We want to help more people get back to work by making it easy for job seekers to find local jobs and for employers to post their jobs.</p>';
            bubblebody += '<p>All free of charge.</p>';
            bubblebody += '<p>Type your location or postcode in the search box to get started.</p>';
            bubblebody += '<br></div >';

            map.openInfoWindowHtml(new GLatLng(CurrentLat, CurrentLong), bubblebody);

            showwelcomebox=false;
        }
        
        GEvent.addListener(map, "click", function(marker) {
            showBubble(marker);
        });
        
        page_resize();
        reCentre();
        
/*                          
        // the more standards compliant browsers (mozilla/netscape/opera/IE7) use window.innerWidth and window.innerHeight
        if (typeof window.innerWidth != 'undefined')
        {
            viewportwidth = window.innerWidth,
            viewportheight = window.innerHeight
        }
        // IE6 in standards compliant mode (i.e. with a valid doctype as the first line in the document)
         else if (typeof document.documentElement != 'undefined'
         && typeof document.documentElement.clientWidth !=
         'undefined' && document.documentElement.clientWidth != 0)
        {
           viewportwidth = document.documentElement.clientWidth,
           viewportheight = document.documentElement.clientHeight
        }    
        // older versions of IE
        else
        {
           viewportwidth = document.getElementsByTagName('body')[0].clientWidth,
           viewportheight = document.getElementsByTagName('body')[0].clientHeight
        } 
        
        //Finally set iPageSize
        iPageSize = Math.round((viewportheight * 0.8) / 35)
*/
        //Set up the tabbed view for the search criteria box
        initTabs('SearchTabs',['Jobs', 'Volunteering'],(volActive?1:0),'100%','100%',[false,false],['Jobs', 'Volunteering']);
    
        page_resize();
        
        if (typeof(doVolSearch)!="undefined" && doVolSearch == true) {
            volSearch();
        }
    }

    function doDragzoom(nw,ne,se,sw,nwpx,nepx,sepx,swpx) {
        
        requirements = [];
        var myBounds = new GLatLngBounds(sw, ne);
        
        for (var i = 0; i < mapMarkers.length; i++) {
            if (myBounds.containsLatLng(mapMarkers[i].getLatLng())) {
                for (var j = 0; j < mapMarkers[i].requirementID.length; j++) {
                   requirements.push(mapMarkers[i].requirementID[j]);                    
                }
            }
        }
       
      RequirementTotal = requirements.length;
      DisplayRequirementList(1); 
    }

    function reCentre() {
        map.checkResize();
        map.setCenter(new GLatLng(CurrentLat,CurrentLong), zoomLevel);
        clearTimeout(t);
    }
    
    
    function advancedSearch(geonameID) {
        
        $('searchwarning').style.display="none";
        $('msgpopup').style.display="none";
        $('locationmessage').innerHTML = '';
        validationReset('txtLocation','ErrorDiv_txtLocation');
        
        if ( $F('txtLocation').length < 2|| $F('txtLocation')== control[0]) {
            // Show validation error message.
            validationerror('txtLocation','ErrorDiv_txtLocation','Please enter a postcode or location.');
            return;
        }
        
        var searchLoc = $F("txtLocation");
        var searchWords = ($F("txtKeywords")==control[1])?'':$F("txtKeywords");
        $('btnAdvSearch').value = 'Searching..';
        $('btnAdvSearch').disabled='true';
        
        // disable the search button for a set period
        setTimeout("resetSearchButton()", searchtimeout);
        
        // Clear the map
        clearAllMarkers();
    
        showProgress("Searching...", "Retrieving data");
    
        // Run the main search function
        PlotPoints(searchLoc, searchWords, CurrentLat, CurrentLong, geonameID);
        setTimeout("updateProgress(1, 'Finished')", 10);
        
        // Only show 'Save Search' button if logged in.
        if (isLoggedIn == true){$('modalLink').style.display = '';}
        
        return false;
    }
    
    function resetSearchButton() {
        $('btnAdvSearch').disabled='';
        $('btnAdvSearch').value = 'Search';
    }
    
    function PlotPoints(pcode, keywords, Lat, Long, geonameID) {
        
        //Create the search parameters object
        var searchRadius = $F('drpRadius');
        
        var searchObj = getSearchParams(pcode, keywords, searchRadius, geonameID);
        
        // Display error and jump out if location not found.
        if (searchObj.error === true) {
            // no valid location found so display warning!
            validationerror('txtLocation','ErrorDiv_txtLocation','Postcode or location could not be found!');
            return false;
        }
        
        updateProgress(0, "Plotting...");
        
        var oSearch = new SearchAPI();
        var oSearchResult = oSearch.getResults(searchObj);
        var currlat;
        var currlng;
        var pointrequirementid = [];
        var pointindex = 0;
        var pointType = 0;
        
        if (oSearchResult.length <= 0 ) {
            showNoResults();
            return false;
        }
        
        if (oSearchResult.length >= 1000 ) {
            
            setTimeout("Effect.Appear('searchwarning', { duration: 0.2, from: 0, to: 1 })",10);
            setTimeout("Effect.Fade('searchwarning', { duration: 0.2, from: 1, to: 0 })",10000);
     
        }
        
        for (var i = 0; i < oSearchResult.length; i++) {
        
            if (currlat == roundNumber(oSearchResult[i].lat, 3) && currlng == roundNumber(oSearchResult[i].lng, 3)) {
                
                pointrequirementid[pointindex] = oSearchResult[i].reqID;
                if (pointType<oSearchResult[i].locationType) {
                    pointType = oSearchResult[i].locationType;
                }
                pointindex += 1;
                
            } else {
            
                if (pointrequirementid.length != 0 ) {
                    
                    marker = new GMarker(new GLatLng(currlat, currlng), getIcon('marker', pointType));
                    marker.requirementID = pointrequirementid;
                    marker.clusterID = -1;
                    mapMarkers.push(marker);
                    pointrequirementid = [];
                    pointindex = 0;
                }
                
                currlat = roundNumber(oSearchResult[i].lat, 3);
                currlng = roundNumber(oSearchResult[i].lng, 3);
                pointrequirementid[pointindex] = oSearchResult[i].reqID;
                pointType = oSearchResult[i].locationType;
                pointindex += 1;
            }
        }
        
        // Push last marker if array not empty
        if (pointrequirementid.length != 0 ) {
                    
            marker = new GMarker(new GLatLng(currlat, currlng), getIcon('marker', pointType));
            marker.requirementID = pointrequirementid;
            //map.addOverlay(marker);
            marker.clusterID = -1;
            mapMarkers.push(marker);

        }

        if (mapMarkers.length > 50) {
            //do some clustering
            var clusterRadius = searchRadius / 5;
            for (var i = 0; i < mapMarkers.length - 1; i++) {
                //if this point not already clustered
                if (mapMarkers[i].clusterID < 0) {
                    //work out a bounding box for this point
                    var thisPoint = mapMarkers[i].getLatLng();
                    var myNE = getPointBearingDist(thisPoint, 45, clusterRadius);
                    var mySW = getPointBearingDist(thisPoint, 225, clusterRadius);
                    var myBounds = new GLatLngBounds(mySW, myNE);
                    //array to gather markers
                    var thisCluster = [];
                    var jobcount = 0;
                    // loop through the rest of the marker array
                    for (var j = i+1; j < mapMarkers.length; j++) {
                        //if this point is not already clustered
                        if (mapMarkers[j].clusterID < 0) {
                            //check if it is in the bounds of our start point
                            if (myBounds.containsLatLng(mapMarkers[j].getLatLng())) {
                                //include in cluster
                                mapMarkers[j].clusterID = mapClusters.length;
                                thisCluster.push(mapMarkers[j]);
                                jobcount += mapMarkers[j].requirementID.length;
                            }
                        }                        
                    }
                    
                    //did we find any cluster candidates
                    if (thisCluster.length > 0) {
                        //create the cluster
                        //include the original point
                        mapMarkers[i].clusterID = mapClusters.length;
                        thisCluster.push(mapMarkers[i]);
                        jobcount += mapMarkers[i].requirementID.length;
                        //add the cluster to the array, with its markers
                        mapClusters.push({
                                point:calcAvgLatLng(thisCluster),
                                jobCount:jobcount,
                                markers:thisCluster
                            });
                    }
                }
            }
        }
        
        //display the clusters
        for (var i = 0; i < mapClusters.length; i++) {
            var cluster = new GMarker(mapClusters[i].point, getIcon('cluster',mapClusters[i].jobCount) );
            cluster.clusterID = i
            map.addOverlay(cluster);
        }
        
        //display the individual markers
        for (var i = 0; i < mapMarkers.length; i++) {
            //if this point is not clustered
            if (mapMarkers[i].clusterID < 0) {
                map.addOverlay(mapMarkers[i]);
            }
        }  
        
        //Show the legend
        doBoxHide("vollegend");
        doBoxOpen("legend");
        
        // Show the dragzoom helper if no cookie found
        if (!getCookie('dzhelper')) {
            setTimeout("Effect.Appear('dzhelpholder', { duration: 0.2, from: 0, to: 1 })",10);
            setTimeout("Effect.Fade('dzhelpholder', { duration: 0.2, from: 1, to: 0.9 })",1000);
            setTimeout("Effect.Fade('dzhelpholder', { duration: 0.2, from: 1, to: 0 })",10000);
        }
    }
    
    
    function calcAvgLatLng(markers) {
        var minLat = 0;
        var minLng = 0;
        var maxLat = 0;
        var maxLng = 0;
        for (var i = 0; i < markers.length; i++) {
            var thisLatLng = markers[i].getLatLng();
            if (i==0) {
                minLat = thisLatLng.lat();
                maxLat = thisLatLng.lat();
                minLng = thisLatLng.lng();
                maxLng = thisLatLng.lng();
            } else {
                minLat = Math.min(minLat, thisLatLng.lat());
                maxLat = Math.max(maxLat, thisLatLng.lat());
                minLng = Math.min(minLng, thisLatLng.lng());
                maxLng = Math.max(maxLng, thisLatLng.lng());
            }
        }        
        var avgLat = minLat + ((maxLat - minLat) / 2);
        var avgLng = minLng + ((maxLng - minLng) / 2);
        return new GLatLng(avgLat, avgLng);
    }
    
    
    function getSearchBounds(centre, radius) {
        /*  
            Dev:    Steve Brockton
            Date:   2007-09-18
            Desc:   get the bounds required for a search radius
        */
        var point = getPointBearingDist(centre, 180, radius);
        var minLat = point.lat();
        point = getPointBearingDist(centre, 0, radius);
        var maxLat = point.lat();
        point = getPointBearingDist(centre, 270, radius);
        var minLng = point.lng();
        point = getPointBearingDist(centre, 90, radius);
        var maxLng = point.lng();
        return new GLatLngBounds(new GLatLng(minLat, minLng), new GLatLng(maxLat, maxLng))
    }
    
    function getPointBearingDist(startPoint, bearing, distance){
    /*  
        Dev:    Steve Brockton
        Date:   2007-09-18
        Desc:   Calculate a point X miles away on a given bearing
    */
    //Convert everything to radians ('cos the world is round)
    var destLat = 0;
    var destLng = 0;
    var Lat = startPoint.lat() * (Math.PI/180);
    var Lng = startPoint.lng() * (Math.PI/180);
    var course = bearing * (Math.PI/180);
    var dist = (Math.PI/(180*60))* distance;
    
    destLat = Math.asin((Math.sin(Lat)*Math.cos(dist))
                + (Math.cos(Lat)*Math.sin(dist))*Math.cos(course));

    if (Math.cos(destLat)==0) {
        destLng = Lng;  //pole
    } else {
        destLng = ((Lng+Math.asin(Math.sin(course)*Math.sin(dist)/Math.cos(destLat))+Math.PI)
                      % (2*Math.PI)) - Math.PI;
    }
    //back to degrees ('cos maps are flat)
    destLat = destLat * (180/Math.PI);
    destLng = destLng * (180/Math.PI);

    return new GLatLng(destLat, destLng);
}

    
    function getSearchParams(postcode, keywords, searchRadius, geonameID) {    
    
         //create default parameter object
        var searchParams = new Object;
        searchParams.Location = postcode;
        searchParams.Keywords = keywords;
        latLng = -1;
        
        // Get the lat & Long
        
        if (postcode.length > 0)
        {
            var oLoc = new LocationsAPI();
            var oLocationSearchResult;      
            if(/\d/.test(postcode)) {
                oLocationSearchResult = oLoc.readByPostCode('GB', postcode);
            } 

            if (!((oLocationSearchResult) && (oLocationSearchResult.length > 0)))
            {
                var placeName = postcode;
                var countryCode = '';
                var myRE = new RegExp('^([\\w\\s]*?), (\\w\\w)$', ['g']);
                var myMatch = myRE.exec(postcode);
                if (myMatch!=null && myMatch.length > 0) {
                    placeName = myMatch[1];
                    countryCode = myMatch[2];
                }
                oLocationSearchResult = oLoc.readByQuery(placeName, countryCode);
            }
            
            if ((oLocationSearchResult) && (oLocationSearchResult.length > 0)) {
                latLng = new GLatLng(oLocationSearchResult[0].latitude, oLocationSearchResult[0].longitude);
                // If multiple results returned allow disambiguation
                if (oLocationSearchResult.length > 1) {
                    var locTemplate = new Template('<tr><td><img src="http://static.zubed.com/images/flags/#{countryCode}.gif" alt="flag #{countryCode}"/></td><td><a href="#" class="listjobtitle" onclick="centreAndSearch(#{latitude}, #{longitude}, \'#{fullName}\', #{geoNameID}, \'#{countryCode}\'); return false;" >#{fullName}</a></td><td>#{adminSecondary}</td><td>#{adminPrimary}</td></tr>');
                    var HTMLContent = ''
                    HTMLContent = '<table>'
                    HTMLContent += '<tr style="font-weight:bold;"><td colspan=4 class="listcompanytitle">Did you mean..?</td></tr>'

                    for (var i = 0; i < oLocationSearchResult.length ; i++) {
                        HTMLContent += locTemplate.evaluate(oLocationSearchResult[i]);
                        if (geonameID && geonameID > 0 && geonameID == oLocationSearchResult[i].geoNameID) {
                            latLng = new GLatLng(oLocationSearchResult[i].latitude, oLocationSearchResult[i].longitude);
                        }
                    }

                    HTMLContent += '</table></div>'
                    $('locationmessage').innerHTML = HTMLContent;            
                }      
            }
        }
        
        if (latLng != -1) {
            //Get the search bounds according to the location and radius
            searchBounds = getSearchBounds(latLng, searchRadius);
            //Centre the map on the selected position
            zoomLevel = map.getBoundsZoomLevel(searchBounds) + 1;
            CurrentLat = latLng.lat();
            CurrentLong = latLng.lng();
            reCentre();
                   
            searchParams.CentreLat = latLng.lat();
            searchParams.CentreLong = latLng.lng();
            searchParams.SWLat = searchBounds.getSouthWest().lat();
            searchParams.SWLng = searchBounds.getSouthWest().lng();
            searchParams.NELat = searchBounds.getNorthEast().lat();
            searchParams.NELng = searchBounds.getNorthEast().lng();
            
            searchParams.JobType = 0;
//            if($('salaryvolunteer').checked == true)
//                {searchParams.JobType = 3;}
//            else
//                {searchParams.JobType = 1;}
            
            searchParams.Sectors = [];
            searchParams.SearchTitleOnly = $('Searchtitleonly').checked
            searchParams.Agency = $('Agency').checked
            searchParams.CompanyID = filterCompanyID;
        
            searchParams.error = false;
        } else {
            searchParams.error = true;
        }
        
        return searchParams;
    
    }

function centreAndSearch(latitude, longitude, fullName, geonameID, countryCode) {
    CurrentLat = latitude;
    CurrentLong = longitude;
    reCentre();
    $('txtLocation').value = fullName + ", " + countryCode;
    advancedSearch(geonameID);
}



 function getIcon(ClientType, value) {
    var icon = new GIcon();
    
    if (ClientType=='cluster') {
        icon.image = "/images/clusters/cluster-" + value + ".gif";
        icon.shadow = "";
        icon.iconSize = new GSize(35, 18);
    } else {
        if (value == 3) {
            icon.image = "/images/markers/employerapprox.gif";
        } else {
            icon.image = "/images/markers/employerexact.gif";
        }
        icon.iconSize = new GSize(17, 23);
        icon.shadow = "/images/markers/mm_20_shadow.png";
    }
    icon.shadowSize = new GSize(32, 23);
    icon.iconAnchor = new GPoint(6, 20);
    icon.infoWindowAnchor = new GPoint(5, 1);
    return icon;
}


 function clearAllMarkers() {
    map.clearOverlays();
    mapMarkers = [];
    mapClusters = [];
}

function showBubble(marker) {
   if ((marker) && marker.requirementID) {
         
        var EmployerRequirement = new EmployerRequirementAPI();

        var oRequirements = EmployerRequirement.readByRequirementIDArray(marker.requirementID);
        requirements = [];

        RequirementTotal = oRequirements.length;

        styleExtra = '';
        if (oRequirements.length > 10 ) {
            styleExtra = 'height: 200px;';
        }

        var sReturnedHTML = '<div class="marker-information" style="' + styleExtra + 'overflow: auto; width: 250px;" >';

        sReturnedHTML += '<h3>Vacancies</h3>';
        sReturnedHTML += '<ul>';
        var Company = '';
        
        for (var i = 0; i < oRequirements.length ; i++) {

            //Check for change of company
            if (Company != oRequirements[i].EmployerName ) {
                //Company changed, output new company name
                sReturnedHTML += oRequirements[i].EmployerName;  
            }
            Company = oRequirements[i].EmployerName;
            
            //Add requirement to array and bubble
            requirements.push(oRequirements[i].RequirementID);
            sReturnedHTML += '<li><a href="#" class="marker-information" onclick="DisplayRequirement(' + i + '); return false;" >';
            sReturnedHTML += oRequirements[i].JobTitle + '</a></li>';    
        
        }
        sReturnedHTML += '</ul>';
        sReturnedHTML += '<br style="clear: both;"/></div>';

        // Show the generated marker information
        marker.openInfoWindowHtml( sReturnedHTML ); 
    } else if ((marker) && marker.clusterID >= 0) {
            //cluster marker
            map.removeOverlay(marker);
            //expand the cluster from the mapClusters array
            var thisCluster = mapClusters[marker.clusterID];
            for (var i = 0; i < thisCluster.markers.length ; i++) {
                map.addOverlay(thisCluster.markers[i]);  
            }
    } else { 
        if ((marker) && marker.volunteer == true) {
            DisplayVolunteerList();
        }
    }
}

/*
function doBoxOpen(sSectionName, pairedSection)
{
    // Dev:     James Pearson
    // Date:    2008-04-01
    // Desc:    Replaces doToggleSection. Opens a side box from its closed state.

    if ($(sSectionName)) {
    
        $(sSectionName).style.display = 'block';
        
         var oCollapse = $(sSectionName + '-collapse');
        oCollapse.onclick = null;
        
        var oContent = $(sSectionName + '-content');        
        oContent.style.display = 'block';
        
        oCollapse.onclick = function(){ 
                doBoxClose(sSectionName); 
        }
        
        if (pairedSection != ''){
            doBoxClose(pairedSection);
        }
    }
    
    return false;
}

function doBoxClose(sSectionName, pairedSection)
{
    // Dev:     James Pearson
    // Date:    2008-04-01
    // Desc:    Replaces doToggleSection. Closes a side box from its opened state.

    if ($(sSectionName)) {
        var oCollapse = $(sSectionName + '-collapse');
        oCollapse.onclick = null;
        
        var oContent = $(sSectionName + '-content');
         oContent.style.display = 'none';
        
        oCollapse.onclick = function(){ 
            doBoxOpen(sSectionName); 
        }
        
        if (pairedSection != ''){
            doBoxOpen(pairedSection);
        }
    }
    
    return false;
}
// end of progress bar functions
*/

// Progress bar functions

    function showProgress(sTitle, sMessage) {
        progress.style.display = "block";
        progressstatus.style.width = "1px";
        progressmessage.innerHTML = sMessage;
    }
    
    function updateProgress(percent, sMessage, clusterName) {
        progress.style.display = "block";

        if ((clusterName) && (!msgNames.contains(clusterName))) msgNames.push(clusterName);

        var iPercent = parseFloat(progressbar.style.width) /100 ;

        if ((percent>=0) || (percent<=1)) {
            
            progressstatus.style.width = ((100 * percent) * iPercent) + "px";
            progressmessage.innerHTML = sMessage;

        }
        if (percent>=1) {
            //check for outstanding messages before hiding
            if (clusterName) msgNames = msgNames.without(clusterName);
            if (msgNames.length==0) window.setTimeout('progress.style.display = "none";', 500);
        }
    }
    
    function updateProgressMessage(sTitle, sMessage, clusterName)
    {
        if (progress.style.display == "none") showProgress(sTitle, sMessage);
        else progressmessage.innerHTML = sMessage;
        if ((clusterName) && (!msgNames.contains(clusterName))) msgNames.push(clusterName);
    }


// end of progress bar functions
        
    function DisplayRequirement(reqIndex) {
     
        var RequirementDesc = '';
        var HTMLContent = '';
        CurrentRequirement = reqIndex;
        
        
        // Get the requirement Details        
        var EmployerRequirement = new EmployerRequirementAPI();
    
        oRequirement = EmployerRequirement.readByID(requirements[reqIndex]);
        
        RequirementDesc = highlightkeywords(oRequirement.JobDescription , ($F("txtKeywords")==control[1])?'':$F("txtKeywords") );
        
        if (oRequirement.ClosingDate.length == 0 || oRequirement.ClosingDate == '00:00:00') {
            ExpiryDate = 'Unknown';
        } else {
            var expDate = new Date;
            expDate.setISO8601(oRequirement.ClosingDate);
            ExpiryDate = expDate.toDDMMYYYY();
        }

        var reqSource = '';       
        switch(oRequirement.Source)
        { 
        case 'AustralianData':
            reqSource = 'AU';
            break;
        case 'USScraper':
            reqSource += 'US';
            break;    
        case 'SemanticScraper':
            reqSource += 'GB';
            break;
        default:
            RateType += '';
        }       
       
       RateType = '£' + oRequirement.Rate;
       if (oRequirement.Rate > 0 ) {
           switch(oRequirement.RateFrequency)
            { 
            case 'H':
                RateType += ' per hour';
                break;
            case 'D':
                RateType += ' per day';
                break;    
            case 'M':
                RateType += ' per month';
                break;
            default:
                RateType += ' per year';
            }
        } else {
            RateType  = 'Unknown ';
        }

        HTMLContent = '<h2  id="requirementDescription" >' + oRequirement.JobTitle + '</h2>';
        
        HTMLContent += '<h3>Company</h3>';
        HTMLContent += '<p>' + oRequirement.EmployerName + ' </p>';

        
        var reqSource = '';       
        switch(oRequirement.Source)
        { 
        case 'AustralianData':
            reqSource = '(AU)';
            break;
        case 'USScraper':
            reqSource += '(US)';
            break;    
        case 'SemanticScraper':
            reqSource += '(GB)';
            break;
        default:
            RateType += '';
        }       
        
        HTMLContent += '<h3>Reference</h3>';
        HTMLContent += '<p>' + oRequirement.ClientRef + ' ' + reqSource + '</p>';        

        
        HTMLContent += '<h3>Rate</h3>';
        HTMLContent += '<p>' + RateType + ' </p>';
        
        HTMLContent += '<h3>Contact</h3>';
        HTMLContent += '<p><b>' + oRequirement.ContactName + '</b></p>';
        var contactPhone;
        if (oRequirement.ContactPhone == '') {
            contactPhone = 'Not Entered';
        } else {
            contactPhone = oRequirement.ContactPhone;
        }        
        HTMLContent += '<p><img src="/images/phone.gif" alt="Telephone" class="ReqIcon" > ' + contactPhone + ' </p>';
        
        var contactEmail;
        if (oRequirement.ContactEmail == '') {
            contactEmail = 'Not Entered';
        } else {
            contactEmail = '<a href="mailto:' + oRequirement.ContactEmail + '?subject=Job:' + oRequirement.ClientRef + '">' + oRequirement.ContactEmail + '</a>';
        }        
        HTMLContent += '<p><img src="/images/email.gif" alt="email address"  class="ReqIcon"  > ' + contactEmail + ' </p>';
        
        var sourceURL;
        if (oRequirement.SourceURL == '') {
            sourceURL = '';
            HTMLContent += '<p><img src="/images/website.gif" alt="Website URL" class="ReqIcon" > Website: Not Entered </p>';
        } else {
            sourceURL = oRequirement.SourceURL;
            HTMLContent += '<p><img src="/images/website.gif" alt="Website URL"  class="ReqIcon" > <a href="'+ sourceURL +'" target="_blank" >View Website</a></p>';
        }        
        
        if (oRequirement.EmployerName != oRequirement.CompanyName) {
            HTMLContent += '<p>Source: ' + oRequirement.CompanyName + '</p>';
        }
        
        HTMLContent += '<h3>Closing Date</h3>';
        HTMLContent += '<p>' + ExpiryDate + ' </p>';
        
        HTMLContent += '<h3>Requirement Description</h3>';
        HTMLContent += '<div style="overflow: auto;">' + RequirementDesc + '</div>';
        
         //Reset the footer
        var footerHTML = '<div id="paging_back"  onclick="pagingBack();" ><a href="#">Back</a></div>'
            footerHTML += '<div id="paging_count"  style="float: left; width: 80px;"></div>'
            footerHTML += '<div id="paging_forward" onclick="pagingForward();" ><a href="#" >Next</a></div>'
           // footerHTML += '<br class="clearfix" />';
            footerHTML += '<div style="width: 100%;height: 20px;clear: both;" class="center" ><a href="#" onclick="javascript:DisplayRequirementList(' + Math.ceil((CurrentRequirement+1)/iPageSize) + ');"><img src="/images/ListView.gif" style="vertical-align: top;" alt="" /> Show as list<a/></div>'
            
          //  footerHTML += '<br><input type="button" value="Show as List" onclick="javascript:DisplayRequirementList(' + Math.ceil((CurrentRequirement+1)/iPageSize) + ');" />'
                      
                      
        //Populate and show modal box
        show_modal('Job Details',HTMLContent,footerHTML,requirements[reqIndex]);
        pagingUpdateCount();
        pagingUpdateButtons();
    }     
    
    function DisplayRequirementList(iPage)
    {
	    //This function will display a model box with a list of the jobs in the requested page
    	 //Finally set iPageSize
    	page_resize();
        iPageSize = Math.round((viewportheight * 0.8) / 35)
    
	    //Determine the no of pages to ensure chosen page is OK
	    var iLength = requirements.length 
	    var iTotalPages = Math.ceil(iLength/iPageSize)

        PageListTotal = iTotalPages;
        
	    var startpoint = ((iPage - 1) * iPageSize);
	    var endpoint = startpoint + Math.min(iPageSize, (iLength-startpoint))

	    var listrequirements = [];

	    for(var i=startpoint ; i<endpoint; i++)
        {
	        listrequirements.push(requirements[i])
        }

        var oListEmployerRequirement = new EmployerRequirementAPI();
        var oListRequirements = oListEmployerRequirement.readByRequirementIDArray(listrequirements);

        //Declare the content HTML
        var HTMLListContent = '';
    	
        //Define the 1st company in the list.
        var theCurrentCompany = '';

        //Start the HTML
        HTMLListContent = '<div style="overflow:auto;"><table>'
        HTMLListContent += '<tr style="font-weight:bold;"><th width="100px"></th><th width="350px"></th><th></th></tr>'

        var origindex = 0;
        
        for (var i = 0; i < oListRequirements.length ; i++) {

                //Check for change of company
                if (theCurrentCompany  != oListRequirements[i].EmployerName ) {
                    //Company changed, output new company name
                    HTMLListContent += '<tr><td colspan=3 class="listcompanytitle" >' + oListRequirements[i].EmployerName + '</td></tr>';  
                }
                theCurrentCompany  = oListRequirements[i].EmployerName;
    	    
                // Loop thru original array to find original index position.
                for (var x = startpoint;x<endpoint;x++)
                {
                    if (oListRequirements[i].RequirementID == requirements[x])
                    {
                        origindex = x;
                    }
                }	                
                
            HTMLListContent += '<tr><td>&nbsp;</td><td><a href="#"  class="listjobtitle" onclick="DisplayRequirement(' + origindex + '); return false;" >' +  oListRequirements[i].JobTitle + '</a></td><td>' + oListRequirements[i].Rate + '</td></tr>';

        }

        HTMLListContent += '</table></div>'

        //Reset the footer
        var footerHTML = '<div id="paging_back"  onclick="pagingListBack('+ (iPage-1) + ',' + iTotalPages + ');" ><a href="#">Back</a></div>'
            footerHTML+= '<div id="paging_count"  style="float: left; width: 80px;">Page ' + iPage + ' of ' + PageListTotal + '</div>'
            footerHTML+= '<div id="paging_forward" onclick="pagingListForward('+ (iPage+1) + ',' + iTotalPages + ');" ><a href="#" >Next</a></div>'


        //Show the selected page
        show_modal('Selected Jobs',HTMLListContent, footerHTML);
    }
    
    function pagingListBack(iNewPage,iTotal) {
        
        if (iNewPage > 0)
        {
          DisplayRequirementList(iNewPage);
          pagingUpdateButtons(iNewPage-1,iTotal)
        }
    }
    
    
    function pagingListForward(iNewPage,iTotal) 
    {
    
        if ((iNewPage ) <= iTotal)
        {
          DisplayRequirementList(iNewPage);
          pagingUpdateButtons(iNewPage-1,iTotal)
        }
        
    }
    
    function pagingBack() {
        
        if (CurrentRequirement > 0 ) {
            CurrentRequirement--;
            DisplayRequirement(CurrentRequirement);
            pagingUpdateCount();
            pagingUpdateButtons(CurrentRequirement,RequirementTotal)
            new Effect.Highlight('requirementDescription', { startcolor: '#FFFF99', endcolor: '#ffffff' });
        }
    }
    
    function pagingForward() {
    
        if ((CurrentRequirement + 1) < RequirementTotal ) {
            CurrentRequirement++;
            DisplayRequirement(CurrentRequirement);
            pagingUpdateCount();
            pagingUpdateButtons(CurrentRequirement,RequirementTotal)
            new Effect.Highlight('requirementDescription', { startcolor: '#FFFF99', endcolor: '#ffffff' });
        }
    }

    function pagingUpdateCount() {
        $('paging_count').innerHTML = (CurrentRequirement+1) + ' of ' + RequirementTotal + '';
    }
  
    function pagingUpdateButtons(iCurrent,iTotal) {
        
        if (iCurrent < 1 ) {
            $('paging_back').style.opacity = .5;
	        $('paging_back').style.filter = 'alpha(opacity=' + 50 + ')';
        } else {
            $('paging_back').style.opacity = 1;
	        $('paging_back').style.filter = 'alpha(opacity=' + 100 + ')';
        }
                
        if ((iCurrent + 1) >= iTotal ) {
            $('paging_forward').style.opacity = .5;
	        $('paging_forward').style.filter = 'alpha(opacity=' + 50 + ')';
        } else {
            $('paging_forward').style.opacity = 1;
	        $('paging_forward').style.filter = 'alpha(opacity=' + 100 + ')';         
        }   
    
    }

// Functions for modal box
    function show_modal(modal_title,HTMLContent, footerHTML, requirementid) 
    {                      
    
        $('modalContainer').style.height = '80%';
        $('modalContainer').style.width = '80%';
        $('modalContainer').style.left = '10%'; 
        
        if ($('modaloverlay').style.display == 'none' ) {
            Effect.Appear('modaloverlay', { duration: 0.3, from: 0, to: 0.5 });
        }        
           
        //Decide if to show the admin reject button - if so set the global for the onclick function      
        if (requirementid !=undefined)
        {       
            if (canrejectjobs == "true")
            {
                $('modaladminbutton').style.visibility = "visible"; 
                iQARequirementID = requirementid
            }
        }
        else
        {
        $('modaladminbutton').style.visibility = "hidden";
        iQARequirementID = 0;
        }          
        //End
        
        $('mtitle').innerHTML = modal_title;
        
        $('modalcontent').innerHTML = HTMLContent;
        
        $('pagination').innerHTML = footerHTML  
        $('modalContainer').style.visibility = "visible";
        if (requirementid !=undefined)
        {$('modalcontentfooter').innerHTML = '<hr><label style="font-size:9px;">Whilst Zubed is continuously working to optimise its search engine, it is not possible to guarantee the accuracy of job searches.</label>'}
        else
        {$('modalcontentfooter').innerHTML = '';}       
        //reset modalcontent to required height (note 64 is no of pixels of title and footer) 
        $('Contentwrapper').style.height = Math.round((((viewportheight * 0.8) - 90)/(viewportheight * 0.8))*100) + '%';
        
        
        return false;
    }
        
    function close_modal() {
        Effect.Fade('modaloverlay', { duration: 0.3, from: .5, to: 0 });
        $('modalcontent').innerHTML = "cleared";
        $('modaladminbutton').style.visibility = "hidden";
        $('modalContainer').style.visibility = "hidden";
        return false;
    }      
        
    function returntoQA()
    {
      var EmployerRequirementReject = new EmployerRequirementAPI();
      var answer = confirm("Are you sure you want to send this job back to QA?")
         
         if (answer){
	           if (EmployerRequirementReject.adminRejectByID(iQARequirementID) == true)
	              {alert("Job returned to QA.");}
	           else
	              {alert("An error occurred.  Job not updated.");} 
	     }                 
    }    
        
    function validationerror(control,msgbox,msg) {
        $(msgbox).innerHTML = msg;
        $(control).addClassName('inputerror');
    }
    
    function validationReset(control, msgbox) {
        // Reset the item styles on the search box.
        $(control).removeClassName('inputerror');
        $(msgbox).innerHTML = '';
        resetSearchButton(); // reactivate the search button
    }
    
    function clearAdvancedSearch() {
            // Reset all search parameters
            $('txtLocation').value = '';
            $('drpRadius').value = '3';
            $('txtKeywords').value = '';
            //$('drpWorkType').value = '0';
            validationReset('txtLocation','ErrorDiv_txtLocation');
    }
   
    function fnTrapKD(event, advanced){
        if ((event.keyCode && event.keyCode == 13) ||
            (event.which && event.which == 13)) {  
                event.returnValue=false;
                event.cancel = true;
                advancedSearch();
                return false;
        }
    }
        
    function closewarning() {
        Effect.Fade('msgpopup', { duration: 0.3, from: 1, to: 0 });
        return false;
    }
    
    function closesearchwarning() {
        Effect.Fade('searchwarning', { duration: 0.3, from: 1, to: 0 });
        return false;
    }

    function highlightkeywords(sText, sKeywords) {
        if (sText.length == 0 || sKeywords.length == 0) {
            return sText;
        }
        
        //replace "and" "or" and doubled spaces
        sKeywords = sKeywords.replace(/ and /gi, ' ');
        sKeywords = sKeywords.replace(/ or /gi, ' ');
        sKeywords = sKeywords.replace(/  /gi, ' ');
        sKeywords = sKeywords.replace(/  /gi, ' ');
        sKeywords = sKeywords.replace('+', '\\+');

        //construct a regular expression to highlight each word
        //phrases in quotes need to be treated as a single word
        var inQuote = false;
        var newRegex = '(\\W';
        for(var i = 0; i < sKeywords.length; i++){
            var thisChar = sKeywords.charAt(i);
            if (thisChar=='"') {
                inQuote = !inQuote;
            } else {
                if (thisChar==' ' && !inQuote) {
                    newRegex += '\\W|';
                } else {
                    newRegex += thisChar;
                }
            }
        }
        newRegex+='\\W)';

        return sText.replace(new RegExp(newRegex, "gi"), '<span class="keywordHighlight">$1</span>');
    }
    
   function showNoResults() {

        if ($('Searchtitleonly').checked) $('warnsearch').addClassName('fontred');
            setTimeout("Effect.Appear('msgpopup', { duration: 0.2, from: 0, to: 1 })",10);
            setTimeout('closewarning()', 10000);
            setTimeout('$(\'warnsearch\').removeClassName(\'fontred\');', 10000);
   
   }
   
    function TextHint(controlName, textid, onfocus) {
    
        if (onfocus) {
            if ($F(controlName) == control[textid] ) {
                $(controlName).removeClassName('fontgray');;
                $(controlName).value = '';
            }
        } else {
            if ($F(controlName) =='' ) {
                $(controlName).addClassName('fontgray');
                $(controlName).value = control[textid];
            } 
        }
    }
    
    function dragzoomcheck() {
    
    
        if ($('dzhelperhide').checked) {
            
            //set a cookie to hide the helper bubble
            var myDate=new Date();
            myDate.setDate(myDate.getDate()+365);
            setCookie('dzhelper', 'true', myDate, '/');
            setTimeout("Effect.Fade('dzhelpholder', { duration: 0.2, from: 1, to: 0 })",2);
        }
    
 
    
    }
 
    
    function fnTrapKD(event, advanced){

        var bRunSearch = false;
        
        if (document.all){
            if (event.keyCode == 13){
                bRunSearch = true;
            }
        } 
        else if (document.getElementById)
        {
            if (event.which == 13){
                bRunSearch = true;
            }
       }
        else if(document.layers) 
        {
            if(event.which == 13){
                bRunSearch = true;
            }
        }
        
        if (bRunSearch == true){
            event.returnValue=false;
            event.cancel = true;
            if (advanced == true) {
                setTimeout('advancedSearch()', 20);
            } else {
                setTimeout('volSearch()', 20);
            }
            return false;
        }
    }    
    
        
// Volunteering Code
    
    function clearVolSearch() {
        // Reset all search parameters
        $('txtVolLocation').value = '';
        $('drpVolRadius').value = '3';
        validationReset('txtVolLocation','ErrorDiv_txtVolLocation');
    }
    
    function volSearch() {
        // Clear the map
        clearAllMarkers();
        volOpportunities = [];
        showProgress("Searching...", "Retrieving data");
        //Show the legend
        doBoxHide("legend");
        doBoxOpen("vollegend");

        var oSearch = new YNDISearchAPI();
        var oSearchResult = oSearch.getResults({Location: $F('txtVolLocation'), Radius: $F('drpVolRadius') });
        if (oSearchResult.errorCode != null) {
            if (oSearchResult.errorCode == 0) {
                if (oSearchResult.oppsReturned > 0) {
                    showVolOpportunities(oSearchResult.opportunities);
                    centreVolLocation();
                } else {
                    if (oSearchResult.locations.length > 0) {
                        showVolLocations(oSearchResult.locations);
                    }
                }
            } else {
                showVolSearchWarning("<p>" + oSearchResult.errorDescription + "</p><br />");
            }
        }
        
        updateProgress(1, "Done", "");        
    }

    function showVolOpportunities(opportunities) {
        //console.log(opportunities.length, "opportunities");
        volOpportunities = opportunities;
    }
    
    function showVolLocations(locations) {
        //console.log(locations.length, "locations");
        showVolSearchWarning("<p>More than one matching location found.</p><p>please be more specific or try a postcode search.</p>");
    }
    
    function showVolSearchWarning(content) {
        $("volsearchwarningtext").innerHTML = content;
        setTimeout("Effect.Appear('volsearchwarning', { duration: 0.2, from: 0, to: 1 })",10);
        setTimeout("Effect.Fade('volsearchwarning', { duration: 0.2, from: 1, to: 0 })",10000);
    }
    
    function closevolsearchwarning() {
        Effect.Fade('volsearchwarning', { duration: 0.3, from: 1, to: 0 });
        return false;
    }
    
    
    function centreVolLocation() {
        var latLng = -1;
        var location = $F('txtVolLocation');
        if (location.length > 0) {
            var oLoc = new LocationsAPI();
            var oLocationSearchResult;      
            if(/\d/.test(location)) {
                oLocationSearchResult = oLoc.readByPostCode('GB', location);
            } else {
                oLocationSearchResult = oLoc.readByQuery(location, 'GB');
            }
        }
        
        if ((oLocationSearchResult) && (oLocationSearchResult.length > 0)) {
            latLng = new GLatLng(oLocationSearchResult[0].latitude, oLocationSearchResult[0].longitude);
        }

        if (latLng != -1) {
            //Get the search bounds according to the location and radius
            var searchBounds = getSearchBounds(latLng, $F('drpVolRadius'));
            //Centre the map on the selected position
            zoomLevel = map.getBoundsZoomLevel(searchBounds);
            CurrentLat = latLng.lat();
            CurrentLong = latLng.lng();
            reCentre();
            var radius = $F('drpVolRadius') * 0.621371192;
            drawCircle(map, CurrentLat, CurrentLong, "#000000", 3, "#ffffff", radius);
            var marker = new GMarker(new GLatLng(CurrentLat, CurrentLong), getVolIcon());
            marker.volunteer = true;  
            map.addOverlay(marker);
        }  
    }
    
    function getVolIcon() {
        var icon = new GIcon();
        icon.image = "/images/markers/volunteer.gif";
        icon.shadow = "/images/markers/mm_20_shadow.png";
        icon.shadowSize = new GSize(32, 23);
        icon.iconAnchor = new GPoint(6, 38);
        icon.infoWindowAnchor = new GPoint(5, 1);
        return icon;
    }
    
    function DisplayVolunteerList()
    {
        var HTMLListContent = '';
        var oppTemplate = new Template('<tr><td><a href="#" class="listjobtitle" onclick="DisplayVolunteerOpportunity(#{oppID}); return false;" >#{title}</a></td><td>#{orgName}</td><td>#{distance}</td></tr>');
        var doitLogo = '<div style="position:absolute;bottom:40px;right:50px;"><span style="position:relative;bottom:12px;color:black;font-weight:bold;">Volunteering opportunities provided by </span><a href="http://www.do-it.org.uk" target="_blank"><img src="/images/do-it-powered-by-rgb_s.jpg" alt="Powered by do-it"/></a></div>';

        HTMLListContent = '<div style="overflow:auto;"><table>'
        HTMLListContent += '<tr style="font-weight:bold;"><td colspan=3 class="listcompanytitle">Volunteering Opportunities</td></tr>'
        HTMLListContent += '<tr style="font-weight:bold;"><th width="200px">Title</th><th width="200px">Organisation</th><th>Distance</th></tr>'

        for (var i = 0; i < volOpportunities.length ; i++) {
            HTMLListContent += oppTemplate.evaluate(volOpportunities[i]);
        }

        HTMLListContent += '</table></div>'
        
        HTMLListContent += doitLogo;

        show_modal('Volunteering Opportunities',HTMLListContent, "");
    }

    function DisplayVolunteerOpportunity(oppID) {
        var oppContent = '';
        var oppTemplate = new Template('<div><h2>#{title}</h2><h3>Organisation</h3><p>#{orgName}</p><h3>Distance from search</h3><p>#{distance} km</p><div><br /><p><a href="http://www.do-it.org.uk/oppdetails.do?id=#{oppID}" target="_blank" style="text-decoration: none;color:black;"><img src="/images/do-it-powered-by-rgb_s.jpg" alt="Powered by do-it"/>Click here for full details of this opportunity</a></p></div><h3>Opportunity Details</h3><p>#{description}</p></div>');
        var opportunity = null;
        var oppIdx = null;

        for (var i = 0; i < volOpportunities.length ; i++) {
            if (volOpportunities[i].oppID == oppID) {
                opportunity = volOpportunities[i];
                oppIdx = i;
                break;
            }
        }
        
        if (opportunity != null) {
            oppContent = oppTemplate.evaluate(opportunity);

            var footerHTML = ''
            if (oppIdx!=null && oppIdx > 0) {
                footerHTML += '<div id="paging_back"  style="float:left;width:55px;" onclick="DisplayVolunteerOpportunity(' + volOpportunities[oppIdx - 1].oppID + ');" ><a href="#">Back</a></div>'
            } else {
                footerHTML += '<div style="float:left;width:60px;">&nbsp;</div>'
            }
            footerHTML += '<div id="paging_List"  style="float:left;" onclick="DisplayVolunteerList();" ><a href="#">Return to list</a></div>'
            if (oppIdx!=null && oppIdx < volOpportunities.length - 1) {
                footerHTML += '<div id="paging_forward" style="float:left;width:60px;" onclick="DisplayVolunteerOpportunity(' + volOpportunities[oppIdx + 1].oppID + ');" ><a href="#" >Next</a></div>'
            } else {
                footerHTML += '<div style="float:left;width:60px;">&nbsp;</div>'
            }      
            show_modal('Volunteering Opportunities',oppContent, footerHTML);
        }
    
}