var pohID = "7";
var homeCount = 116;

window.onload = function() {
    init();
    btmMenuTap('homeContainer');
    document.getElementById('loadingScreen').style.display = "none";
    document.getElementById('MainContainer').style.display = "block";
};

//************************************************
// IE Browser detect from MSDN.com
//************************************************

function getInternetExplorerVersion()
// Returns the version of Internet Explorer or a -1
// (indicating the use of another browser).
{
    var rv = -1; // Return value assumes failure
    if (navigator.appName == 'Microsoft Internet Explorer') {
        var ua = navigator.userAgent;
        var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
        if (re.exec(ua) != null)
            rv = parseFloat(RegExp.$1);
    }
    return rv;
}
//************************************************
// End IE browser detect
//************************************************

// ************************************************************************
//  Refresh Scrolls
// ************************************************************************
function refreshScrolls() {
    ieversion = getInternetExplorerVersion();
    if (ieversion < 0) {
        myScroll1.refresh();
        myScroll2.refresh();
        myScroll3.refresh();
        myScroll4.refresh();
        myScroll5.refresh();
        myScroll6.refresh();
        myScroll7.refresh();
    }
};
// ************************************************************************
//  END - Refresh Scrolls
// ************************************************************************

//************************************************
// Bookmark Functions
//************************************************
function retrieveBookmarks() {
    showLoading();
    var i = 0;
    var firstFlag = 0; //Need to clear out the innerHTML if this is the first bookmark result hit

    document.getElementById('bookmarkResults').innerHTML = "";

    for (i = 0; i < homeCount; i++) {
        var myName = i + "Bookmark";
        if (localStorage.getItem(myName)) {
            var homeID = localStorage.getItem(myName);
            showBookmark(homeID, firstFlag);
            //localStorage.removeItem(myName); //Uncomment to clear all bookmarks when you hit the bookmarks button
            firstFlag = 1;
        }
    }

    if (firstFlag == 0) {
        document.getElementById('bookmarkResults').innerHTML = "<div class=\"pageMenuItem\">You Have No Bookmarks</div>";
    }

    hideLoading();
};
function showBookmark(homeID, firstFlag) {
    showLoading();
    var myResults = document.getElementById('bookmarkResults').innerHTML;

    if (firstFlag == 0) {
        myResults = "";
    }

    PageMethods.GetBookmark(homeID, pohID, MethodResultsGetBookmark);
};
function MethodResultsGetBookmark(ResultString) {
    var myResults = document.getElementById('bookmarkResults').innerHTML;

    myResults += ResultString;

    document.getElementById('bookmarkResults').innerHTML = myResults;
    hideLoading();
};
//************************************************
// END - Bookmark Functions
//************************************************

// ************************************************************************
//  Web Methods
// ************************************************************************
function getAll(field, fieldValue) {
    field = field.replace('@', '\'');
    showLoading();
    document.getElementById('resultsResults').innerHTML = "";

    if (field == "IsFeatured") {
        PageMethods.GetAll(pohID, field, fieldValue, MethodResultsGetAllFeatured);
    }
    else {
        PageMethods.GetAll(pohID, field, fieldValue, MethodResultsGetAll);
    }
};
function MethodResultsGetAll(ResultString) {
    var myTitle;
    document.getElementById('resultsResults').innerHTML = ResultString;

    //resultsTitle is a hidden div
    myTitle = document.getElementById('resultsTitle').innerHTML;
    document.getElementById('resultsTitleName').innerHTML = myTitle;

    checkFeatHood(myTitle);
    
    hideLoading();

    setTimeout(function() {
        refreshScrolls();
    }, 3000);
};
function MethodResultsGetAllFeatured(ResultString) {
    document.getElementById('homeList').innerHTML = ResultString;
    hideLoading();

    setTimeout(function() {
        refreshScrolls();
    }, 3000);
};
function checkFeatHood(MyTitle) {
    var featMenu = document.getElementById('featMenu');
    var featResults = document.getElementById('resultsResults');
    var featAbout = document.getElementById('resultsAbout');
    
    switch (MyTitle) {
        case "Canyon Lakes":
            featMenu.style.display = "block";
            featResults.style.display = "none";
            featAbout.style.display = "block";
            loadCL();
            break;
        case "Parke Place":
            featMenu.style.display = "block";
            featResults.style.display = "none";
            featAbout.style.display = "block";
            loadPP();
            break;
        case "Pleasant Grove":
            featMenu.style.display = "block";
            featResults.style.display = "none";
            featAbout.style.display = "block";
            loadPG();
            break;
        case "Williamson Farms":
            featMenu.style.display = "block";
            featResults.style.display = "none";
            featAbout.style.display = "block";
            loadWF();
            break;
        default:
            featMenu.style.display = "none";
            featResults.style.display = "block";
            featAbout.style.display = "none";
            break;
    }
    
    setTimeout(function() {
        refreshScrolls();
    }, 3000);
};
function getBuilders() {
    showLoading();
    PageMethods.GetBuilders(pohID, MethodResultsGetBuilders);
};
function MethodResultsGetBuilders(ResultString) {
    document.getElementById('builderList').innerHTML = ResultString;
    hideLoading();

    setTimeout(function() {
        refreshScrolls();
    }, 3000);
};
function getHoods() {
    showLoading();
    PageMethods.GetHoods(pohID, MethodResultsGetHoods);
};
function MethodResultsGetHoods(ResultString) {
    document.getElementById('listResults').innerHTML = ResultString;
    hideLoading();

    setTimeout(function() {
        refreshScrolls();
    }, 3000);
};
function GetHoodsByArea(area) {
    showLoading();
    
    var areaString;
    switch (area) {
        case "N.W. Okla. City":
            areaString = "NW";
            break;
        case "Edmond":
            areaString = "Edmond";
            break;
        case "S.W. Okla. City":
            areaString = "SW";
            break;
        case "East Area":
            areaString = "East";
            break;
    }
    getBanner(areaString);
    
    PageMethods.GetHoodsByArea(pohID, area, MethodResultsGetHoodsByArea);
};
function MethodResultsGetHoodsByArea(ResultString) {
    document.getElementById('areaHoodList').innerHTML = ResultString;
    hideLoading();

    setTimeout(function() {
        refreshScrolls();
    }, 3000);
};
function getCities() {
    showLoading();
    PageMethods.GetCities(pohID, MethodResultsGetCities);
};
function MethodResultsGetCities(ResultString) {
    document.getElementById('listResults').innerHTML = ResultString;
    hideLoading();

    setTimeout(function() {
        refreshScrolls();
    }, 3000);
};
function getPropertyByID(ID) {
    showLoading();
    var screenRes = document.getElementById('Content').clientWidth;
    
    document.getElementById('profileResults').innerHTML = "";
    PageMethods.GetPropertyByID(ID, pohID, screenRes, MethodResultsGetPropertyByID);
};
function MethodResultsGetPropertyByID(ResultString) {
    document.getElementById('profileResults').innerHTML = ResultString;

    var isElite = document.getElementById('homeElite').innerHTML;

    if (isElite == "1") {
        document.getElementById('profileTitleBar').style.display = "none";
        document.getElementById('profileMenuBar').style.display = "block";
    }
    else {
        document.getElementById('profileTitleBar').style.display = "block";
        document.getElementById('profileMenuBar').style.display = "none";
        var myTitle = document.getElementById('profBuilder').innerHTML;
        document.getElementById('profTitle').innerHTML = myTitle;
    }

    //Set Menu & Popup links
    popupLinks();

    //Set comments if any have been made
    var myPropID = document.getElementById('propID').innerHTML;
    var myCommentVar = myPropID + "Comment";
    if (localStorage.getItem(myCommentVar)) {
        document.getElementById('profNotes').innerHTML = localStorage.getItem(myCommentVar);
    }

    //Keep the loading going until the image has fully loaded.
    var mySRC = document.getElementById('homePhoto').src;
    var myImage = new Image();
    
    myImage.src = mySRC;

    myImage.onload = function() {
        hideLoading();
    }

    setTimeout(function() {
        refreshScrolls();
    }, 3000);
};
// ************************************************************************
//  END - Web Methods
// ************************************************************************

// ************************************************************************
//  Ad Functions
// ************************************************************************
function getBanner(which) {
    PageMethods.GetPOHAdMySql(which, '7', getBannerResults);
}
function getBannerResults(which) {
    var myWidth = document.getElementById('Content').clientWidth;
    //alert(which);
    var aStr = which.split('~');

    if (myWidth < 768) {
        document.getElementById('ImageTopBanner').src = 'http://www.showhomesguide.com/banners/area/' + aStr[0] + '.jpg';
    }
    else {
        document.getElementById('ImageTopBanner').src = 'http://www.showhomesguide.com/banners/area/Web-' + aStr[0] + '.jpg';
    }
    //alert(document.getElementById('ImageTopBanner').src);
    document.getElementById('topBannerLink').href = 'http://' + aStr[2];
}
// ************************************************************************
//  END - Ad Functions
// ************************************************************************

// ************************************************************************
//  Spinning Wheel Stuff
// ************************************************************************
function swSearch(criteria) {
    //Need function to gather options for search criteria
    var myWidth = document.getElementById("MainContainer").clientWidth;
    
    if (myWidth <= 1024) {
        switch (criteria) {
            case "Builder":
                showLoading();
                PageMethods.getSWBuilders(pohID, MethodResultsBuilders);
                break;
            case "Price":
                var prices = { p0: 'All', p1: '$100,000 and under', p2: '$100,001 - $200,000', p3: '$200,001 - $300,000', p4: '$300,001 - $400,000', p5: '$400,001 - $500,000', p6: '$500,001 and above' };
                SpinningWheel.addSlot(prices, 'left', 'All');
                SpinningWheel.setCancelAction(cancel);
                SpinningWheel.setDoneAction(doneP);
                SpinningWheel.open();
                break;
            case "Hood":
                showLoading();
                PageMethods.getSWHoods(pohID, MethodResultsHoods);
                break;
            case "City":
                showLoading();
                PageMethods.getSWCity(pohID, MethodResultsCities);
                break;
            case "Beds":
                var beds = { be0: 'All', be1: '2', be2: '3', be3: '4', be4: '5', be5: '6' }
                SpinningWheel.addSlot(beds, 'left', 'All');
                SpinningWheel.setCancelAction(cancel);
                SpinningWheel.setDoneAction(doneBE);
                SpinningWheel.open();
            case "Baths":
                var baths = { ba0: 'All', ba1: '2', ba2: '3', ba3: '4', ba4: '5', ba5: '6' }
                SpinningWheel.addSlot(baths, 'left', 'All');
                SpinningWheel.setCancelAction(cancel);
                SpinningWheel.setDoneAction(doneBA);
                SpinningWheel.open();
                break;
            case "Amenities":
                var amenities = { a0: 'All', a1: 'Granite', a2: 'Stone', a3: 'Pool', a4: 'Hot Tub', a5: 'Marble', a6: 'Tile' };
                SpinningWheel.addSlot(amenities, 'left', 'All');
                SpinningWheel.setCancelAction(cancel);
                SpinningWheel.setDoneAction(doneA);
                SpinningWheel.open();
                break;
        }
    }
};

function MethodResultsBuilders(ResultString) {
    //The string is coming in as:  Builder~Builder~Builder.....
    var myResults = ResultString.split("~");
    var builders = {};

    for (var i = 0; i < myResults.length; i++) {
        builders[i] = myResults[i];
    }

    //The first is the key and the second in quotes is the value
    SpinningWheel.addSlot(builders, 'left', 'All');

    SpinningWheel.setCancelAction(cancel);
    SpinningWheel.setDoneAction(doneB);

    hideLoading();

    SpinningWheel.open();
};
function MethodResultsHoods(ResultString) {
    //The string is coming in as:  Hood~Hood~Hood.....
    var myResults = ResultString.split("~");
    var hoods = {};

    for (var i = 0; i < myResults.length; i++) {
        hoods[i] = myResults[i];
    }
    
    SpinningWheel.addSlot(hoods, 'left', 'All');
    SpinningWheel.setCancelAction(cancel);
    SpinningWheel.setDoneAction(doneH);

    hideLoading();

    SpinningWheel.open();
};
function MethodResultsCities(ResultString) {
    //The string is coming in as:  City~City~City.....
    var myResults = ResultString.split("~");
    var city = {};

    for (var i = 0; i < myResults.length; i++) {
        city[i] = myResults[i];
    }

    SpinningWheel.addSlot(city, 'left', 'All');
    SpinningWheel.setCancelAction(cancel);
    SpinningWheel.setDoneAction(doneC);

    hideLoading();

    SpinningWheel.open();
};
function doneP() {
    var results = SpinningWheel.getSelectedValues();
    searchCriteria(results.values, 'p');
};
function doneB() {
    var results = SpinningWheel.getSelectedValues();
    searchCriteria(results.values, 'b');
};
function doneH() {
    var results = SpinningWheel.getSelectedValues();
    searchCriteria(results.values, 'h');
};
function doneC() {
    var results = SpinningWheel.getSelectedValues();
    searchCriteria(results.values, 'c');
};
function doneA() {
    var results = SpinningWheel.getSelectedValues();
    searchCriteria(results.values, 'a');
};
function doneBE() {
    var results = SpinningWheel.getSelectedValues();
    searchCriteria(results.values, 'be');
};
function doneBA() {
    var results = SpinningWheel.getSelectedValues();
    searchCriteria(results.values, 'ba');
};
function cancel() {
    //alert('cancelled!');
};
// ************************************************************************
//  End Spinning Wheel Stuff
// ************************************************************************

// ************************************************************************
//  Search Functions
// ************************************************************************
function setSearch() {
    //Invoked when going to the Search Page
    var myWidth = document.getElementById('MainContainer').clientWidth;

    if (myWidth <= 1024) {
        //leave things the way they are
    }
    else {
        //viewing from large monitor - Hide Labels and Arrows and display the drop downs
        document.getElementById('pcSearch').style.display = "block";
        document.getElementById('searchWrapper').style.display = "none";

        //Populate DropDownLists
        showLoading();
        PageMethods.getDropDownBuilders(pohID, MethodResultsDropDownListBuilders);
        PageMethods.getDropDownHood(pohID, MethodResultsDropDownListHood);
        PageMethods.getDropDownCity(pohID, MethodResultsDropDownListCity);
    }
};

function MethodResultsDropDownListBuilders(ResultString) {
    document.getElementById('dropDownBuilder').innerHTML = ResultString;
    hideLoading();
};
function MethodResultsDropDownListHood(ResultString) {
    document.getElementById('dropDownHood').innerHTML = ResultString;
    hideLoading();
};
function MethodResultsDropDownListCity(ResultString) {
    document.getElementById('dropDownCity').innerHTML = ResultString;
    hideLoading();
};

