﻿// reference http://msdn.microsoft.com/en-us/library/bb259689.aspx
var VETileSys = {    
    EarthRadius : 6378137,
    MinLatitude : -85.05112878,
    MaxLatitude : 85.05112787,
    MinLongitude : -180,
    MaxLongitude : 180,  
    
    Clip : function(n, minValue, maxValue) {
        return Math.min(Math.max(n, minValue), maxValue );
    },
    
    MapSize : function(lvl) {
        return 256 << lvl;
    },

    GroundResolution : function(lat, lvl) {
        lat = VETileSys.Clip(lat, VETileSys.MinLatitude, VETileSys.MaxLatitude);
        return Math.cos(lat * Math.PI / 180 ) * 2 * Math.PI * VETileSys.EarthRadius / VETileSys.MapSize(lvl);
    },
    
    MapScale : function(lat, lvl, dpi) {
        return VETileSys.GroundResolution(lat, lvl) * dpi / 0.0254;
    },
    

    LatLongToPixelXY : function(lat, lng, lvl, outPixelXY) {
        lat = VETileSys.Clip(lat, VETileSys.MinLatitude, VETileSys.MaxLatitude);
        lng = VETileSys.Clip(lng, VETileSys.MinLongitude, VETileSys.MaxLongitude);
        
        var x = ( lng + 180 ) / 360;
        var sinLat = Math.sin( lat * Math.PI / 180 );
        var y = 0.5 - Math.log((1 + sinLat ) / ( 1 - sinLat )) / (4*Math.PI);
        var mapsize = VETileSys.MapSize(lvl);
        outPixelXY.x = Math.round(VETileSys.Clip(x * mapsize + 0.5, 0, mapsize - 1));
        outPixelXY.y = Math.round(VETileSys.Clip(y * mapsize + 0.5, 0, mapsize - 1));
    },
    
    PixelXYToTileXY : function(px, py, outTile) {
        outTile.x = Math.floor(px / 256);
        outTile.y = Math.floor(py / 256);
    },

    TileXYToQuadKey : function(tx, ty, lvl) {
        var qkey = "";
        for ( var i = lvl; i > 0 ; i--) {
            var digit = 0;
            var mask = 1 << (i - 1);
            if ( (tx & mask) != 0 ) {
                digit++;
            }
            if ( (ty & mask) != 0 ) {
                digit++; digit++;
            }
            qkey += digit;
        }
        return qkey;
    },
    
    GetInfo : function(lat, lng, lvl, out) {
        out.p = {x:0, y:0};
        out.t = {x:0, y:0};
        VETileSys.LatLongToPixelXY(lat, lng, lvl, out.p);
        VETileSys.PixelXYToTileXY(out.p.x, out.p.y, out.t);
    },
    
    GetTile : function( qkey ) {
        return "http://t1.tiles.virtualearth.net/tiles/r" + qkey + ".png?g=159";
    }
}; // end VETileSys

var VESmallMap = {
    GetMap : function(lat, lng, lvl, div) {
        // get the height and width from div
        div = $(div);
        var dim = { w: div.width(), h: div.height() };
    
        // get the info from tile system first
        var info = {};
        VETileSys.GetInfo(lat, lng, lvl, info);
        
        // the coordinate to inside the tile it resides on
        info.cp = { x: info.p.x % 256, y: info.p.y % 256 }; 
        //console.log( info.cp );
        
        // now, assume info.p is the point at the center 
        // within div, now calculate the offset relative to div
        // for the tile for the upper left corner,
        // 0,0 at the top left corner
        info.tileOffset = { 
            // half the the width - the x offset within the tile
            x1: Math.floor(dim.w / 2 - info.cp.x),
            // half of the height - the height of the point with the tile
            y1: Math.floor(dim.h / 2 - info.cp.y)
        };
        // the coordinerate of the lower right corner
        info.tileOffset.x2 = info.tileOffset.x1 + 256;
        info.tileOffset.y2 = info.tileOffset.y1 + 256;        
        //console.log( info.tileOffset );
        
        // so how many tiles on the left are needed
        var left = Math.ceil(info.tileOffset.x1 / 256);
        // how many tiles on the right are needed
        var right = Math.ceil( (dim.w - info.tileOffset.x2 )/ 256 );
        // how many tiles on the top are needed
        var top = Math.ceil( info.tileOffset.y1 / 256 );
        // how mnay tiles on the bottom are needed
        var bottom = Math.ceil( ( dim.h - info.tileOffset.y2 ) / 256 );
        
        // now we know we know how many tiles we need to get    
        for ( var x = -left; x <= right; x++ ) {
            for ( var y = -top; y <= bottom; y++ ) {
                var img = document.createElement("img");
                img.src = VETileSys.GetTile( VETileSys.TileXYToQuadKey( info.t.x + x, info.t.y + y, lvl ) );
                img = $(img);
                img.css("top",  256 * y + info.tileOffset.y1 );
                img.css("left", 256 * x + info.tileOffset.x1 );
                img.css("position", "absolute");
                img.css("z-index", "1");
                div.append(img);
            }
        }
        
        // add the pin to the center
        var img = document.createElement("img");
        img.src = "/image/vemap/star_icon.gif";
        img = $(img);
        img.css("top", Math.floor(dim.h / 2 - 31));
        img.css("left", Math.floor(dim.w / 2 -20.5) );
        img.css("position", "absolute");
        img.css("z-index", "2");
        div.append(img);
        
        
    } // end GetMap
}; // end VESmallMap