function searchCriteria(value, key) {
    //Invoked by Spinning Wheel
    var myCategory = key.toString();

    switch (myCategory) {
        case "p":
            document.getElementById('labelPrice').innerHTML = "  " + value;
            break;
        case "b":
            document.getElementById('labelBuilder').innerHTML = "  " + value;
            break;
        case "h":
            document.getElementById('labelHood').innerHTML = "  " + value;
            break;
        case "c":
            document.getElementById('labelCity').innerHTML = "  " + value;
            break;
        case "a":
            document.getElementById('labelAmenities').innerHTML = "  " + value;
            break;
        case "be":
            document.getElementById('labelBeds').innerHTML = "  " + value;
            break;
        case "ba":
            document.getElementById('labelBaths').innerHTML = "  " + value;
            break;
    }

};
function doSearch() {
    //Invoked when hitting the Search button on the Search Page
    var myBuilder;
    var myPrice;
    var myHood;
    var myCity;
    var myBeds;
    var myBaths;
    var myAmenities;

    var myWidth = document.getElementById("MainContainer").clientWidth;

    if (myWidth <= 1024) {
        myBuilder = document.getElementById('labelBuilder').innerHTML.replace(/^\s+|\s+$/g, '').replace("&amp;", "&");
        myPrice = document.getElementById('labelPrice').innerHTML.replace(/^\s+|\s+$/g, '').replace("&amp;", "&");
        myHood = document.getElementById('labelHood').innerHTML.replace(/^\s+|\s+$/g, '').replace("&amp;", "&");
        myCity = document.getElementById('labelCity').innerHTML.replace(/^\s+|\s+$/g, '').replace("&amp;", "&");
        myBeds = document.getElementById('labelBeds').innerHTML.replace(/^\s+|\s+$/g, '').replace("&amp;", "&");
        myBaths = document.getElementById('labelBaths').innerHTML.replace(/^\s+|\s+$/g, '').replace("&amp;", "&");
        myAmenities = document.getElementById('labelAmenities').innerHTML.replace(/^\s+|\s+$/g, '').replace("&amp;", "&");
    }
    else {
        //we are not on a device, so we need to get the drop down values.
        //alert("here");
        var p = document.getElementById('DropDownListPrice');
        var a = document.getElementById('DropDownListAmenities');
        var be = document.getElementById('DropDownListBeds');
        var ba = document.getElementById('DropDownListBaths');
        //If it is dynamically generated, then have to reference the first child of the containing div
        var b = document.getElementById('dropDownBuilder').firstChild;
        var h = document.getElementById('dropDownHood').firstChild;
        var c = document.getElementById('dropDownCity').firstChild;

        myBuilder = b.options[b.selectedIndex].value;
        myPrice = p.options[p.selectedIndex].value;
        myHood = h.options[h.selectedIndex].value;
        myCity = "All";
        myBeds = be.options[be.selectedIndex].value;
        myBaths = ba.options[ba.selectedIndex].value;
        myAmenities = a.options[a.selectedIndex].value;
    }

    showLoading();
    PageMethods.GetPOHAllPreviewSearchBB(pohID, myBuilder, myPrice, myHood, myCity, myAmenities, myBeds, myBaths, MethodResultsGetPOHAllPreviewSearch);
};
function MethodResultsGetPOHAllPreviewSearch(ResultString) {
    
    if (ResultString.length != 0) {
        showLoading();
        document.getElementById('resultsResults').innerHTML = ResultString;
        nav('resultsContainer', 'searchContainer', '')
        hideLoading();

        setTimeout(function() {
            refreshScrolls();
        }, 3000);
    }
    else {
        hideLoading();
        alert("There are no homes matching your search criteria.");
        document.getElementById('resultsContainer').style.display = "none";
        document.getElementById('searchContainer').style.display = "block";
    }
};
// ************************************************************************
//  END - Search Functions
// ************************************************************************

// ************************************************************************
//  Popup Functions
// ************************************************************************
function showPopup() {
    document.getElementById('popupContainer').style.display = "block";
};
function hidePopup() {
    document.getElementById('popupContainer').style.display = "none";
};
function popupLinks() {
    var myPhone = document.getElementById('propPhone').innerHTML;
    var myEmail = document.getElementById('propEmail').innerHTML;
    var myWeb = document.getElementById('propWeb').innerHTML;
    var myPropID = document.getElementById('propID').innerHTML;
    var myFullID = document.getElementById('fullID').innerHTML;

    //Get Property Info
    if (myPhone != "") {
        myPhone = "tel:" + myPhone;
    }
    else {
        myPhone = "#";
    }
    if (myEmail != "") {
        myEmail = "mailto:" + myEmail;
    }
    else {
        myEmail = "#";
    }
    if (myWeb != "") {
        myWeb = "http://" + myWeb;
    }
    else {
        myWeb = "#";
    }

    document.getElementById('linkBookMark').href = "javascript:BookMark(" + myPropID + ", " + pohID + ")";
    document.getElementById('linkBookMark2').href = "javascript:BookMark(" + myPropID + ", " + pohID + ")";
    document.getElementById('linkCall').href = myPhone;
    document.getElementById('linkEmail').href = myEmail;
    document.getElementById('linkWeb').href = myWeb;
    document.getElementById('linkGallery').href = "javascript:getGallery(" + myFullID + ", " + pohID + ")";
    document.getElementById('linkFaceBook').href = "javascript:getFaceBook(" + myPropID + ", " + pohID + ")";
    document.getElementById('linkFaceBook2').href = "javascript:getFaceBook(" + myPropID + ", " + pohID + ")";
    document.getElementById('linkTwitter').href = "javascript:getTwitter(" + myPropID + ", " + pohID + ")";
    document.getElementById('linkFriend').href = "javascript:getFriend(" + myPropID + ", " + pohID + ")";
    document.getElementById('linkFriend2').href = "javascript:getFriend(" + myPropID + ", " + pohID + ")";
    document.getElementById('linkComment').href = "javascript:getComment(" + myPropID + ", " + pohID + ")";
    document.getElementById('linkRate').href = "javascript:getRate(" + myPropID + ", " + pohID + ")";
    document.getElementById('linkRate2').href = "javascript:getRate(" + myPropID + ", " + pohID + ")";
};

function BookMark(id, pohID) {
    var myVar = id + "Bookmark";
    if (localStorage.getItem(myVar)) {
        alert("You have already bookmarked this home.");
    }
    else {
        localStorage.setItem(myVar, id);
        alert("You have bookmarked this home.");
    }

    var guid = document.getElementById("HiddenGuid").value;
    var myFullPropID = document.getElementById('fullID').innerHTML;
    PageMethods.AddActivity("7", "WSbookmarked", myFullPropID, MethodResultsSave);
};

function getGallery(id, pohID) {
    hidePopup();

    showGallery(id, pohID);
    var myFullPropID = document.getElementById('fullID').innerHTML;
    PageMethods.AddActivity("7", "WSgallery", myFullPropID, MethodResultsSave);
};
function MethodResultsSave(resultstring) {
}
function getFaceBook(id, pohID) {
    var myFullPropID = document.getElementById('fullID').innerHTML;
    PageMethods.AddActivity("7", "WSfacebooked", myFullPropID, MethodResultsSave);
    window.open("http://www.facebook.com/sharer.php?u=http://mobile.paradeofhomesokc.com/ShowPropF.aspx?id=" + id)
};

function getTwitter(id, pohID) {
    var myFullPropID = document.getElementById('fullID').innerHTML;

    PageMethods.AddActivity("7", "WStwitter", myFullPropID, MethodResultsSave);
    window.open("http://www.twitter.com/home?status=http://mobile.paradeofhomesokc.com/ShowPropF.aspx?id=" + id);
};

function getFriend(id, pohID) {
    var daReferrer = document.referrer;
    var errorMsg = "error";
    var subject = "2011 OKC Parade of Homes";
    var body_message = "Check this home out from the 2011 OKC Parade of Homes! http://mobile.paradeofhomesok.com/default.aspx?id=" + id + "&v=" + pohID;
    var mailto_link = 'mailto:' + "" + '?subject=' + subject + '&body=' + body_message;
    win = window.open(mailto_link, 'emailWindow');
    if (win && win.open && !win.closed) win.close();
};

//Comments
function showComment() {
    hidePopup();
    
    document.getElementById('commentContainer').style.display = "block";
};

function hideComment() {
    document.getElementById('commentContainer').style.display = "none";
};

function getComment(id, pohID) {
    var myComment = document.getElementById('profNotes').innerHTML;

    if (myComment == "") {
        document.getElementById('TextBoxComment').innerHTML = "Enter Your Comment Here";
    }
    else {
        document.getElementById('TextBoxComment').innerHTML = myComment;
    }
   
    showComment();
};

function saveComment() {
    var myComment = document.getElementById('TextBoxComment').value;
    document.getElementById('profNotes').innerHTML = myComment;

    //Save to Local Variable
    var myPropID = document.getElementById('propID').innerHTML;
    var myVar = myPropID + "Comment";
    localStorage.setItem(myVar, myComment);

    var myFullPropID = document.getElementById('fullID').innerHTML;
    PageMethods.AddActivity("7", myComment, myFullPropID, MethodResultsSave);
    alert("Your Comment Has Been Saved");
    hideComment();
};
//End Comments

//Ratings
function showRate() {
    hidePopup();
    document.getElementById('rateContainer').style.display = "block";
};

function hideRate() {
    document.getElementById('rateContainer').style.display = "none";
};

function getRate(id, pohID) {
    var myPropID = document.getElementById('propID').innerHTML;
    var myRateVar = myPropID + "Rating";
    var myRating;

    if (localStorage.getItem(myRateVar)) {
        myRating = localStorage.getItem(myRateVar);
    }
    else {
        myRating = 0;
    }

    //Reset Stars
    for (var i = 1; i <= 5; i++) {
        var myStar = "star" + i;
        document.getElementById(myStar).src = "images/star-Empty.png";
    }
    //Set stars based on rating
    for (var i = 1; i <= myRating; i++) {
        var myStar = "star" + i;
        document.getElementById(myStar).src = "images/star-Fill.png";
    }    
    
    showRate();
};

function rateStars(star) {
    for (var i = 1; i <= star; i++) {
        var myStar = "star" + i;
        document.getElementById(myStar).src = "images/star-Fill.png";
    }

    document.getElementById('ratingResult').innerHTML = star;

    //Save to Local Variable
    var myPropID = document.getElementById('propID').innerHTML;
    var myVar = myPropID + "Rating";


    localStorage.setItem(myVar, star);
    myPropID = document.getElementById('fullID').innerHTML;
    var myFullPropID = document.getElementById('fullID').innerHTML;
    PageMethods.AddActivity("7", "WSRated", myFullPropID, MethodResultsSave);
    PageMethods.SaveRating(myPropID, star, "7", MethodResultsSave);
};

function saveRate() {
    var myRating = document.getElementById('ratingResult').innerHTML;
    var myAlert;

    if (myRating != "") {
        myAlert = "You rated this house " + myRating + " stars.";
       
    }
    else {
        myAlert = "You did not rate this house.";
    }
    
    alert(myAlert);
    document.getElementById('rateContainer').style.display = "none";
};
//END Ratings

//Individual Map
function closeHomeMap() {
    document.getElementById('mapPopupContainer').style.display = "none";
};

function showHomeMap() {
    showLoading();
    var lat = document.getElementById('propLat').innerHTML;
    var lng = document.getElementById('propLong').innerHTML;
    var mylat = parseInt(lat);
    var mylng = parseInt(lng);

    var homeLatlng = new google.maps.LatLng(mylat, mylng);
    var myOptions = {
        zoom: 8,
        center: homeLatlng,
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };

    var homeMap = new google.maps.Map(document.getElementById("map-canvas2"), myOptions);
    
    document.getElementById('mapPopupContainer').style.display = "block";
    hideLoading();
};
// ************************************************************************
//  END - Popup Functions
// ************************************************************************

// ************************************************************************
//  Gallery
// ************************************************************************
function showGallery(onlineID, pohID) {
    showLoading();
    PageMethods.GetAdditionalImagesMySql(onlineID, pohID, MethodResultsGetAdditionalImagesMySql);
};
function MethodResultsGetAdditionalImagesMySql(ResultString) {
    if (ResultString == "") {
        alert("There are no gallery images for this home.");
    }
    else {
        document.getElementById('galleryPhotos').innerHTML = ResultString;
        document.getElementById('galleryContainer').style.display = "block";
        document.getElementById('photo1').style.display = "block";
    }
    hideLoading();
};
function closeGallery() {
    document.getElementById('galleryContainer').style.display = "none";
};
function galPrev() {
    var myDivList = document.getElementById('galleryPhotos');

    for (i = 1; i <= myDivList.childNodes.length; i++) {
        var myPhoto = "photo" + i;
        var myPrevPhoto = "photo" + (i - 1);

        if (document.getElementById(myPhoto).style.display == "block") {
            if (document.getElementById(myPrevPhoto)) {
                document.getElementById(myPhoto).style.display = "none";
                document.getElementById(myPrevPhoto).style.display = "block";
            }
            break;
        }
    }
};
function galNext() {
    var myDivList = document.getElementById('galleryPhotos');
    
    for (i = 1; i <= myDivList.childNodes.length; i++) {
        var myPhoto = "photo" + i;
        var myNextPhoto = "photo" + (i + 1);

        if (document.getElementById(myPhoto).style.display == "block") {
            if (document.getElementById(myNextPhoto)) {
                document.getElementById(myPhoto).style.display = "none";
                document.getElementById(myNextPhoto).style.display = "block";
            }
            break;
        }
    }
};

// ************************************************************************
//  END Gallery
// ************************************************************************

// ************************************************************************
//  Navigation
// ************************************************************************
function showLoading() {
    document.getElementById('loading').style.display = "block";
};
function hideLoading() {
    document.getElementById('loading').style.display = "none";
};
function nav(newPage, currentPage) {
    document.getElementById(newPage).style.display = "block";
    document.getElementById(currentPage).style.display = "none";

    if (newPage == "resultsContainer") {
        var myString;

        switch (currentPage) {
            case "homeContainer":
                myString = "<div class=\"BackBtn\" onclick=\"back('homeContainer', 'resultsContainer')\">Back</div>";
                break;
            case "listContainer":
                myString = "<div class=\"BackBtn\" onclick=\"back('listContainer', 'resultsContainer')\">Back</div>";
                break;
            case "searchContainer":
                myString = "<div class=\"BackBtn\" onclick=\"back('searchContainer', 'resultsContainer')\">Back</div>";
                document.getElementById('resultsTitleName').innerHTML = "Search Results";
                break;
        }
        document.getElementById('resultsBack').innerHTML = myString;
    }
    if (newPage == "profileContainer") {
        var myString;

        switch (currentPage) {
            case "homeContainer":
                myString = "<div class=\"BackBtn\" onclick=\"back('homeContainer', 'profileContainer')\">Back</div>";
                myString2 = "<img onclick=\"back('homeContainer', 'profileContainer')\" src=\"images/BtnClose.png\" />";
                break;
            case "mapContainer":
                myString = "<div class=\"BackBtn\" onclick=\"back('mapContainer', 'profileContainer')\">Back</div>";
                myString2 = "<img onclick=\"back('mapContainer', 'profileContainer')\" src=\"images/BtnClose.png\" />";
                break;
            case "resultsContainer":
                myString = "<div class=\"BackBtn\" onclick=\"back('resultsContainer', 'profileContainer')\">Back</div>";
                myString2 = "<img onclick=\"back('resultsContainer', 'profileContainer')\" src=\"images/BtnClose.png\" />";
                break;
            case "bookmarkContainer":
                myString = "<div class=\"BackBtn\" onclick=\"back('bookmarkContainer', 'profileContainer')\">Back</div>";
                myString2 = "<img onclick=\"back('bookmarkContainer', 'profileContainer')\" src=\"images/BtnClose.png\" />";
                break;
        }
        document.getElementById('profBack').innerHTML = myString;
        document.getElementById('profClose').innerHTML = myString2;
    }

    refreshScrolls();
};
function back(newPage, currentPage) {
    //for the ads
    var myWhich;
    switch (newPage) {
        case "resultsContainer":
            myWhich = document.getElementById('resultsTitleName').innerHTML;
            break;
        case "homeContainer":
            myWhich = "homeContainer";
            break;
        case "listContainer":
            myWhich = "listTitle";
            break;
        case "searchContainer":
            myWhich = "Search";
            break;
        case "bookmarkContainer":
            myWhich = "";
            break;
    }
    getBanner(myWhich);
    document.getElementById(newPage).style.display = "block";
    document.getElementById(currentPage).style.display = "none";
    refreshScrolls();
};
function btmNav(newPage) {
    btmMenuTap(newPage);

    //Determine which child of "Content" is block, which would be the current page
    var myDivList = document.getElementById('Content');
    for (i = 0; i < myDivList.childNodes.length; i++) {
        if (myDivList.childNodes[i].nodeName == "DIV" && myDivList.childNodes[i].style.display == "block") {
            myDivList.childNodes[i].style.display = "none";
            break;
        }
    }

    if (newPage == "mapContainer") {
        getAllMap();
    };

    document.getElementById(newPage).style.display = "block";

    refreshScrolls();
};

function btmMenuTap(newPage) {
    var myIcon = "";
    var myButton = "";
    var myText = "";
    var myBack = "";
    var myBanner = "";

    resetBtmMenu();
    if (newPage == "homeContainer") {
        myIcon = "images/Icon-Home-Over.png";
        myButton = "ImageButton1";
        myText = "Text1";
        myBack = "BtmMenuItem1";
        myBanner = "homeContainer";
    }
    if (newPage == "mapContainer") {
        myIcon = "images/Icon-MapPin-Over.png";
        myButton = "ImageButton2";
        myText = "Text2";
        myBack = "BtmMenuItem2";
        myBanner = "Map";
    }
    if (newPage == "bookmarkContainer") {
        myIcon = "images/Icon-Bookmark-Over.png";
        myButton = "ImageButton3";
        myText = "Text3";
        myBack = "BtmMenuItem3";
        myBanner = "";
    }
    if (newPage == "searchContainer") {
        myIcon = "images/Icon-Search-Over.png";
        myButton = "ImageButton4";
        myText = "Text4";
        myBack = "BtmMenuItem4";
        myBanner = "Search";
    }
    if (newPage == "moreContainer") {
        myIcon = "images/Icon-More-Over.png";
        myButton = "ImageButton5";
        myText = "Text5";
        myBack = "BtmMenuItem5";
        myBanner = "Random";
    }
    getBanner(myBanner);
    document.getElementById(myButton).src = myIcon;
    document.getElementById(myText).style.color = "White";
    document.getElementById(myBack).style.background = "url(images/BtmMenuBack-Over.png) no-repeat fixed center center";
    document.getElementById(myBack).style.backgroundSize = "cover";
};

function resetBtmMenu() {
    //Reset all Bottom Menu Button Images
    document.getElementById('ImageButton1').src = "images/Icon-Home.png";
    document.getElementById('ImageButton2').src = "images/Icon-MapPin.png";
    document.getElementById('ImageButton3').src = "images/Icon-Bookmark.png";
    document.getElementById('ImageButton4').src = "images/Icon-Search.png";
    document.getElementById('ImageButton5').src = "images/Icon-More.png";

    //Reset all Bottom Menu Text Colors
    document.getElementById('Text1').style.color = "#c6c6c5";
    document.getElementById('Text2').style.color = "#c6c6c5";
    document.getElementById('Text3').style.color = "#c6c6c5";
    document.getElementById('Text4').style.color = "#c6c6c5";
    document.getElementById('Text5').style.color = "#c6c6c5";

    //Reset all the Background overlays
    document.getElementById('BtmMenuItem1').style.backgroundImage = "url(images/transparent.png)";
    document.getElementById('BtmMenuItem2').style.backgroundImage = "url(images/transparent.png)";
    document.getElementById('BtmMenuItem3').style.backgroundImage = "url(images/transparent.png)";
    document.getElementById('BtmMenuItem4').style.backgroundImage = "url(images/transparent.png)";
    document.getElementById('BtmMenuItem5').style.backgroundImage = "url(images/transparent.png)";
};
function toggleMore(myDiv) {
    hideToggleDivs();
    document.getElementById(myDiv).style.display = "block";
    refreshScrolls();
    myScroll4.scrollTo(0, 0, 200);
};
function hideToggleDivs() {
    document.getElementById('eventInfo').style.display = "none";
    document.getElementById('help').style.display = "none";
    document.getElementById('appInfo').style.display = "none";
};
function toggleHome(myDiv) {
    hideHomeToggleDivs();
    document.getElementById(myDiv).style.display = "block";
    refreshScrolls();
    myScroll1.scrollTo(0, 0, 200);
};
function hideHomeToggleDivs() {
    document.getElementById('builderList').style.display = "none";
    document.getElementById('hoodList').style.display = "none";
    document.getElementById('homeList').style.display = "none";
    document.getElementById('areaHoodList').style.display = "none";
};
function toggleResults(myDiv) {
    switch (myDiv) {
        case ('resultsResults'):
            document.getElementById('resultsResults').style.display = "block";
            document.getElementById('resultsAbout').style.display = "none";
            break;
        case ('resultsAbout'):
            document.getElementById('resultsResults').style.display = "none";
            document.getElementById('resultsAbout').style.display = "block";
            break;
    }
    var myHood = document.getElementById('resultsTitleName').innerHTML;
    getBanner(myHood);
};
// ************************************************************************
//  END - Navigation
// ************************************************************************

// ************************************************************************
//  Map Functions
// ************************************************************************
function FixID(strId) {
    var newStr = strId;
    if (strId.length == 1) {
        newStr = "0" + newStr;
    }
    return newStr;
};
function getAllMap() {
    showLoading();
    //GetAllLocations
    nav("mapContainer", "homeContainer");
    PageMethods.GetAllLocations(pohID, ReturnAllLocations);
};
function ReturnAllLocations(ResultsString) {
    ShowMap(ResultsString);
};
function ShowMap(ResultsString) {
    //to get GPS http://itouchmap.com/latlong.html
    var map,
				map_options,
				mapdiv = document.getElementById('map_canvas'),
				myMarker = false,
				useragent = navigator.userAgent;

    // Google Maps needs the inline height/width
    //mapdiv.style.width = mapdiv.style.height = '100%';
    //mapdiv.style.height = mapdiv.style.height = '100%';

    // define the map options
    map_options = {
        zoom: 11,
        mapTypeControl: true,
        mapTypeControlOptions: { style: google.maps.MapTypeControlStyle.HORIZONTAL_BAR },
        zoomControlOptions: { style: google.maps.ZoomControlStyle.SMALL },
        center: new google.maps.LatLng(ResultsString.detailList[0].Latitude, ResultsString.detailList[0].Longitude), // downtown Austin
        mapTypeId: google.maps.MapTypeId.ROADMAP
    };
    // then create the map
    map = new google.maps.Map(mapdiv, map_options);
    var imageRedPin = new google.maps.MarkerImage('images/Pin-Red.png',
            new google.maps.Size(32, 38), // This marker is 32 pixels wide by 38 pixels tall.
            new google.maps.Point(0, 0), // The origin for this image is 0,0.
            new google.maps.Point(2, 4)); // The anchor for this image is the base of the flagpole at 0,32.

    var i;
    var hString;
    for (i = 0; i < ResultsString.detailList.length; i++) {
        hString += ResultsString.detailList[i].id + "<br>" + "\r";
        var myLatlng = new google.maps.LatLng(ResultsString.detailList[i].Latitude, ResultsString.detailList[i].Longitude); //using a specific location
        //alert(ResultsString.detailList[i].Company + " a");
        var marker = new google.maps.Marker({
            position: myLatlng,
            title: ResultsString.detailList[i].Company + " - " + ResultsString.detailList[i].Address,
            icon: imageRedPin
        });
        //alert(ResultsString.detailList[i].Company + " b");
        marker.setMap(map);

        // ************************************************************************** //
        // Defining our custom InfoBox
        // ************************************************************************** //
        var boxText = document.createElement("div");
        //boxText.style.cssText = "border: 1px solid black; margin-top: 8px; background: yellow; padding: 5px;";
        boxText.innerHTML = "Home by " + ResultsString.detailList[i].Company + "<br>Address:" + ResultsString.detailList[i].Address;

        var boxOptions = {
            content: boxText
                , disableAutoPan: false
                , maxWidth: 0
                , pixelOffset: new google.maps.Size(-111, -67) //first set to -half the width,
                , zIndex: null
                , boxClass: "mapInfoBox"
                , closeBoxMargin: "2px 2px 2px 2px"
                , closeBoxURL: "images/MapGoArrow.png"
                , infoBoxClearance: new google.maps.Size(1, 1)
                , isHidden: false
                , pane: "floatPane"
                , enableEventPropagation: false
        };


        google.maps.event.addListener(marker, 'click', (function(marker, i) {
            return function() {

                var boxText = document.createElement("div");
                //boxText.style.cssText = "border: 1px solid black; margin-top: 8px; background: yellow; padding: 5px;";
                //boxText.innerHTML = "Address: " + ResultsString[2][0];
                var imgSrc = "<img class=\"thumb\" src=\"HomeImages/" + (ResultsString.detailList[i].ImageName.replace("..", ".")) + "\">";
                boxText.innerHTML = imgSrc + "<br>#" + ResultsString.detailList[i].id + "<br>Home by " + ResultsString.detailList[i].Company + "<br>Addition: " + ResultsString.detailList[i].Addition + "<br>Address: " + ResultsString.detailList[i].Address;

                var boxOptions = {
                    content: boxText
                , alignBottom: true
                , disableAutoPan: false
                , maxWidth: 0
                , pixelOffset: new google.maps.Size(-138, -5) //first set to -half the width,
                , zIndex: null
                , boxClass: "mapInfoBox"
                , closeBoxMargin: "2px 2px 2px 2px"
                , closeBoxURL: "images/MapGoArrow.png"
                , infoBoxClearance: new google.maps.Size(1, 1)
                , isHidden: false
                , HouseId: ResultsString.detailList[i].id
                , pane: "floatPane"
                , enableEventPropagation: false
                };
                var ib2 = new InfoBox(boxOptions);
                ib2.open(map, this);
                //infowindow.setContent("test " + i);
                //infowindow.open(map, marker);
            }
        })(marker, i));
    }
    //alert(hString);

    function displayLocation(position) {
        var myLatLng = new google.maps.LatLng(position.coords.latitude, position.coords.longitude);

        // build entire marker first time thru
        if (!myMarker) {
            // define the 'you are here' marker image
            var image = new google.maps.MarkerImage('blue_dot_circle.png',
						new google.maps.Size(38, 38), // size
						new google.maps.Point(0, 0), // origin
						new google.maps.Point(19, 19) // anchor
					);

            // then create the new marker
            myMarker = new google.maps.Marker({
                position: myLatLng,
                map: map,
                icon: image,
                flat: true,
                title: 'I might be here'
            });

            // just change marker position on subsequent passes
        } else {
            myMarker.setPosition(myLatLng);
        }

        // center map view on every pass
        map.setCenter(myLatLng);
    };


    function handleError(error) {
        switch (error.code) {
            case error.TIMEOUT:
                //alert('Sorry. Timed out.');
                break;
            case error.PERMISSION_DENIED:
                alert('Sorry. Permission to find your location has been denied.');
                break;
            case error.POSITION_UNAVAILABLE:
                alert('Sorry. Position unavailable.');
                break;
            default:
                alert('Sorry. Mystery error code: ' + error.code);
                break;
        }
    };

    var options = {
        timeout: 1000,
        maximumAge: 1000,
        enableHighAccuracy: true
    };


    // allow iPhone or Android to track movement
    //alert(useragent);

    if (useragent.indexOf('iPhone') != -1 || useragent.indexOf('Android') != -1) {
        navigator.geolocation.watchPosition(displayLocation, handleError, options);

        // or let other geolocation capable browsers to get their static position
    } else if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(displayLocation, handleError, options);
    }
    hideLoading();
};
// ************************************************************************
//  END - Map Functions
// ************************************************************************

// ************************************************************************
// ************************************************************************
// ************************************************************************
//  Third Party included .js files
// ************************************************************************
// ************************************************************************
// ************************************************************************

// ************************************************************************
//  iScroll
// ************************************************************************
/*!
* iScroll Lite base on iScroll v4.1.6 ~ Copyright (c) 2011 Matteo Spinelli, http://cubiq.org
* Released under MIT license, http://cubiq.org/license
*/