function getNearByUrl() { 
    var secs = document.forms[0].sec; 
    if (secs[secs.length-1].checked && trim(document.forms[0].ename.value + '') == '') 
        return; 
        
    for (i = 0; i < secs.length; i++) { 
        if (secs[i].checked) { 
            sec = secs[i].value; 
            if (sec == 'oth') 
                window.location = '/search/find.aspx?secid=1&name=' + 
                document.forms[0].ename.value.toString().strip() + 
                '&area=r-54294&sort=distance'; 
            else window.location = 'whats_nearby.aspx?sec=' + sec; 
        }
    }
};

// variable to hold the NycVEMap object in record detail pages
var VERdMap = {
    map : null,
    
    getMap : function(mapDivID, lat, lon, zoom, title, desc, routeDivID, callback) {
        VERdMap.map = new NycVEMap(mapDivID, lat, lon, zoom, title, desc, routeDivID);
        VERdMap.map.getMap(callback);
    }
};

// map_location.aspx
var VEDirMap = {
    mapDivID : "dirMap",
    routeDivID : "routeHolder",
    zoom : 15,
    
    getMap : function(lat, lon, title, desc) {
        VERdMap.getMap(VEDirMap.mapDivID, lat, lon, VEDirMap.zoom, title, desc, VEDirMap.routeDivID);
    },
    
    getDir : function() {
        var fa = $("input:text[name=fa]");
        var fc = $("input:text[name=fc]");
        var fs = $("input:text[name=fs]");
        var fz = $("input:text[name=fz]");
        var fct = $("select[name=fct]");
        var ta = $("input:text[name=ta]");
        var tc = $("input:text[name=tc]");
        var ts = $("input:text[name=ts]");
        var tz = $("input:text[name=tz]");
        var tct = $("select[name=tct]");
        var drt = $("input:radio[name=drt]:checked");
        var du = $("input:radio[name=du]:checked");
        var rt = $("input:radio[name=rt]:checked");
        
        var start = fa.val() + ", " + fc.val() + ", " + fs.val() + " " + fz.val() + ", " + fct.val();
        var end = ta.val() + ", " + tc.val() + ", " + ts.val() + " " + tz.val() + ", " + tct.val();
        var isInMiles = (du.val() == "miles");
        var isQuickest = (rt.val() == "quick");
        var isDriving = (drt.val() == "driving");
        
        $("#dirMapTitle").text( (isDriving ? "Driving Directions" : "Walking Directions") );
        
        VERdMap.map.getRoute(start, end, isInMiles, isQuickest, isDriving);
    }
};

// whats_nearby.aspx                                  
var VENearbyMap = {
    recordID: null,
    sectionID: null,
    mapDivID : "nearbyMap",
    zoom : 17,     
    
    init : function(sectionID, recordID, lat, lon, title, desc) {
        VENearbyMap.sectionID = sectionID;
        VENearbyMap.recordID = recordID;
        VERdMap.getMap(VENearbyMap.mapDivID, lat, lon, VENearbyMap.zoom, title, desc, null, 
            function() { // callback after getMap()
                WhatsNearbySearch.init(VERdMap.map);
                
                var defaultsec = location.search.match(/[&\?]sec=([^&]{3})/i);
                var secs = document.getElementsByName('sec');
                if ( defaultsec ) {
					// has default value from url
					for ( var i =0; i < secs.length;i++ ) {
						if ( secs[i].value == defaultsec[1] ) {
							secs[i].checked = true;
							break;
						}
					}
                } else {
					for (i = 0; i < secs.length; i++)  {
						if ((secs[i].value == 'bar' && sectionID == 6) || 
							(secs[i].value == 'res' && sectionID != 6)) {
							secs[i].checked = true;
							break;
						}
					}
				}
                
                VENearbyMap.getNearby();
            } 
        );
    },
    
    getNearby : function() {
        var secs = document.getElementsByName('sec');
        
        for (i = 0; i < secs.length; i++) 
        {
            if (secs[i].checked) 
            {
                var sec = secs[i].value;
                WhatsNearbySearch.search(VENearbyMap.sectionID, VENearbyMap.recordID, sec);                
            }
        }
    }
};