(function() {
    var m = Math,
	vendor = (/webkit/i).test(navigator.appVersion) ? 'webkit' :
		(/firefox/i).test(navigator.userAgent) ? 'Moz' :
		'opera' in window ? 'O' : '',

    // Browser capabilities
	has3d = 'WebKitCSSMatrix' in window && 'm11' in new WebKitCSSMatrix(),
	hasTouch = 'ontouchstart' in window,
	hasTransform = vendor + 'Transform' in document.documentElement.style,
	isIDevice = (/iphone|ipad/gi).test(navigator.appVersion),
	isPlaybook = (/playbook/gi).test(navigator.appVersion),
	hasTransitionEnd = isIDevice || isPlaybook,
	nextFrame = (function() {
	    return window.requestAnimationFrame
			|| window.webkitRequestAnimationFrame
			|| window.mozRequestAnimationFrame
			|| window.oRequestAnimationFrame
			|| window.msRequestAnimationFrame
			|| function(callback) { return setTimeout(callback, 17); }
	})(),
	cancelFrame = (function() {
	    return window.cancelRequestAnimationFrame
			|| window.webkitCancelRequestAnimationFrame
			|| window.mozCancelRequestAnimationFrame
			|| window.oCancelRequestAnimationFrame
			|| window.msCancelRequestAnimationFrame
			|| clearTimeout
	})(),

    // Events
	RESIZE_EV = 'onorientationchange' in window ? 'orientationchange' : 'resize',
	START_EV = hasTouch ? 'touchstart' : 'mousedown',
	MOVE_EV = hasTouch ? 'touchmove' : 'mousemove',
	END_EV = hasTouch ? 'touchend' : 'mouseup',
	CANCEL_EV = hasTouch ? 'touchcancel' : 'mouseup',

    // Helpers
	trnOpen = 'translate' + (has3d ? '3d(' : '('),
	trnClose = has3d ? ',0)' : ')',

    // Constructor
	iScroll = function(el, options) {
	    var that = this,
			doc = document,
			i;

	    that.wrapper = typeof el == 'object' ? el : doc.getElementById(el);
	    that.wrapper.style.overflow = 'hidden';
	    that.scroller = that.wrapper.children[0];

	    // Default options
	    that.options = {
	        hScroll: true,
	        vScroll: true,
	        bounce: true,
	        bounceLock: false,
	        momentum: true,
	        lockDirection: true,
	        useTransform: true,
	        useTransition: false,

	        // Events
	        onRefresh: null,
	        onBeforeScrollStart: function(e) { e.preventDefault(); },
	        onScrollStart: null,
	        onBeforeScrollMove: null,
	        onScrollMove: null,
	        onBeforeScrollEnd: null,
	        onScrollEnd: null,
	        onTouchEnd: null,
	        onDestroy: null
	    };

	    // User defined options
	    for (i in options) that.options[i] = options[i];

	    // Normalize options
	    that.options.useTransform = hasTransform ? that.options.useTransform : false;
	    that.options.hScrollbar = that.options.hScroll && that.options.hScrollbar;
	    that.options.vScrollbar = that.options.vScroll && that.options.vScrollbar;
	    that.options.useTransition = hasTransitionEnd && that.options.useTransition;

	    // Set some default styles
	    that.scroller.style[vendor + 'TransitionProperty'] = that.options.useTransform ? '-' + vendor.toLowerCase() + '-transform' : 'top left';
	    that.scroller.style[vendor + 'TransitionDuration'] = '0';
	    that.scroller.style[vendor + 'TransformOrigin'] = '0 0';
	    if (that.options.useTransition) that.scroller.style[vendor + 'TransitionTimingFunction'] = 'cubic-bezier(0.33,0.66,0.66,1)';

	    if (that.options.useTransform) that.scroller.style[vendor + 'Transform'] = trnOpen + '0,0' + trnClose;
	    else that.scroller.style.cssText += ';position:absolute;top:0;left:0';

	    that.refresh();

	    that._bind(RESIZE_EV, window);
	    that._bind(START_EV);
	    if (!hasTouch) that._bind('mouseout', that.wrapper);
	};

    // Prototype
    iScroll.prototype = {
        enabled: true,
        x: 0,
        y: 0,
        steps: [],
        scale: 1,

        handleEvent: function(e) {
            var that = this;
            switch (e.type) {
                case START_EV:
                    if (!hasTouch && e.button !== 0) return;
                    that._start(e);
                    break;
                case MOVE_EV: that._move(e); break;
                case END_EV:
                case CANCEL_EV: that._end(e); break;
                case RESIZE_EV: that._resize(); break;
                case 'mouseout': that._mouseout(e); break;
                case 'webkitTransitionEnd': that._transitionEnd(e); break;
            }
        },

        _resize: function() {
            this.refresh();
        },

        _pos: function(x, y) {
            x = this.hScroll ? x : 0;
            y = this.vScroll ? y : 0;

            if (this.options.useTransform) {
                this.scroller.style[vendor + 'Transform'] = trnOpen + x + 'px,' + y + 'px' + trnClose + ' scale(' + this.scale + ')';
            } else {
                x = m.round(x);
                y = m.round(y);
                this.scroller.style.left = x + 'px';
                this.scroller.style.top = y + 'px';
            }

            this.x = x;
            this.y = y;
        },

        _start: function(e) {
            var that = this,
			point = hasTouch ? e.touches[0] : e,
			matrix, x, y;

            if (!that.enabled) return;

            if (that.options.onBeforeScrollStart) that.options.onBeforeScrollStart.call(that, e);

            if (that.options.useTransition) that._transitionTime(0);

            that.moved = false;
            that.animating = false;
            that.zoomed = false;
            that.distX = 0;
            that.distY = 0;
            that.absDistX = 0;
            that.absDistY = 0;
            that.dirX = 0;
            that.dirY = 0;

            if (that.options.momentum) {
                if (that.options.useTransform) {
                    // Very lame general purpose alternative to CSSMatrix
                    matrix = getComputedStyle(that.scroller, null)[vendor + 'Transform'].replace(/[^0-9-.,]/g, '').split(',');
                    x = matrix[4] * 1;
                    y = matrix[5] * 1;
                } else {
                    x = getComputedStyle(that.scroller, null).left.replace(/[^0-9-]/g, '') * 1;
                    y = getComputedStyle(that.scroller, null).top.replace(/[^0-9-]/g, '') * 1;
                }

                if (x != that.x || y != that.y) {
                    if (that.options.useTransition) that._unbind('webkitTransitionEnd');
                    else cancelFrame(that.aniTime);
                    that.steps = [];
                    that._pos(x, y);
                }
            }

            that.absStartX = that.x; // Needed by snap threshold
            that.absStartY = that.y;

            that.startX = that.x;
            that.startY = that.y;
            that.pointX = point.pageX;
            that.pointY = point.pageY;

            that.startTime = e.timeStamp || Date.now();

            if (that.options.onScrollStart) that.options.onScrollStart.call(that, e);

            that._bind(MOVE_EV);
            that._bind(END_EV);
            that._bind(CANCEL_EV);
        },

        _move: function(e) {
            var that = this,
			point = hasTouch ? e.touches[0] : e,
			deltaX = point.pageX - that.pointX,
			deltaY = point.pageY - that.pointY,
			newX = that.x + deltaX,
			newY = that.y + deltaY,
			timestamp = e.timeStamp || Date.now();

            if (that.options.onBeforeScrollMove) that.options.onBeforeScrollMove.call(that, e);

            that.pointX = point.pageX;
            that.pointY = point.pageY;

            // Slow down if outside of the boundaries
            if (newX > 0 || newX < that.maxScrollX) {
                newX = that.options.bounce ? that.x + (deltaX / 2) : newX >= 0 || that.maxScrollX >= 0 ? 0 : that.maxScrollX;
            }
            if (newY > 0 || newY < that.maxScrollY) {
                newY = that.options.bounce ? that.y + (deltaY / 2) : newY >= 0 || that.maxScrollY >= 0 ? 0 : that.maxScrollY;
            }

            if (that.absDistX < 6 && that.absDistY < 6) {
                that.distX += deltaX;
                that.distY += deltaY;
                that.absDistX = m.abs(that.distX);
                that.absDistY = m.abs(that.distY);

                return;
            }

            // Lock direction
            if (that.options.lockDirection) {
                if (that.absDistX > that.absDistY + 5) {
                    newY = that.y;
                    deltaY = 0;
                } else if (that.absDistY > that.absDistX + 5) {
                    newX = that.x;
                    deltaX = 0;
                }
            }

            that.moved = true;
            that._pos(newX, newY);
            that.dirX = deltaX > 0 ? -1 : deltaX < 0 ? 1 : 0;
            that.dirY = deltaY > 0 ? -1 : deltaY < 0 ? 1 : 0;

            if (timestamp - that.startTime > 300) {
                that.startTime = timestamp;
                that.startX = that.x;
                that.startY = that.y;
            }

            if (that.options.onScrollMove) that.options.onScrollMove.call(that, e);
        },

        _end: function(e) {
            if (hasTouch && e.touches.length != 0) return;

            var that = this,
			point = hasTouch ? e.changedTouches[0] : e,
			target, ev,
			momentumX = { dist: 0, time: 0 },
			momentumY = { dist: 0, time: 0 },
			duration = (e.timeStamp || Date.now()) - that.startTime,
			newPosX = that.x,
			newPosY = that.y,
			newDuration;

            that._unbind(MOVE_EV);
            that._unbind(END_EV);
            that._unbind(CANCEL_EV);

            if (that.options.onBeforeScrollEnd) that.options.onBeforeScrollEnd.call(that, e);

            if (!that.moved) {
                if (hasTouch) {
                    // Find the last touched element
                    target = point.target;
                    while (target.nodeType != 1) target = target.parentNode;

                    if (target.tagName != 'SELECT' && target.tagName != 'INPUT' && target.tagName != 'TEXTAREA') {
                        ev = document.createEvent('MouseEvents');
                        ev.initMouseEvent('click', true, true, e.view, 1,
						point.screenX, point.screenY, point.clientX, point.clientY,
						e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
						0, null);
                        ev._fake = true;
                        target.dispatchEvent(ev);
                    }
                }

                that._resetPos(200);

                if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
                return;
            }

            if (duration < 300 && that.options.momentum) {
                momentumX = newPosX ? that._momentum(newPosX - that.startX, duration, -that.x, that.scrollerW - that.wrapperW + that.x, that.options.bounce ? that.wrapperW : 0) : momentumX;
                momentumY = newPosY ? that._momentum(newPosY - that.startY, duration, -that.y, (that.maxScrollY < 0 ? that.scrollerH - that.wrapperH + that.y : 0), that.options.bounce ? that.wrapperH : 0) : momentumY;

                newPosX = that.x + momentumX.dist;
                newPosY = that.y + momentumY.dist;

                if ((that.x > 0 && newPosX > 0) || (that.x < that.maxScrollX && newPosX < that.maxScrollX)) momentumX = { dist: 0, time: 0 };
                if ((that.y > 0 && newPosY > 0) || (that.y < that.maxScrollY && newPosY < that.maxScrollY)) momentumY = { dist: 0, time: 0 };
            }

            if (momentumX.dist || momentumY.dist) {
                newDuration = m.max(m.max(momentumX.time, momentumY.time), 10);

                that.scrollTo(newPosX, newPosY, newDuration);

                if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
                return;
            }

            that._resetPos(200);
            if (that.options.onTouchEnd) that.options.onTouchEnd.call(that, e);
        },

        _resetPos: function(time) {
            var that = this,
			resetX = that.x >= 0 ? 0 : that.x < that.maxScrollX ? that.maxScrollX : that.x,
			resetY = that.y >= 0 || that.maxScrollY > 0 ? 0 : that.y < that.maxScrollY ? that.maxScrollY : that.y;

            if (resetX == that.x && resetY == that.y) {
                if (that.moved) {
                    if (that.options.onScrollEnd) that.options.onScrollEnd.call(that); 	// Execute custom code on scroll end
                    that.moved = false;
                }

                return;
            }

            that.scrollTo(resetX, resetY, time || 0);
        },

        _mouseout: function(e) {
            var t = e.relatedTarget;

            if (!t) {
                this._end(e);
                return;
            }

            while (t = t.parentNode) if (t == this.wrapper) return;

            this._end(e);
        },

        _transitionEnd: function(e) {
            var that = this;

            if (e.target != that.scroller) return;

            that._unbind('webkitTransitionEnd');

            that._startAni();
        },

        /**
        *
        * Utilities
        *
        */
        _startAni: function() {
            var that = this,
			startX = that.x, startY = that.y,
			startTime = Date.now(),
			step, easeOut;

            if (that.animating) return;

            if (!that.steps.length) {
                that._resetPos(400);
                return;
            }

            step = that.steps.shift();

            if (step.x == startX && step.y == startY) step.time = 0;

            that.animating = true;
            that.moved = true;

            if (that.options.useTransition) {
                that._transitionTime(step.time);
                that._pos(step.x, step.y);
                that.animating = false;
                if (step.time) that._bind('webkitTransitionEnd');
                else that._resetPos(0);
                return;
            }

            (function animate() {
                var now = Date.now(),
				newX, newY;

                if (now >= startTime + step.time) {
                    that._pos(step.x, step.y);
                    that.animating = false;
                    if (that.options.onAnimationEnd) that.options.onAnimationEnd.call(that); 		// Execute custom code on animation end
                    that._startAni();
                    return;
                }

                now = (now - startTime) / step.time - 1;
                easeOut = m.sqrt(1 - now * now);
                newX = (step.x - startX) * easeOut + startX;
                newY = (step.y - startY) * easeOut + startY;
                that._pos(newX, newY);
                if (that.animating) that.aniTime = nextFrame(animate);
            })();
        },

        _transitionTime: function(time) {
            this.scroller.style[vendor + 'TransitionDuration'] = time + 'ms';
        },

        _momentum: function(dist, time, maxDistUpper, maxDistLower, size) {
            var deceleration = 0.0006,
			speed = m.abs(dist) / time,
			newDist = (speed * speed) / (2 * deceleration),
			newTime = 0, outsideDist = 0;

            // Proportinally reduce speed if we are outside of the boundaries 
            if (dist > 0 && newDist > maxDistUpper) {
                outsideDist = size / (6 / (newDist / speed * deceleration));
                maxDistUpper = maxDistUpper + outsideDist;
                speed = speed * maxDistUpper / newDist;
                newDist = maxDistUpper;
            } else if (dist < 0 && newDist > maxDistLower) {
                outsideDist = size / (6 / (newDist / speed * deceleration));
                maxDistLower = maxDistLower + outsideDist;
                speed = speed * maxDistLower / newDist;
                newDist = maxDistLower;
            }

            newDist = newDist * (dist < 0 ? -1 : 1);
            newTime = speed / deceleration;

            return { dist: newDist, time: m.round(newTime) };
        },

        _offset: function(el) {
            var left = -el.offsetLeft,
			top = -el.offsetTop;

            while (el = el.offsetParent) {
                left -= el.offsetLeft;
                top -= el.offsetTop;
            }

            return { left: left, top: top };
        },

        _bind: function(type, el, bubble) {
            (el || this.scroller).addEventListener(type, this, !!bubble);
        },

        _unbind: function(type, el, bubble) {
            (el || this.scroller).removeEventListener(type, this, !!bubble);
        },


        /**
        *
        * Public methods
        *
        */
        destroy: function() {
            var that = this;

            that.scroller.style[vendor + 'Transform'] = '';

            // Remove the event listeners
            that._unbind(RESIZE_EV, window);
            that._unbind(START_EV);
            that._unbind(MOVE_EV);
            that._unbind(END_EV);
            that._unbind(CANCEL_EV);
            that._unbind('mouseout', that.wrapper);
            if (that.options.useTransition) that._unbind('webkitTransitionEnd');

            if (that.options.onDestroy) that.options.onDestroy.call(that);
        },

        refresh: function() {
            var that = this,
			offset;

            that.wrapperW = that.wrapper.clientWidth;
            that.wrapperH = that.wrapper.clientHeight;

            that.scrollerW = that.scroller.offsetWidth;
            that.scrollerH = that.scroller.offsetHeight;
            that.maxScrollX = that.wrapperW - that.scrollerW;
            that.maxScrollY = that.wrapperH - that.scrollerH;
            that.dirX = 0;
            that.dirY = 0;

            that.hScroll = that.options.hScroll && that.maxScrollX < 0;
            that.vScroll = that.options.vScroll && (!that.options.bounceLock && !that.hScroll || that.scrollerH > that.wrapperH);

            offset = that._offset(that.wrapper);
            that.wrapperOffsetLeft = -offset.left;
            that.wrapperOffsetTop = -offset.top;


            that.scroller.style[vendor + 'TransitionDuration'] = '0';

            that._resetPos(200);
        },

        scrollTo: function(x, y, time, relative) {
            var that = this,
			step = x,
			i, l;

            that.stop();

            if (!step.length) step = [{ x: x, y: y, time: time, relative: relative}];

            for (i = 0, l = step.length; i < l; i++) {
                if (step[i].relative) { step[i].x = that.x - step[i].x; step[i].y = that.y - step[i].y; }
                that.steps.push({ x: step[i].x, y: step[i].y, time: step[i].time || 0 });
            }

            that._startAni();
        },

        scrollToElement: function(el, time) {
            var that = this, pos;
            el = el.nodeType ? el : that.scroller.querySelector(el);
            if (!el) return;

            pos = that._offset(el);
            pos.left += that.wrapperOffsetLeft;
            pos.top += that.wrapperOffsetTop;

            pos.left = pos.left > 0 ? 0 : pos.left < that.maxScrollX ? that.maxScrollX : pos.left;
            pos.top = pos.top > 0 ? 0 : pos.top < that.maxScrollY ? that.maxScrollY : pos.top;
            time = time === undefined ? m.max(m.abs(pos.left) * 2, m.abs(pos.top) * 2) : time;

            that.scrollTo(pos.left, pos.top, time);
        },

        disable: function() {
            this.stop();
            this._resetPos(0);
            this.enabled = false;

            // If disabled after touchstart we make sure that there are no left over events
            this._unbind(MOVE_EV);
            this._unbind(END_EV);
            this._unbind(CANCEL_EV);
        },

        enable: function() {
            this.enabled = true;
        },

        stop: function() {
            cancelFrame(this.aniTime);
            this.steps = [];
            this.moved = false;
            this.animating = false;
        }
    };

    if (typeof exports !== 'undefined') exports.iScroll = iScroll;
    else window.iScroll = iScroll;

})();
// ************************************************************************
//  END iScroll
// ************************************************************************

// ************************************************************************
//  Add 2 Home
// ************************************************************************
/**
* 
* * * * * * * * * * * * * * * * * * * * * * * * * * * *
*
* Copyright (c) 2011 Matteo Spinelli, http://cubiq.org/
* Released under MIT license
* http://cubiq.org/dropbox/mit-license.txt
* 
* Version 1.0.1 - Last updated: 2011.02.05
* 
* * * * * * * * * * * * * * * * * * * * * * * * * * * *
* 
*/
; (function() {
    if (navigator.appName != "Microsoft Internet Explorer") {
        var nav = navigator,
	isIDevice = (/iphone|ipod|ipad/gi).test(nav.platform),
	isIPad = (/ipad/gi).test(nav.platform),
	isRetina = 'devicePixelRatio' in window && window.devicePixelRatio > 1,
	isSafari = nav.appVersion.match(/Safari/gi),
	hasHomescreen = 'standalone' in nav && isIDevice,
	isStandalone = hasHomescreen && nav.standalone,
	OSVersion = nav.appVersion.match(/OS \d+_\d+/g),
	platform = nav.platform.split(' ')[0],
	language = nav.language.replace('-', '_'),
	startY = startX = 0,
	expired = localStorage.getItem('_addToHome'),
	theInterval, closeTimeout, el, i, l,
	options = {
	    animationIn: 'drop', 	// drop || bubble || fade
	    animationOut: 'fade', 	// drop || bubble || fade
	    startDelay: 2000, 		// 2 seconds from page load before the balloon appears
	    lifespan: 20000, 		// 20 seconds before it is automatically destroyed
	    bottomOffset: 14, 		// Distance of the balloon from bottom
	    expire: 0, 				// Minutes to wait before showing the popup again (0 = always displayed)
	    message: '', 			// Customize your message or force a language ('' = automatic)
	    touchIcon: false, 		// Display the touch icon
	    arrow: true, 			// Display the balloon arrow
	    iterations: 100				// Internal/debug use
	},
        /* Message in various languages, en_us is the default if a language does not exist */
	intl = {
	    ca_es: 'Per instalˇlar aquesta aplicaciķ al vostre %device premeu `%icon` i llavors `Afegir a pantalla d\'inici`',
	    da_dk: 'Tilføj denne side til din %device: tryk på `%icon` og derefter `<strong>Tilføj til hjemmeskærm</strong>`.',
	    de_de: 'Installieren Sie diese App auf Ihrem %device: `%icon` antippen und dann `<strong>Zum Home-Bildschirm</strong>`.',
	    el_gr: '????????????? ????? ??? ???????? ???? ??????? ??? %device: `%icon` ???? ?????? `<strong>???????? ?? ????????</strong>`.',
	    en_us: 'For the full app and best experiance, install this web app on your %device: tap `%icon` and then `<strong>Add to Home Screen</strong>`.',
	    es_es: 'Para instalar esta app en su %device, pulse `%icon` y seleccione `<strong>Aņadir a pantalla de inicio</strong>`.',
	    fr_fr: 'Ajoutez cette application sur votre %device en cliquant sur `%icon`, puis `<strong>Ajouter ā l\'écran d\'accueil</strong>`.',
	    he_il: '<span dir="rtl">???? ???????? ?? ?? ?-%device ???: ??? `%icon` ??? `<strong>???? ???? ????</strong>`.</span>',
	    it_it: 'Installa questa applicazione sul tuo %device: premi su `%icon` e poi `<strong>Aggiungi a Home</strong>`.',
	    ja_jp: '?????????????%device???????????`%icon`??????`<strong>????????</strong>`?????????',
	    ko_kr: '%device? ??? ????? %icon? ?? ? "???? ??"? ?????',
	    nl_nl: 'Installeer deze webapp op uw %device: tik `%icon` en dan `<strong>Zet in beginscherm</strong>`.',
	    pt_br: 'Instale este web app em seu %device: aperte `%icon` e selecione `<strong>Adicionar ā Tela Inicio</strong>`.',
	    pt_pt: 'Para instalar esta aplicaįão no seu %device, prima o `%icon` e depois o `<strong>Adicionar ao ecrã principal</strong>`.',
	    sv_se: 'Lägg till denna webbapplikation på din %device: tryck på `%icon` och därefter `<strong>Lägg till på hemskärmen</strong>`.'
	};

        OSVersion = OSVersion ? OSVersion[0].replace(/[^\d_]/g, '').replace('_', '.') * 1 : 0;
        expired = expired == 'null' ? 0 : expired * 1;

        // Merge options
        if (window.addToHomeConfig) {
            for (i in window.addToHomeConfig) {
                options[i] = window.addToHomeConfig[i];
            }
        }

        // Is it expired?
        if (!options.expire || expired < new Date().getTime()) {
            expired = 0;
        }

        /* Bootstrap */
        if (hasHomescreen && !expired && !isStandalone && isSafari) {
            document.addEventListener('DOMContentLoaded', ready, false);
            window.addEventListener('load', loaded, false);
        }


        /* on DOM ready */
        function ready() {
            document.removeEventListener('DOMContentLoaded', ready, false);

            var div = document.createElement('div'),
		close,
		link = options.touchIcon ? document.querySelectorAll('head link[rel=apple-touch-icon],head link[rel=apple-touch-icon-precomposed]') : [],
		sizes, touchIcon = '';

            div.id = 'addToHomeScreen';
            div.style.cssText += 'position:absolute;-webkit-transition-property:-webkit-transform,opacity;-webkit-transition-duration:0;-webkit-transform:translate3d(0,0,0);';
            div.style.left = '-9999px'; 	// Hide from view at startup

            // Localize message
            if (options.message in intl) {		// You may force a language despite the user's locale
                language = options.message;
                options.message = '';
            }
            if (options.message == '') {		// We look for a suitable language (defaulted to en_us)
                options.message = language in intl ? intl[language] : intl['en_us'];
            }

            // Search for the apple-touch-icon
            if (link.length) {
                for (i = 0, l = link.length; i < l; i++) {
                    sizes = link[i].getAttribute('sizes');

                    if (sizes) {
                        if (isRetina && sizes == '114x114') {
                            touchIcon = link[i].href;
                            break;
                        }
                    } else {
                        touchIcon = link[i].href;
                    }
                }

                touchIcon = '<span style="background-image:url(' + touchIcon + ')" class="touchIcon"></span>';
            }

            div.className = (isIPad ? 'ipad' : 'iphone') + (touchIcon ? ' wide' : '');
            div.innerHTML = touchIcon + options.message.replace('%device', platform).replace('%icon', OSVersion >= 4.2 ? '<span class="share"></span>' : '<span class="plus">+</span>') + (options.arrow ? '<span class="arrow"></span>' : '') + '<span class="close">×</span>';

            document.body.appendChild(div);
            el = div;

            // Add the close action
            close = el.querySelector('.close');
            if (close) close.addEventListener('click', addToHomeClose, false);

            // Add expire date to the popup
            if (options.expire) localStorage.setItem('_addToHome', new Date().getTime() + options.expire * 60 * 1000);
        }


        /* on window load */
        function loaded() {
            window.removeEventListener('load', loaded, false);

            setTimeout(function() {
                var duration;

                startY = isIPad ? window.scrollY : window.innerHeight + window.scrollY;
                startX = isIPad ? window.scrollX : Math.round((window.innerWidth - el.offsetWidth) / 2) + window.scrollX;

                el.style.top = isIPad ? startY + options.bottomOffset + 'px' : startY - el.offsetHeight - options.bottomOffset + 'px';
                el.style.left = isIPad ? startX + 208 - Math.round(el.offsetWidth / 2) + 'px' : startX + 'px';

                switch (options.animationIn) {
                    case 'drop':
                        if (isIPad) {
                            duration = '0.6s';
                            el.style.webkitTransform = 'translate3d(0,' + -(window.scrollY + options.bottomOffset + el.offsetHeight) + 'px,0)';
                        } else {
                            duration = '0.9s';
                            el.style.webkitTransform = 'translate3d(0,' + -(startY + options.bottomOffset) + 'px,0)';
                        }
                        break;
                    case 'bubble':
                        if (isIPad) {
                            duration = '0.6s';
                            el.style.opacity = '0'
                            el.style.webkitTransform = 'translate3d(0,' + (startY + 50) + 'px,0)';
                        } else {
                            duration = '0.6s';
                            el.style.webkitTransform = 'translate3d(0,' + (el.offsetHeight + options.bottomOffset + 50) + 'px,0)';
                        }
                        break;
                    default:
                        duration = '1s';
                        el.style.opacity = '0';
                }

                setTimeout(function() {
                    el.style.webkitTransitionDuration = duration;
                    el.style.opacity = '1';
                    el.style.webkitTransform = 'translate3d(0,0,0)';
                    el.addEventListener('webkitTransitionEnd', transitionEnd, false);
                }, 0);

                closeTimeout = setTimeout(addToHomeClose, options.lifespan);
            }, options.startDelay);
        }

        function transitionEnd() {
            el.removeEventListener('webkitTransitionEnd', transitionEnd, false);
            el.style.webkitTransitionProperty = '-webkit-transform';
            el.style.webkitTransitionDuration = '0.2s';

            if (closeTimeout) {		// Standard loop
                clearInterval(theInterval);
                theInterval = setInterval(setPosition, options.iterations);
            } else {				// We are closing
                el.parentNode.removeChild(el);
            }
        }

        function setPosition() {
            var matrix = new WebKitCSSMatrix(window.getComputedStyle(el, null).webkitTransform),
		posY = isIPad ? window.scrollY - startY : window.scrollY + window.innerHeight - startY,
		posX = isIPad ? window.scrollX - startX : window.scrollX + Math.round((window.innerWidth - el.offsetWidth) / 2) - startX;

            if (posY == matrix.m42 && posX == matrix.m41) return;

            clearInterval(theInterval);
            el.removeEventListener('webkitTransitionEnd', transitionEnd, false);
            //	el.style.webkitTransitionDuration = '0';

            setTimeout(function() {
                el.addEventListener('webkitTransitionEnd', transitionEnd, false);
                //		el.style.webkitTransitionDuration = '0.2s';
                el.style.webkitTransform = 'translate3d(' + posX + 'px,' + posY + 'px,0)';
            }, 0);
        }

        function addToHomeClose() {
            clearInterval(theInterval);
            clearTimeout(closeTimeout);
            closeTimeout = null;
            el.removeEventListener('webkitTransitionEnd', transitionEnd, false);

            var posY = isIPad ? window.scrollY - startY : window.scrollY + window.innerHeight - startY,
		posX = isIPad ? window.scrollX - startX : window.scrollX + Math.round((window.innerWidth - el.offsetWidth) / 2) - startX,
		opacity = '1',
		duration = '0',
		close = el.querySelector('.close');

            if (close) close.removeEventListener('click', addToHomeClose, false);

            el.style.webkitTransitionProperty = '-webkit-transform,opacity';

            switch (options.animationOut) {
                case 'drop':
                    if (isIPad) {
                        duration = '0.4s';
                        opacity = '0';
                        posY = posY + 50;
                    } else {
                        duration = '0.6s';
                        posY = posY + el.offsetHeight + options.bottomOffset + 50;
                    }
                    break;
                case 'bubble':
                    if (isIPad) {
                        duration = '0.8s';
                        posY = posY - el.offsetHeight - options.bottomOffset - 50;
                    } else {
                        duration = '0.4s';
                        opacity = '0';
                        posY = posY - 50;
                    }
                    break;
                default:
                    duration = '0.8s';
                    opacity = '0';
            }

            el.addEventListener('webkitTransitionEnd', transitionEnd, false);
            el.style.opacity = opacity;
            el.style.webkitTransitionDuration = duration;
            el.style.webkitTransform = 'translate3d(' + posX + 'px,' + posY + 'px,0)';
        }

        /* Public function */
        window.addToHomeClose = addToHomeClose;
    }
})();
// ************************************************************************
//  END Add 2 Home
// ************************************************************************