var RDetail = {
    GoRecord : function(select,asid) {
        var baseUrl;
        // movie theater actual section id is 28
        var pageName = ( asid == 28 ? "/movies_and_times.aspx" : (asid == 29 ? "/synopsis.aspx" : "/editorial_review.aspx") );
        var val = select.options[select.selectedIndex].value;
        
        if ( val == "" )
            return "";
        if ( asid == 28 ) baseUrl = "/movies/theater/";
        else if ( asid == 29) baseUrl = "/movies/title/";
        else baseUrl = location.pathname.substring(0, location.pathname.indexOf('/',1 ) +1 );
                
        window.location = baseUrl + select.options[select.selectedIndex].text.toAlphaNumeric()
                    + "." + val + pageName;
    },
    SwitchImg : function(imgSrc) {
        $("#TopImageBig").css("background-image", "url('" + imgSrc + "')");
    },
    renderPopPhotos : function() {
        var t = [];
	    
	    t.push("<br /><center>");
        if (popPhotoUrls && popPhotoUrls.length > 0) {
            for (idx = 0; idx < popPhotoUrls.length; idx++) {
                var thumb = popPhotoUrls[idx];
                var bigPhoto = popPhotoUrls[idx].replace(/tn\//g,"");
    	                    
                t.push("<img border='0' style='margin:2px;' onmouseover=\"document.getElementById('activeImg').style.backgroundImage=");
                    t.push("'url(" + bigPhoto + ")'\"");
                    t.push(" src='" + thumb + "' />");
            }
            t.push("<br /><br />");
            t.push("<div id='activeImg' style='width: 550px; height: 300px; background-color:#ffffff; ");
                t.push("background-image: url(" + popPhotoUrls[0].replace(/tn\//g,"") + "); ");
                t.push("background-position: center center; background-repeat: no-repeat;'></div>");
        } else {
            t.push("<br /><br /><b>No photos are available with this broadway show.</b><br /><br />");
        }
        t.push("</center>");
        
        NycHotelPopup.popText(t.join(''),"Photo Gallery");
    }
};

var ListTag = {
    tagDefault : "Separate each tag with a comma.",
    recordid : 0,
    recordname : "",
    sectionid : 0,
    userBaseUrl : "",
    whatsTag : "You can TAG any business or event you find on NYC.com. A tag is like a " +
	            "personal keyword or category label. So with tags, you can label what " +
	            "interests you on NYC.com with words that make sense to you. Your tags " + 
	            "can then be used to help you share, store and organize this information. " +
	            "For example, you could tag a Japanese restaurant you like with \"great " + 
	            "sushi,\" \"delicious,\" \"expensive,\" \"downtown.\" In the future, if you're in the " + 
	            "mood for great sushi, you can easily find any restaurant fast that you tagged " +
	            "\"great sushi.\" Or if you're looking for a restaurant downtown, just " +
	            "search with \"downtown.\" What's more, you can also see all the records everyone " +
	            "else has tagged \"great sushi\" or \"downtown\" at NYC.com.<br/><br/> " +
	            "This is different than a normal search, because it shows you what the " +
	            "users at NYC.com are thinking about and reviewing. TAGS are a great resource " +
	            "for finding out what's going on, what's hot, what people are talking about. " +
	            "Some rise and others fall in importance, depending on how the tag is being used.<br/><br/> " +
	            "So why use TAGS?<br/> 1. Tags keep found things found. Tags make it easy for you to find " +
	            "businesses or events again, using the terms you use to describe them. " + 
	            "If you can't remember the name of that great French bistro you went to " +
	            "four months ago, just click on your FRENCH tag, and there it is!<br/><br/> " +
	            "2. Tags let you find things using other users' language. We might " +
	            "tag a restaurant as FRENCH, but someone else might tag it as PARIS CHEF. " + 
	            "And you can see the most popular tags on NYC.com by visiting " +
	            "<a class=\"boldGrey\" href=\"/tags/\">http://www.nyc.com/tags/</a> - " +
	            "the size of each link shows how many records " +
	            "are tagged with that word or phrase. The bigger the word, the bigger " +
	            "and more powerful the tag!<br/><br/> " +
	            "3. Tags let you visualize your NYC and see how others see it.",
	
    init : function(sid,rid,rname,userurl) {
        ListTag.sectionid = sid;
        ListTag.recordid = rid;
        ListTag.recordname = rname;
        ListTag.userBaseUrl = userurl;
    }, // end init
    
    validateTag : function(tagtext) {
        var objregexp = /^[\sa-zA-Z0-9,]*$/
		
		if (!tagtext.match(objregexp) || tagtext == ListTag.tagDefault)
		{
			alert("Please tag with simple keyword(s) contain only alphabets and numerics!");
			return false;
		}
		return true;
    }, // end validateTag
    
    addTags : function() {
        var newtagtext = $("#tagForm input[type=text]").val().strip();
        var sharetagswith = $("#tagForm input[name=isprivate][checked]").val();
        
        if (ListTag.validateTag(newtagtext)) {
            LoadingMask.show();
            $.post("post.nyc",{_ns:"ListTag",_a:1,_m:"AddTags",sid:ListTag.sectionid,rid:ListTag.recordid,
                rname:ListTag.recordname,tagtext:newtagtext,isp:sharetagswith},
                function(res) { LoadingMask.hide(); ListTag.updateTagList(res); ListTag.showTagForm(false); }, "json");
        }
    }, // end addTags
    
    showWhatsTag : function() {
        var h = [];
        h.push("<div style='padding:10px; text-align:left;'>");
            h.push(ListTag.whatsTag);
        h.push("</div>");
        
        ModalPopup.showBox(h.join(''), "What's Tag?");
    },
    
    deleteTag : function(tagid) {
        if (window.confirm("Are you sure you want to delete this tag?")) {
            LoadingMask.show();
            
            $.post("post.nyc",{_ns:"ListTag",_a:1,_m:"DeleteTag",tid:tagid,rid:ListTag.recordid},
                function(res) { LoadingMask.hide(); ListTag.updateTagList(res); }, "json");
        }
    }, // end deleteTag
    
    updateTagList : function(result) {
        if (result != null && result.tags != null) {
            var h = [];
            
            if (result.tags.length > 0)
                h.push("<span class='listHead'>Your Tags:</span>");   
            
            for (idx = 0; idx < result.tags.length; idx++) {
                h.push("<span class='tag'>");
                    h.push("<a href='" + ListTag.userBaseUrl + "tags.aspx?tag=" + escape(result.tags[idx].tagtext) + "'>");
                        h.push(result.tags[idx].tagtext);h.push("</a> ");
                    h.push("<a href='javascript://remove tag' onclick='ListTag.deleteTag(" + result.tags[idx].tagid + ");'>[ X ]</a>");
                h.push("</span> ");
            }
            
            $("#rdTagList").html(h.join(''));
        }
    }, // end updateTagList
    
    validateList : function(select,textbox) {
        if (select.val() == -1 && textbox.val() == "") {
			alert("Please enter the name of the new list.");
			textbox.focus();
			return false;
		}
		return true; 
    }, // end validateList
    
    addToList : function() {
        var textbox = $("#listForm input[type=text]");
        var select = $("#listForm select");
        
        if (ListTag.validateList(select,textbox)) {
            LoadingMask.show();
            
            $.post("post.nyc",{_ns:"ListTag",_a:1,_m:"AddToList",sid:ListTag.sectionid,rid:ListTag.recordid,
                rname:ListTag.recordname,lid:select.val(),lname:textbox.val()},
                function(res) { LoadingMask.hide(); ListTag.updateDropDown(res);  ListTag.showListForm(false); }, "text");
        }
    }, // end addToList
    
    updateDropDown : function(listid) {
        // update drop
        if (!isNaN(listid) && listid > 0) {
            var newlistname = $("#listForm input[type=text]").val();
            var newOption = "<option value='" + listid + "'>" + newlistname + "</option>";
            var isAdded = false;
            
            $("#listForm select option").each(function(o) {
                if (isAdded) return;
                
                var opt = $(this);
                
                if (opt.text() > newlistname) {
                    console.log(opt.text());
                    opt.before(newOption);
                    isAdded = true;
                }
            } );
            
            if (!isAdded) $("#listForm select").append(newOption);
        }
    }, // end updateList
    
    showTagForm : function(isShown) {
        $(".listTagForm").hide();
        
        if (isShown) $("#tagForm").show();
    }, // end showTagForm
    
    showListForm : function(isShown) {
        $(".listTagForm").hide();
        
        if (isShown) $("#listForm").show();
    } // end showListForm
}; // end ListTag