// Modernizr v1.7  www.modernizr.com
// PhoneID Library
window.Modernizr = function(a, b, c) { function G() { e.input = function(a) { for (var b = 0, c = a.length; b < c; b++) t[a[b]] = !!(a[b] in l); return t } ("autocomplete autofocus list placeholder max min multiple pattern required step".split(" ")), e.inputtypes = function(a) { for (var d = 0, e, f, h, i = a.length; d < i; d++) l.setAttribute("type", f = a[d]), e = l.type !== "text", e && (l.value = m, l.style.cssText = "position:absolute;visibility:hidden;", /^range$/.test(f) && l.style.WebkitAppearance !== c ? (g.appendChild(l), h = b.defaultView, e = h.getComputedStyle && h.getComputedStyle(l, null).WebkitAppearance !== "textfield" && l.offsetHeight !== 0, g.removeChild(l)) : /^(search|tel)$/.test(f) || (/^(url|email)$/.test(f) ? e = l.checkValidity && l.checkValidity() === !1 : /^color$/.test(f) ? (g.appendChild(l), g.offsetWidth, e = l.value != m, g.removeChild(l)) : e = l.value != m)), s[a[d]] = !!e; return s } ("search tel url email datetime date month week time datetime-local number range color".split(" ")) } function F(a, b) { var c = a.charAt(0).toUpperCase() + a.substr(1), d = (a + " " + p.join(c + " ") + c).split(" "); return !!E(d, b) } function E(a, b) { for (var d in a) if (k[a[d]] !== c && (!b || b(a[d], j))) return !0 } function D(a, b) { return ("" + a).indexOf(b) !== -1 } function C(a, b) { return typeof a === b } function B(a, b) { return A(o.join(a + ";") + (b || "")) } function A(a) { k.cssText = a } var d = "1.7", e = {}, f = !0, g = b.documentElement, h = b.head || b.getElementsByTagName("head")[0], i = "modernizr", j = b.createElement(i), k = j.style, l = b.createElement("input"), m = ":)", n = Object.prototype.toString, o = " -webkit- -moz- -o- -ms- -khtml- ".split(" "), p = "Webkit Moz O ms Khtml".split(" "), q = { svg: "http://www.w3.org/2000/svg" }, r = {}, s = {}, t = {}, u = [], v, w = function(a) { var c = b.createElement("style"), d = b.createElement("div"), e; c.textContent = a + "{#modernizr{height:3px}}", h.appendChild(c), d.id = "modernizr", g.appendChild(d), e = d.offsetHeight === 3, c.parentNode.removeChild(c), d.parentNode.removeChild(d); return !!e }, x = function() { function d(d, e) { e = e || b.createElement(a[d] || "div"); var f = (d = "on" + d) in e; f || (e.setAttribute || (e = b.createElement("div")), e.setAttribute && e.removeAttribute && (e.setAttribute(d, ""), f = C(e[d], "function"), C(e[d], c) || (e[d] = c), e.removeAttribute(d))), e = null; return f } var a = { select: "input", change: "input", submit: "form", reset: "form", error: "img", load: "img", abort: "img" }; return d } (), y = ({}).hasOwnProperty, z; C(y, c) || C(y.call, c) ? z = function(a, b) { return b in a && C(a.constructor.prototype[b], c) } : z = function(a, b) { return y.call(a, b) }, r.flexbox = function() { function c(a, b, c, d) { a.style.cssText = o.join(b + ":" + c + ";") + (d || "") } function a(a, b, c, d) { b += ":", a.style.cssText = (b + o.join(c + ";" + b)).slice(0, -b.length) + (d || "") } var d = b.createElement("div"), e = b.createElement("div"); a(d, "display", "box", "width:42px;padding:0;"), c(e, "box-flex", "1", "width:10px;"), d.appendChild(e), g.appendChild(d); var f = e.offsetWidth === 42; d.removeChild(e), g.removeChild(d); return f }, r.canvas = function() { var a = b.createElement("canvas"); return a.getContext && a.getContext("2d") }, r.canvastext = function() { return e.canvas && C(b.createElement("canvas").getContext("2d").fillText, "function") }, r.webgl = function() { return !!a.WebGLRenderingContext }, r.touch = function() { return "ontouchstart" in a || w("@media (" + o.join("touch-enabled),(") + "modernizr)") }, r.geolocation = function() { return !!navigator.geolocation }, r.postmessage = function() { return !!a.postMessage }, r.websqldatabase = function() { var b = !!a.openDatabase; return b }, r.indexedDB = function() { for (var b = -1, c = p.length; ++b < c; ) { var d = p[b].toLowerCase(); if (a[d + "_indexedDB"] || a[d + "IndexedDB"]) return !0 } return !1 }, r.hashchange = function() { return x("hashchange", a) && (b.documentMode === c || b.documentMode > 7) }, r.history = function() { return !!(a.history && history.pushState) }, r.draganddrop = function() { return x("dragstart") && x("drop") }, r.websockets = function() { return "WebSocket" in a }, r.rgba = function() { A("background-color:rgba(150,255,150,.5)"); return D(k.backgroundColor, "rgba") }, r.hsla = function() { A("background-color:hsla(120,40%,100%,.5)"); return D(k.backgroundColor, "rgba") || D(k.backgroundColor, "hsla") }, r.multiplebgs = function() { A("background:url(//:),url(//:),red url(//:)"); return (new RegExp("(url\\s*\\(.*?){3}")).test(k.background) }, r.backgroundsize = function() { return F("backgroundSize") }, r.borderimage = function() { return F("borderImage") }, r.borderradius = function() { return F("borderRadius", "", function(a) { return D(a, "orderRadius") }) }, r.boxshadow = function() { return F("boxShadow") }, r.textshadow = function() { return b.createElement("div").style.textShadow === "" }, r.opacity = function() { B("opacity:.55"); return /^0.55$/.test(k.opacity) }, r.cssanimations = function() { return F("animationName") }, r.csscolumns = function() { return F("columnCount") }, r.cssgradients = function() { var a = "background-image:", b = "gradient(linear,left top,right bottom,from(#9f9),to(white));", c = "linear-gradient(left top,#9f9, white);"; A((a + o.join(b + a) + o.join(c + a)).slice(0, -a.length)); return D(k.backgroundImage, "gradient") }, r.cssreflections = function() { return F("boxReflect") }, r.csstransforms = function() { return !!E(["transformProperty", "WebkitTransform", "MozTransform", "OTransform", "msTransform"]) }, r.csstransforms3d = function() { var a = !!E(["perspectiveProperty", "WebkitPerspective", "MozPerspective", "OPerspective", "msPerspective"]); a && "webkitPerspective" in g.style && (a = w("@media (" + o.join("transform-3d),(") + "modernizr)")); return a }, r.csstransitions = function() { return F("transitionProperty") }, r.fontface = function() { var a, c, d = h || g, e = b.createElement("style"), f = b.implementation || { hasFeature: function() { return !1 } }; e.type = "text/css", d.insertBefore(e, d.firstChild), a = e.sheet || e.styleSheet; var i = f.hasFeature("CSS2", "") ? function(b) { if (!a || !b) return !1; var c = !1; try { a.insertRule(b, 0), c = /src/i.test(a.cssRules[0].cssText), a.deleteRule(a.cssRules.length - 1) } catch (d) { } return c } : function(b) { if (!a || !b) return !1; a.cssText = b; return a.cssText.length !== 0 && /src/i.test(a.cssText) && a.cssText.replace(/\r+|\n+/g, "").indexOf(b.split(" ")[0]) === 0 }; c = i('@font-face { font-family: "font"; src: url(data:,); }'), d.removeChild(e); return c }, r.video = function() { var a = b.createElement("video"), c = !!a.canPlayType; if (c) { c = new Boolean(c), c.ogg = a.canPlayType('video/ogg; codecs="theora"'); var d = 'video/mp4; codecs="avc1.42E01E'; c.h264 = a.canPlayType(d + '"') || a.canPlayType(d + ', mp4a.40.2"'), c.webm = a.canPlayType('video/webm; codecs="vp8, vorbis"') } return c }, r.audio = function() { var a = b.createElement("audio"), c = !!a.canPlayType; c && (c = new Boolean(c), c.ogg = a.canPlayType('audio/ogg; codecs="vorbis"'), c.mp3 = a.canPlayType("audio/mpeg;"), c.wav = a.canPlayType('audio/wav; codecs="1"'), c.m4a = a.canPlayType("audio/x-m4a;") || a.canPlayType("audio/aac;")); return c }, r.localstorage = function() { try { return !!localStorage.getItem } catch (a) { return !1 } }, r.sessionstorage = function() { try { return !!sessionStorage.getItem } catch (a) { return !1 } }, r.webWorkers = function() { return !!a.Worker }, r.applicationcache = function() { return !!a.applicationCache }, r.svg = function() { return !!b.createElementNS && !!b.createElementNS(q.svg, "svg").createSVGRect }, r.inlinesvg = function() { var a = b.createElement("div"); a.innerHTML = "<svg/>"; return (a.firstChild && a.firstChild.namespaceURI) == q.svg }, r.smil = function() { return !!b.createElementNS && /SVG/.test(n.call(b.createElementNS(q.svg, "animate"))) }, r.svgclippaths = function() { return !!b.createElementNS && /SVG/.test(n.call(b.createElementNS(q.svg, "clipPath"))) }; for (var H in r) z(r, H) && (v = H.toLowerCase(), e[v] = r[H](), u.push((e[v] ? "" : "no-") + v)); e.input || G(), e.crosswindowmessaging = e.postmessage, e.historymanagement = e.history, e.addTest = function(a, b) { a = a.toLowerCase(); if (!e[a]) { b = !!b(), g.className += " " + (b ? "" : "no-") + a, e[a] = b; return e } }, A(""), j = l = null, f && a.attachEvent && function() { var a = b.createElement("div"); a.innerHTML = "<elem></elem>"; return a.childNodes.length !== 1 } () && function(a, b) { function p(a, b) { var c = -1, d = a.length, e, f = []; while (++c < d) e = a[c], (b = e.media || b) != "screen" && f.push(p(e.imports, b), e.cssText); return f.join("") } function o(a) { var b = -1; while (++b < e) a.createElement(d[b]) } var c = "abbr|article|aside|audio|canvas|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", d = c.split("|"), e = d.length, f = new RegExp("(^|\\s)(" + c + ")", "gi"), g = new RegExp("<(/*)(" + c + ")", "gi"), h = new RegExp("(^|[^\\n]*?\\s)(" + c + ")([^\\n]*)({[\\n\\w\\W]*?})", "gi"), i = b.createDocumentFragment(), j = b.documentElement, k = j.firstChild, l = b.createElement("body"), m = b.createElement("style"), n; o(b), o(i), k.insertBefore(m, k.firstChild), m.media = "print", a.attachEvent("onbeforeprint", function() { var a = -1, c = p(b.styleSheets, "all"), k = [], o; n = n || b.body; while ((o = h.exec(c)) != null) k.push((o[1] + o[2] + o[3]).replace(f, "$1.iepp_$2") + o[4]); m.styleSheet.cssText = k.join("\n"); while (++a < e) { var q = b.getElementsByTagName(d[a]), r = q.length, s = -1; while (++s < r) q[s].className.indexOf("iepp_") < 0 && (q[s].className += " iepp_" + d[a]) } i.appendChild(n), j.appendChild(l), l.className = n.className, l.innerHTML = n.innerHTML.replace(g, "<$1font") }), a.attachEvent("onafterprint", function() { l.innerHTML = "", j.removeChild(l), j.appendChild(n), m.styleSheet.cssText = "" }) } (a, b), e._enableHTML5 = f, e._version = d, g.className = g.className.replace(/\bno-js\b/, "") + " js " + u.join(" "); return e } (this, this.document)
// END Modernizr

// SpinningWheel-min
var SpinningWheel = { cellHeight: 44, friction: 0.003, slotData: [], handleEvent: function(e) { if (e.type == "touchstart") { this.lockScreen(e); if (e.currentTarget.id == "sw-cancel" || e.currentTarget.id == "sw-done") { this.tapDown(e) } else { if (e.currentTarget.id == "sw-frame") { this.scrollStart(e) } } } else { if (e.type == "touchmove") { this.lockScreen(e); if (e.currentTarget.id == "sw-cancel" || e.currentTarget.id == "sw-done") { this.tapCancel(e) } else { if (e.currentTarget.id == "sw-frame") { this.scrollMove(e) } } } else { if (e.type == "touchend") { if (e.currentTarget.id == "sw-cancel" || e.currentTarget.id == "sw-done") { this.tapUp(e) } else { if (e.currentTarget.id == "sw-frame") { this.scrollEnd(e) } } } else { if (e.type == "webkitTransitionEnd") { if (e.target.id == "sw-wrapper") { this.destroy() } else { this.backWithinBoundaries(e) } } else { if (e.type == "orientationchange") { this.onOrientationChange(e) } else { if (e.type == "scroll") { this.onScroll(e) } } } } } } }, onOrientationChange: function(e) { window.scrollTo(0, 0); this.swWrapper.style.top = window.innerHeight + window.pageYOffset + "px"; this.calculateSlotsWidth() }, onScroll: function(e) { this.swWrapper.style.top = window.innerHeight + window.pageYOffset + "px" }, lockScreen: function(e) { e.preventDefault(); e.stopPropagation() }, reset: function() { this.slotEl = []; this.activeSlot = null; this.swWrapper = undefined; this.swSlotWrapper = undefined; this.swSlots = undefined; this.swFrame = undefined }, calculateSlotsWidth: function() { var div = this.swSlots.getElementsByTagName("div"); for (var i = 0; i < div.length; i += 1) { this.slotEl[i].slotWidth = div[i].offsetWidth } }, create: function() { var i, l, out, ul, div; this.reset(); div = document.createElement("div"); div.id = "sw-wrapper"; div.style.top = window.innerHeight + window.pageYOffset + "px"; div.style.webkitTransitionProperty = "-webkit-transform"; div.innerHTML = '<div id="sw-header"><div id="sw-cancel">Cancel</div><div id="sw-done">Done</div></div><div id="sw-slots-wrapper"><div id="sw-slots"></div></div><div id="sw-frame"></div>'; document.body.appendChild(div); this.swWrapper = div; this.swSlotWrapper = document.getElementById("sw-slots-wrapper"); this.swSlots = document.getElementById("sw-slots"); this.swFrame = document.getElementById("sw-frame"); for (l = 0; l < this.slotData.length; l += 1) { ul = document.createElement("ul"); out = ""; for (i in this.slotData[l].values) { out += "<li>" + this.slotData[l].values[i] + "</li>" } ul.innerHTML = out; div = document.createElement("div"); div.className = this.slotData[l].style; div.appendChild(ul); this.swSlots.appendChild(div); ul.slotPosition = l; ul.slotYPosition = 0; ul.slotWidth = 0; ul.slotMaxScroll = this.swSlotWrapper.clientHeight - ul.clientHeight - 86; ul.style.webkitTransitionTimingFunction = "cubic-bezier(0, 0, 0.2, 1)"; this.slotEl.push(ul); if (this.slotData[l].defaultValue) { this.scrollToValue(l, this.slotData[l].defaultValue) } } this.calculateSlotsWidth(); document.addEventListener("touchstart", this, false); document.addEventListener("touchmove", this, false); window.addEventListener("orientationchange", this, true); window.addEventListener("scroll", this, true); document.getElementById("sw-cancel").addEventListener("touchstart", this, false); document.getElementById("sw-done").addEventListener("touchstart", this, false); this.swFrame.addEventListener("touchstart", this, false) }, open: function() { this.create(); this.swWrapper.style.webkitTransitionTimingFunction = "ease-out"; this.swWrapper.style.webkitTransitionDuration = "400ms"; this.swWrapper.style.webkitTransform = "translate3d(0, -260px, 0)" }, destroy: function() { this.swWrapper.removeEventListener("webkitTransitionEnd", this, false); this.swFrame.removeEventListener("touchstart", this, false); document.getElementById("sw-cancel").removeEventListener("touchstart", this, false); document.getElementById("sw-done").removeEventListener("touchstart", this, false); document.removeEventListener("touchstart", this, false); document.removeEventListener("touchmove", this, false); window.removeEventListener("orientationchange", this, true); window.removeEventListener("scroll", this, true); this.slotData = []; this.cancelAction = function() { return false }; this.cancelDone = function() { return true }; this.reset(); document.body.removeChild(document.getElementById("sw-wrapper")) }, close: function() { this.swWrapper.style.webkitTransitionTimingFunction = "ease-in"; this.swWrapper.style.webkitTransitionDuration = "400ms"; this.swWrapper.style.webkitTransform = "translate3d(0, 0, 0)"; this.swWrapper.addEventListener("webkitTransitionEnd", this, false) }, addSlot: function(values, style, defaultValue) { if (!style) { style = "" } style = style.split(" "); for (var i = 0; i < style.length; i += 1) { style[i] = "sw-" + style[i] } style = style.join(" "); var obj = { values: values, style: style, defaultValue: defaultValue }; this.slotData.push(obj) }, getSelectedValues: function() { var index, count, i, l, keys = [], values = []; for (i in this.slotEl) { this.slotEl[i].removeEventListener("webkitTransitionEnd", this, false); this.slotEl[i].style.webkitTransitionDuration = "0"; if (this.slotEl[i].slotYPosition > 0) { this.setPosition(i, 0) } else { if (this.slotEl[i].slotYPosition < this.slotEl[i].slotMaxScroll) { this.setPosition(i, this.slotEl[i].slotMaxScroll) } } index = -Math.round(this.slotEl[i].slotYPosition / this.cellHeight); count = 0; for (l in this.slotData[i].values) { if (count == index) { keys.push(l); values.push(this.slotData[i].values[l]); break } count += 1 } } return { keys: keys, values: values} }, setPosition: function(slot, pos) { this.slotEl[slot].slotYPosition = pos; this.slotEl[slot].style.webkitTransform = "translate3d(0, " + pos + "px, 0)" }, scrollStart: function(e) { var xPos = e.targetTouches[0].clientX - this.swSlots.offsetLeft; var slot = 0; for (var i = 0; i < this.slotEl.length; i += 1) { slot += this.slotEl[i].slotWidth; if (xPos < slot) { this.activeSlot = i; break } } if (this.slotData[this.activeSlot].style.match("readonly")) { this.swFrame.removeEventListener("touchmove", this, false); this.swFrame.removeEventListener("touchend", this, false); return false } this.slotEl[this.activeSlot].removeEventListener("webkitTransitionEnd", this, false); this.slotEl[this.activeSlot].style.webkitTransitionDuration = "0"; var theTransform = window.getComputedStyle(this.slotEl[this.activeSlot]).webkitTransform; theTransform = new WebKitCSSMatrix(theTransform).m42; if (theTransform != this.slotEl[this.activeSlot].slotYPosition) { this.setPosition(this.activeSlot, theTransform) } this.startY = e.targetTouches[0].clientY; this.scrollStartY = this.slotEl[this.activeSlot].slotYPosition; this.scrollStartTime = e.timeStamp; this.swFrame.addEventListener("touchmove", this, false); this.swFrame.addEventListener("touchend", this, false); return true }, scrollMove: function(e) { var topDelta = e.targetTouches[0].clientY - this.startY; if (this.slotEl[this.activeSlot].slotYPosition > 0 || this.slotEl[this.activeSlot].slotYPosition < this.slotEl[this.activeSlot].slotMaxScroll) { topDelta /= 2 } this.setPosition(this.activeSlot, this.slotEl[this.activeSlot].slotYPosition + topDelta); this.startY = e.targetTouches[0].clientY; if (e.timeStamp - this.scrollStartTime > 80) { this.scrollStartY = this.slotEl[this.activeSlot].slotYPosition; this.scrollStartTime = e.timeStamp } }, scrollEnd: function(e) { this.swFrame.removeEventListener("touchmove", this, false); this.swFrame.removeEventListener("touchend", this, false); if (this.slotEl[this.activeSlot].slotYPosition > 0 || this.slotEl[this.activeSlot].slotYPosition < this.slotEl[this.activeSlot].slotMaxScroll) { this.scrollTo(this.activeSlot, this.slotEl[this.activeSlot].slotYPosition > 0 ? 0 : this.slotEl[this.activeSlot].slotMaxScroll); return false } var scrollDistance = this.slotEl[this.activeSlot].slotYPosition - this.scrollStartY; if (scrollDistance < this.cellHeight / 1.5 && scrollDistance > -this.cellHeight / 1.5) { if (this.slotEl[this.activeSlot].slotYPosition % this.cellHeight) { this.scrollTo(this.activeSlot, Math.round(this.slotEl[this.activeSlot].slotYPosition / this.cellHeight) * this.cellHeight, "100ms") } return false } var scrollDuration = e.timeStamp - this.scrollStartTime; var newDuration = (2 * scrollDistance / scrollDuration) / this.friction; var newScrollDistance = (this.friction / 2) * (newDuration * newDuration); if (newDuration < 0) { newDuration = -newDuration; newScrollDistance = -newScrollDistance } var newPosition = this.slotEl[this.activeSlot].slotYPosition + newScrollDistance; if (newPosition > 0) { newPosition /= 2; newDuration /= 3; if (newPosition > this.swSlotWrapper.clientHeight / 4) { newPosition = this.swSlotWrapper.clientHeight / 4 } } else { if (newPosition < this.slotEl[this.activeSlot].slotMaxScroll) { newPosition = (newPosition - this.slotEl[this.activeSlot].slotMaxScroll) / 2 + this.slotEl[this.activeSlot].slotMaxScroll; newDuration /= 3; if (newPosition < this.slotEl[this.activeSlot].slotMaxScroll - this.swSlotWrapper.clientHeight / 4) { newPosition = this.slotEl[this.activeSlot].slotMaxScroll - this.swSlotWrapper.clientHeight / 4 } } else { newPosition = Math.round(newPosition / this.cellHeight) * this.cellHeight } } this.scrollTo(this.activeSlot, Math.round(newPosition), Math.round(newDuration) + "ms"); return true }, scrollTo: function(slotNum, dest, runtime) { this.slotEl[slotNum].style.webkitTransitionDuration = runtime ? runtime : "100ms"; this.setPosition(slotNum, dest ? dest : 0); if (this.slotEl[slotNum].slotYPosition > 0 || this.slotEl[slotNum].slotYPosition < this.slotEl[slotNum].slotMaxScroll) { this.slotEl[slotNum].addEventListener("webkitTransitionEnd", this, false) } }, scrollToValue: function(slot, value) { var yPos, count, i; this.slotEl[slot].removeEventListener("webkitTransitionEnd", this, false); this.slotEl[slot].style.webkitTransitionDuration = "0"; count = 0; for (i in this.slotData[slot].values) { if (i == value) { yPos = count * this.cellHeight; this.setPosition(slot, yPos); break } count -= 1 } }, backWithinBoundaries: function(e) { e.target.removeEventListener("webkitTransitionEnd", this, false); this.scrollTo(e.target.slotPosition, e.target.slotYPosition > 0 ? 0 : e.target.slotMaxScroll, "150ms"); return false }, tapDown: function(e) { e.currentTarget.addEventListener("touchmove", this, false); e.currentTarget.addEventListener("touchend", this, false); e.currentTarget.className = "sw-pressed" }, tapCancel: function(e) { e.currentTarget.removeEventListener("touchmove", this, false); e.currentTarget.removeEventListener("touchend", this, false); e.currentTarget.className = "" }, tapUp: function(e) { this.tapCancel(e); if (e.currentTarget.id == "sw-cancel") { this.cancelAction() } else { this.doneAction() } this.close() }, setCancelAction: function(action) { this.cancelAction = action }, setDoneAction: function(action) { this.doneAction = action }, cancelAction: function() { return false }, cancelDone: function() { return true } };
// End SpinningWheel-min

//************************************************************************
// JS Animation
//************************************************************************
/*!
jsAnim: Powerful javascript animation
--------------------------------------------
Copyright 2009 Kevin Dolan
-http://www.thekevindolan.com
	
Code licensed under the MIT license
-See license.txt
	
v0.2
*/

//These vars are used to hold all jsAnimManagers
var jsAnimManagers = new Array();
var jsAnimManagerId = 0;

/*! public, accessible
jsAnimManager object constructor
Used by end-user to manage jsAnim objects
Params:
-[timestep] : time between frames, defaults to 40
*/
function jsAnimManager(timestep) {

    jsAnimManagers[jsAnimManagerId] = this;
    this.myId = jsAnimManagerId;
    jsAnimManagerId++;

    if (timestep)
        this.timestep = timestep;
    else
        this.timestep = 40;

    this.paused = false;

    this.animObjects = new Array();
    this.index = 0;

    //Used internally to process a single frame of all active animations
    this.step = function() {
        if (!this.paused) {
            for (x in this.animObjects) {
                this.animObjects[x].step();
            }
            setTimeout("jsAnimManagers[" + this.myId + "].step()", this.timestep);
        }
    };

    //Used internally to kill a jsAnimObject
    this.kill = function(id) {
        delete this.animObjects[id];
    };

    /*! public
    Called to create a new animation object
    Params:
    -objId : id of object being controlled
    */
    this.createAnimObject = function(objId) {
        var el = document.getElementById(objId);
        var id = this.index;
        this.animObjects[id] = new jsAnimObject(el, id, this);
        this.index++;
        return this.animObjects[id];
    };

    /*! public
    Called to pause the animation manager
    */
    this.pause = function() {
        this.paused = true;
    };

    /*! public
    Called to unpause the animation manager
    */
    this.resume = function() {
        this.paused = false;
        this.step();
    };

    /*! public
    Called to set the appropriate style values to allow position to be controlled by jsAnim
    Params:
    -objId : id of object to be registered
    -[fixed] : fixed positioning, false to absolute fixed, defaults to false
    */
    this.registerPosition = function(objId, fixed) {
        var el = document.getElementById(objId);
        var width = el.offsetWidth;
        var height = el.offsetHeight;

        if (fixed)
            el.style.position = "fixed";
        else
            el.style.position = "absolute";

        el.style.top = "0px";
        el.style.left = "50%";
        el.halfWidth = Math.floor(width / 2);
        el.halfHeight = Math.floor(height / 2);
        el.style.marginLeft = (-el.halfWidth) + "px";
        el.style.marginTop = (-el.halfHeight) + "px";

        el.positionRegistered = true;

        /*! public
        Called to manually set the position of this object
        */
        el.setPosition = function(x, y) {
            this.style.marginLeft = (x - this.halfWidth) + "px";
            this.style.marginTop = (y - this.halfHeight) + "px";
        };

    };

    this.step();
    return true;
}

/*! accesible
jsAnimObject object constructor
Used internally to hold the state of a single animation manager
Params:
-obj : object being animated
		
*/
function jsAnimObject(obj, id, manager) {

    this.id = id;
    this.obj = obj;
    this.paused = false;
    this.animEntries = new Array();
    this.animLoops = new Array();
    this.current = 0;
    this.manager = manager;

    this.step = function() {
        if (!this.paused) {
            //Ugly code to get only the first element in the array
            for (x in this.animEntries) {
                var finished = this.animEntries[x].step();
                if (finished) {
                    this.animLoops[x]--;
                    this.animEntries[x].current = 0;
                    this.animEntries[x].onLoop();
                }
                if (this.animLoops[x] == 0) {
                    this.animEntries[x].onComplete();
                    delete this.animEntries[x];
                }
                break;
            }
        }
    };

    /*! public
    Called to add an animation to the chain
    Params:
    -params : a collection in the containing the following elements
    - property : the Prop object to animate
    - [from] : optional from value, if unspecified current value is used
    - to : the value to animate to
    - duration : the length of time this animation should take
    - [ease] : the jsAnimEase object to use, if unspecified linear will be used
    - [loop] : the number of times to loop the animation, negative values are infinite, if unspecified 1 will be used
    - [onLoop] : the callback function for loop completion
    - [onComplete] : the callback function for animation completion
    */
    this.add = function(params) {

        var property = params.property;
        var from = params.from
        var to = params.to;
        var duration = params.duration;
        if (params.ease)
            var ease = params.ease;
        else
            var ease = jsAnimEase.linear;
        if (params.loop)
            var loop = params.loop;
        else
            var loop = 1;
        if (params.onLoop)
            var onLoop = params.onLoop;
        else
            var onLoop = function() { };
        if (params.onComplete)
            var onComplete = params.onComplete;
        else
            var onComplete = function() { };

        this.animEntries[this.current] = new jsAnimEntry(this.obj, property, from, to, duration, this.manager.timestep, ease, onLoop, onComplete);
        this.animLoops[this.current] = loop;

        this.current++;

    };

    /*! public
    Called to skip the current animation, can be used to exit an infinite loop
    */
    this.skip = function() {
        //Ugly code to get only the first element in the array
        for (x in this.animEntries) {
            delete this.animEntries[x];
            break;
        }
    };

    /*! public
    Called to pause this animator
    */
    this.pause = function() {
        this.paused = true;
    };

    /*! public
    Called to resum this animator
    */
    this.resume = function() {
        this.paused = false;
    };

    /*! public
    Called to kill this animator
    */
    this.kill = function() {
        this.manager.kill(this.id);
    };

    return true;
}

/*! public, accesible
Pos object constructor
Called to store an x and y coordinate representing an object's center
according to the jsAnim coordinate system
Params:
-x : x coordinate, 0 is center, negative is left, positive is right
-y : y coordinate, 0 is top, positive id below
*/
function Pos(x, y) {

    //public
    this.x = x;

    //public
    this.y = y;

    return true;
}

/*! public, accesible
Dim object constructor
Called to store a width/height dimension
Params:
-w : width
-h : height
*/
function Dim(w, h) {

    //public
    this.w = w;

    //public
    this.h = h;

    return true;
}

/*! public, accesible
Col object constructor
Called to store an RGB color
Params:
-r : red value (0,255)
-g : green value (0,255)
-b : blue value (0,255)
*/
function Col(r, g, b) {

    //public
    this.r = r;

    //public
    this.g = g;

    //public
    this.b = b;

    return true;
}

/*! 
jsAnimEntry object constructor
Used internally to hold the state of single animation entry
Params:
-property : jsAnimProp object
-from : initial value
-to : end value
-duration : total time of animation (ms)
-ease : jsAnimEase object
-timestep : the timestep value of the animation manager
-onLoop : called after each loop
-onComplete : called after completion
*/
function jsAnimEntry(obj, property, from, to, duration, timestep, ease, onLoop, onComplete) {

    this.obj = obj;
    this.property = property;
    this.from = from;
    this.to = to;
    this.duration = duration;
    this.timestep = timestep;
    this.ease = ease;
    this.current = 0;
    this.onLoop = onLoop;
    this.onComplete = onComplete;

    /*!
    Used internally to move the object one step
    Returns : true if this anim entry has completed, false otherwise
    */
    this.step = function() {
        if (!this.from)
            this.from = this.property.current(this.obj);

        if (this.current >= this.duration) {
            var p = this.ease.transform(1);
            this.property.update(this.obj, this.from, this.to, p);
            return true;
        }
        else {
            var t = this.current / this.duration;
            var p = this.ease.transform(t);
            this.property.update(this.obj, this.from, this.to, p);
            this.current += this.timestep;
            return false;
        }
    };

    return true;
}

/*! public
jsAnimEase objects
Used to control easing
Methods:
transform : Transform a number 0-1 representing a time proportion
to a new number 0-1 representing a progress proportion 
*/
var jsAnimEase = {

    /*!public
    Constant Rate
    */
    linear: {
        transform: function(t) {
            return t;
        }
    },

    /*!public
    Starts slow, then speeds up
    */
    parabolicPos: {
        transform: function(t) {
            return t * t;
        }
    },

    /*!public
    Starts fast, then slows down
    */
    parabolicNeg: {
        transform: function(t) {
            return 1 - (t - 1) * (t - 1);
        }
    },

    /*!public
    Overshoots target then returns to target
    Params:
    -g : overshoot amount [0-1]
    */
    backout: function(g) {
        return {
            transform: function(t) {
                return (-1 * t * (t + g - 2)) / (1 - g);
            }
        };
    },

    /*!public
    Backs up a bit then moves to target
    Params:
    -g : backup amount [0-1]
    */
    backin: function(g) {
        return {
            transform: function(t) {
                return 1 + ((t + 1 - g) * ((t + 1 - g) + g - 2)) / (1 - g);
            }
        };
    },

    /*!public
    Goes to target and then back at constant rate
    */
    bounceLinear: {
        transform: function(t) {
            if (t < 0.5)
                return 2 * t;
            else
                return 1 - 2 * (t - 0.5)
        }
    },

    /*!public
    Goes to target and then back at variable rate
    */
    bounceParabolic: {
        transform: function(t) {
            return -4 * t * (t - 1);
        }
    },

    /*!public
    Goes to target and then back smoothly
    */
    bounceSmooth: {
        transform: function(t) {
            return 0.5 - 0.5 * Math.cos(2 * Math.PI * t);
        }
    }
}

/*!
Utility objects for internal use
*/
var jsAnimUtil = {

    interp: function(v1, v2, percent) {
        if (isNaN(v1))
            v1 = 0;
        if (isNaN(v2))
            v2 = 0;
        var v = v1 + percent * (v2 - v1);
        return Math.floor(v);
    },

    getCSS: function(elem, field) {
        var css = document.defaultView && document.defaultView.getComputedStyle ?
			document.defaultView.getComputedStyle(elem, null)
			: elem.currentStyle || elem.style;
        return css[field];
    },

    explode: function(delimiter, string, limit) {
        // http://kevin.vanzonneveld.net
        // +     original by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +     improved by: kenneth
        // +     improved by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // +     improved by: d3x
        // +     bugfixed by: Kevin van Zonneveld (http://kevin.vanzonneveld.net)
        // *     example 1: explode(' ', 'Kevin van Zonneveld');
        // *     returns 1: {0: 'Kevin', 1: 'van', 2: 'Zonneveld'}
        // *     example 2: explode('=', 'a=bc=d', 2);
        // *     returns 2: ['a', 'bc=d']

        var emptyArray = { 0: '' };

        // third argument is not required
        if (arguments.length < 2 ||
			typeof arguments[0] == 'undefined' ||
			typeof arguments[1] == 'undefined') {
            return null;
        }

        if (delimiter === '' ||
			delimiter === false ||
			delimiter === null) {
            return false;
        }

        if (typeof delimiter == 'function' ||
			typeof delimiter == 'object' ||
			typeof string == 'function' ||
			typeof string == 'object') {
            return emptyArray;
        }

        if (delimiter === true) {
            delimiter = '1';
        }

        if (!limit) {
            return string.toString().split(delimiter.toString());
        } else {
            // support for limit argument
            var splitted = string.toString().split(delimiter.toString());
            var partA = splitted.splice(0, limit - 1);
            var partB = splitted.join(delimiter.toString());
            partA.push(partB);
            return partA;
        }
    }
}

/*! public
Prop objects
Used to keep track of which property is being controlled
Methods:
update : update the property to where it should be at the given time
current : return a natural representation of the current property
*/
var Prop = {
    /*! public
    Wait, while doing no animating
    */
    wait: {
        update: function(obj, from, to, percent) { },
        current: function(obj) { return 0; }
    },

    /*! public
    Follows a linear path
    */
    position: {
        update: function(obj, from, to, percent) {
            var x = jsAnimUtil.interp(from.x, to.x, percent);
            var y = jsAnimUtil.interp(from.y, to.y, percent);

            obj.setPosition(x, y);
        },

        current: function(obj) {
            var left = parseInt(obj.style.marginLeft);
            var top = parseInt(obj.style.marginTop);
            var x = left + obj.halfWidth;
            var y = top + obj.halfHeight;
            return new Pos(x, y);
        }
    },

    /*! public
    Follows a semicircular path
    Params:
    -clockwise : True for clockwise, false otherwise
    */
    positionSemicircle: function(clockwise) {
        return {
            update: function(obj, from, to, percent) {
                var centerX = (from.x + to.x) / 2;
                var centerY = (from.y + to.y) / 2;

                var h = centerY - from.y;
                var w = from.x - centerX;

                var dist = Math.sqrt(h * h + w * w);

                if (w == 0) {
                    if (h > 0)
                        var initAngle = -Math.PI / 2;
                    else
                        var initAngle = Math.PI / 2;
                }
                else {
                    var atan = Math.atan(h / Math.abs(w));
                    if (w > 0)
                        var initAngle = atan;
                    else {
                        var initAngle = Math.PI - atan;
                    }
                }

                if (clockwise)
                    var addAngle = -percent * Math.PI;
                else
                    var addAngle = percent * Math.PI;

                var angle = initAngle + addAngle;

                var x = Math.floor(centerX + dist * Math.cos(angle));
                var y = Math.floor(centerY - dist * Math.sin(angle));

                obj.setPosition(x, y);
            },

            current: function(obj) {
                var left = parseInt(obj.style.marginLeft);
                var top = parseInt(obj.style.marginTop);
                var x = left + obj.halfWidth;
                var y = top + obj.halfHeight;
                return new Pos(x, y);
            }
        }
    },

    /*! public
    Follows a circular path through target then back to start
    Params:
    -clockwise : True for clockwise, false otherwise
    */
    positionCircle: function(clockwise) {
        return {
            update: function(obj, from, to, percent) {
                var centerX = (from.x + to.x) / 2;
                var centerY = (from.y + to.y) / 2;

                var h = centerY - from.y;
                var w = from.x - centerX;

                var dist = Math.sqrt(h * h + w * w);

                if (w == 0) {
                    if (h > 0)
                        var initAngle = -Math.PI / 2;
                    else
                        var initAngle = Math.PI / 2;
                }
                else {
                    var atan = Math.atan(h / Math.abs(w));
                    if (w > 0)
                        var initAngle = atan;
                    else {
                        var initAngle = Math.PI - atan;
                    }
                }

                if (clockwise)
                    var addAngle = 2 * percent * Math.PI;
                else
                    var addAngle = -2 * percent * Math.PI;

                var angle = initAngle + addAngle;

                var x = Math.floor(centerX + dist * Math.cos(angle));
                var y = Math.floor(centerY + dist * Math.sin(angle));

                obj.setPosition(x, y);
            },

            current: function(obj) {
                var left = parseInt(obj.style.marginLeft);
                var top = parseInt(obj.style.marginTop);
                var x = left + obj.halfWidth;
                var y = top + obj.halfHeight;
                return new Pos(x, y);
            }
        }
    },

    //public
    top: {
        update: function(obj, from, to, percent) {
            obj.style.top = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'top'));
        }

    },

    //public
    right: {
        update: function(obj, from, to, percent) {
            obj.style.right = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'right'));
        }
    },

    //public
    bottom: {
        update: function(obj, from, to, percent) {
            obj.style.bottom = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'bottom'));
        }
    },

    //public
    left: {
        update: function(obj, from, to, percent) {
            obj.style.left = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'left'));
        }
    },

    //public
    margin: {
        update: function(obj, from, to, percent) {
            obj.style.margin = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'margin'));
        }
    },

    //public
    marginTop: {
        update: function(obj, from, to, percent) {
            obj.style.marginTop = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'marginTop'));
        }
    },

    //public
    marginRight: {
        update: function(obj, from, to, percent) {
            obj.style.marginRight = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'marginRight'));
        }
    },

    //public
    marginBottom: {
        update: function(obj, from, to, percent) {
            obj.style.marginBottom = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'marginBottom'));
        }
    },

    //public
    marginLeft: {
        update: function(obj, from, to, percent) {
            obj.style.marginLeft = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'marginLeft'));
        }
    },

    //public
    padding: {
        update: function(obj, from, to, percent) {
            obj.style.padding = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'padding'));
        }
    },

    //public
    paddingTop: {
        update: function(obj, from, to, percent) {
            obj.style.paddingTop = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'paddingTop'));
        }
    },

    //public
    paddingRight: {
        update: function(obj, from, to, percent) {
            obj.style.paddingRight = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'paddingRight'));
        }
    },

    //public
    paddingBottom: {
        update: function(obj, from, to, percent) {
            obj.style.paddingBottom = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'paddingBottom'));
        }
    },

    //public
    paddingLeft: {
        update: function(obj, from, to, percent) {
            obj.style.paddingLeft = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'paddingLeft'));
        }
    },

    //public
    borderWidth: {
        update: function(obj, from, to, percent) {
            obj.style.borderWidth = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'borderWidth'));
        }
    },

    //public
    borderTopWidth: {
        update: function(obj, from, to, percent) {
            obj.style.borderTopWidth = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'borderTopWidth'));
        }
    },

    //public
    borderRightWidth: {
        update: function(obj, from, to, percent) {
            obj.style.borderRightWidth = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'borderRightWidth'));
        }
    },

    //public
    borderBottomWidth: {
        update: function(obj, from, to, percent) {
            obj.style.borderBottomWidth = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'borderBottomWidth'));
        }
    },

    //public
    borderLeftWidth: {
        update: function(obj, from, to, percent) {
            obj.style.borderLeftWidth = jsAnimUtil.interp(from, to, percent) + "px";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'borderLeftWidth'));
        }
    },

    //public
    fontSize: {
        update: function(obj, from, to, percent) {
            obj.style.fontSize = jsAnimUtil.interp(from, to, percent) + "pt";
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'fontSize'));
        }
    },

    //public
    height: {
        update: function(obj, from, to, percent) {
            var v = jsAnimUtil.interp(from, to, percent);

            obj.style.height = v + "px";

            //Update the position if registered
            if (obj.positionRegistered) {
                var y = parseInt(obj.style.marginTop) + obj.halfHeight;
                obj.halfHeight = Math.floor(obj.offsetHeight / 2);
                obj.style.marginTop = y - obj.halfHeight + "px";
            }
        },

        current: function(obj) {
            var ht = jsAnimUtil.getCSS(obj, 'height');
            if (ht == "auto")
                return obj.offsetHeight;
            else
                return parseInt(ht);
        }
    },

    //public
    width: {
        update: function(obj, from, to, percent) {
            var v = jsAnimUtil.interp(from, to, percent);

            obj.style.width = v + "px";

            //Update the position if registered
            if (obj.positionRegistered) {
                var x = parseInt(obj.style.marginLeft) + obj.halfWidth;
                obj.halfWidth = Math.floor(obj.offsetWidth / 2);
                obj.style.marginLeft = x - obj.halfWidth + "px";
            }
        },

        current: function(obj) {
            return parseInt(jsAnimUtil.getCSS(obj, 'width'));
        }
    },

    //public
    dimension: {
        update: function(obj, from, to, percent) {
            var h = jsAnimUtil.interp(from.h, to.h, percent);
            var w = jsAnimUtil.interp(from.w, to.w, percent);

            obj.style.height = h + "px";
            obj.style.width = w + "px";

            //Update the position if registered
            if (obj.positionRegistered) {
                var y = parseInt(obj.style.marginTop) + obj.halfHeight;
                obj.halfHeight = Math.floor(obj.offsetHeight / 2);
                obj.style.marginTop = (y - obj.halfHeight) + "px";

                var x = parseInt(obj.style.marginLeft) + obj.halfWidth;
                obj.halfWidth = Math.floor(obj.offsetWidth / 2);
                obj.style.marginLeft = (x - obj.halfWidth) + "px";
            }
        },

        current: function(obj) {
            var ht = jsAnimUtil.getCSS(obj, 'height');
            if (ht == "auto")
                var h = obj.offsetHeight;
            else
                var h = parseInt(ht);
            var w = parseInt(jsAnimUtil.getCSS(obj, 'width'));
            return new Dim(w, h);
        }
    },

    //public
    color: {
        update: function(obj, from, to, percent) {
            r = jsAnimUtil.interp(from.r, to.r, percent);
            g = jsAnimUtil.interp(from.g, to.g, percent);
            b = jsAnimUtil.interp(from.b, to.b, percent);

            obj.style.color = "rgb(" + r + "," + g + "," + b + ")";
        },

        current: function(obj) {
            var color = jsAnimUtil.getCSS(obj, 'color');
            color = color.substring(4, color.length - 1);
            var rgb = jsAnimUtil.explode(",", color);
            return new Col(parseInt(rgb[0]), parseInt(rgb[1]), parseInt(rgb[2]));
        }
    },

    //public
    backgroundColor: {
        update: function(obj, from, to, percent) {
            r = jsAnimUtil.interp(from.r, to.r, percent);
            g = jsAnimUtil.interp(from.g, to.g, percent);
            b = jsAnimUtil.interp(from.b, to.b, percent);

            obj.style.backgroundColor = "rgb(" + r + "," + g + "," + b + ")";
        },

        current: function(obj) {
            var color = jsAnimUtil.getCSS(obj, 'backgroundColor');
            color = color.substring(4, color.length - 1);
            var rgb = jsAnimUtil.explode(",", color);

            return new Col(parseInt(rgb[0]), parseInt(rgb[1]), parseInt(rgb[2]));
        }
    },

    //public
    borderColor: {
        update: function(obj, from, to, percent) {
            r = jsAnimUtil.interp(from.r, to.r, percent);
            g = jsAnimUtil.interp(from.g, to.g, percent);
            b = jsAnimUtil.interp(from.b, to.b, percent);

            obj.style.borderColor = "rgb(" + r + "," + g + "," + b + ")";
        },

        current: function(obj) {
            var color = jsAnimUtil.getCSS(obj, 'borderColor');
            color = color.substring(4, color.length - 1);
            var rgb = jsAnimUtil.explode(",", color);
            return new Col(parseInt(rgb[0]), parseInt(rgb[1]), parseInt(rgb[2]));
        }
    },

    //public
    opacity: {
        update: function(obj, from, to, percent) {
            v = jsAnimUtil.interp(100 * from, 100 * to, percent);
            obj.style.opacity = v / 100;
        },

        current: function(obj) {
            return jsAnimUtil.getCSS(obj, 'opacity');
        }
    }
}
//************************************************************************
// END - JS Animation
//************************************************************************
