var b_version = navigator.appVersion;
var isIE6 = b_version.search(/MSIE 6/i) != -1;
var isIE7 = b_version.search(/MSIE 7/i) != -1;
var isSafari20 = b_version.search(/412.2.2/i) != -1;
var isMacintosh = b_version.search(/Macintosh/i) != -1;
var isSafari3 = b_version.search(/applewebkit\/5/i) != -1;
var isSafari = b_version.search(/applewebkit/i) != -1;
var isSafari2 = isSafari && !isSafari3;
var IEquirks = b_version.search(/MSIE/i) != -1;
var NS = {
    rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#",
    dc: "http://purl.org/dc/elements/1.1/",
    cc: "http://web.resource.org/cc/",
    vcard: "http://www.w3.org/2001/vcard-rdf/3.0#",
    georss: "http://www.georss.org/georss/",
    schmap: "http://www.schmap.com/xml/schmapplet#",
    findme: "http://www.schmap.com/xml/findme#",
    atom: "http://www.w3.org/2005/Atom",
    none: ''
};

// this doesn't so much need to be a function, it's here for readability
function idiv(a, b) {
    return (a-(a%b))/b;
}

function elementOverlapsV(element, top, bottom) {
    var pos = getElementPosition(element);
    if(pos.y > bottom) return false;
    var dim = getElementDimensions(element);
    if((pos.y + dim.h) < top) return false;
    return true;
}

function logException(err, context) {
    context = context || '';
    if(err.fileName && err.lineNumber)
        logError(context + err + ' on ' + err.fileName + ':' + err.lineNumber);
    else
        logError(context + repr(err) + ':' + err.message);
}

function err_logging(f) {
    return function() {
        try {
            //logDebug("this in err_logging:" + this);
            //logDebug("apply f:" + f.toString());
            f.apply(this, arguments);
        } catch(err) {
            logException(err);
            //throw(err);
        }
    };
}

function dataFailure(what, err) {
    alert('There was an error loading the ' + what +
          '.  Please try again in a few minutes.');
}

function PNG_html(attrs) {
    var img = new StringBuffer();
    var src = attrs.src;
    if(IEquirks)
        attrs.src = '/common/spacer.png';
    img.append('<img ');
    if(attrs.id)
        img.append('id="').append(attrs.id).append('" ');
	if(attrs.thisClass)
		img.append('class="').append(attrs.thisClass).append('" ');
    img.append('src="').append(attrs.src);
    img.append('" width="').append(attrs.width).append('" height="').append(attrs.height).append('"/>');
    if(IEquirks) {
        var img = new StringBuffer();
        img.append('<IMG ');
        if(attrs.id)
            img.append('id="').append(attrs.id).append('" ');
        img.append(' style="').append("FILTER: progid:DXImageTransform.Microsoft.AlphaImageLoader(src='");
        img.append(src).append("',sizingMethod='scale'); WIDTH: ").append(attrs.width);
        img.append("px; HEIGHT: ").append(attrs.height).append("px");
		if(attrs.thisClass)
			img.append('" class="').append(attrs.thisClass);
        img.append('" src="/images/pageicons/spacer.png">');
    }
    return img.toString();
}

function PNG(attrs) {
    var src = attrs.src;
    if(schmapplet.IEquirks)
        attrs.src = '/images/pageicons/spacer.png';
    img = MochiKit.DOM.IMG(attrs);
    var filter = new StringBuffer();
    if(schmapplet.IEquirks) {
        setElementDimensions(img, {h: attrs.height, w: attrs.width});
        filter.append("progid:DXImageTransform.Microsoft.").append("AlphaImageLoader(src='").append(src).append("',sizingMethod='scale')");
        img.style.filter = filter.toString();
    }
    return img;
}

function PNGck(attrs) { //PNG check
    var src = attrs.src;
	var isPNG = (src.toLowerCase().search('.png')!==-1);
	    if(schmapplet.IEquirks&&isPNG)
        attrs.src = '/images/pageicons/spacer.png';
    img = MochiKit.DOM.IMG({src:attrs.src});
    var filter = new StringBuffer();
    if(schmapplet.IEquirks&&isPNG) {
        setElementDimensions(img, {h: attrs.height, w: attrs.width});
        filter.append("progid:DXImageTransform.Microsoft.").append("AlphaImageLoader(src='").append(src).append("',sizingMethod='scale')");
        img.style.filter = filter.toString();
    }
    return img;
}

function setTextTrimmed(element, text, limit) {
    element = $(element);
    element.title = text;
    replaceChildNodes(element, text);
    text += '...';
    while(element.scrollWidth > limit) {
        text = text.substr(0, text.length - 8) + '...';
        replaceChildNodes(element, text);
    }
}

function PlaceObj(node) {
	if (node) {
    //logDebug("start building node", node);
    this.id = xmlAccess.getAttributeNS(node, "rdf", "ID");
    //logDebug("id:" + this.id);
    this.name = xmlAccess.getSingleChildText(node, "dc:title");
    //logDebug("name:" + this.name);
    this.sdesc = xmlAccess.getSingleChildText(node, 'dc:description');
    //logDebug("sdesc:" + this.sdesc);
	var ldescNode = xmlAccess.getFirstChild(node, 'schmap:text');
	this.ldesc = xmlAccess.getCData(ldescNode);
	if(this.ldesc == ''){
        this.ldesc = xmlAccess.getSingleChildText(node, 'schmap:text');
	}
	if(this.ldesc!=''){
	schmapplet.hasStats = true;
	}
    this.schmapIcon = xmlAccess.getSingleChildText(node, 'schmap:icon');
    this.normalMapIcon = xmlAccess.getSingleChildText(node, 'schmap:icon');
    //logDebug("ldesc:" + this.ldesc);
    this.rating = Number(xmlAccess.getSingleChildText(node, 'schmap:rating'));
    this.featured = Number(xmlAccess.getSingleChildText(node, 'schmap:featured'));
    this.email = xmlAccess.getSingleChildText(node, 'vcard:EMAIL');

    // 0 - not sticky place
    // 1 - normal sticky places defined in place.xml
    // 2 - sticky places added by user via url
    this.stickyPlaceType = 0;
    var stickyPlace = xmlAccess.getFirstChild(node, 'schmap:StickyPlace');
    if (stickyPlace != null) {
        this.stickyPlaceType = 1;
    }
    
    //logDebug("email:", this.email);
    var urlFirst = xmlAccess.getSingleChildText(node, 'vcard:URL');
    
    url=urlFirst.split(' ');
    if(url.length== 1){
        this.url=url[0];
        this.urlText = this.url.replace(/^.*?\/\/(.+)$/, '$1')
            .replace(/^(.*)\/+$/, '$1');
        this.extra_url = false;     
    }else{
        this.url=url[url.length-1];
        this.urlText=urlFirst.replace(this.url,'');
        this.extra_url = true;
    }
    this.tel = [];
    //logDebug("url:", this.url);
    this.url_munged = this.url.replace(/^.*?\/\/(.+)$/, '$1')
        .replace(/^(.*)\/+$/, '$1');

    //logDebug("url_munged:", this.url_munged);
    var phones = xmlAccess.getChildren(node, 'vcard:TEL');
    try {
        do {
            var phone = phones.next();
            var value = xmlAccess.getSingleChildText(phone, 'rdf:value');
            if(value !='')
            this.tel.push(value);
        } while(phone)
    } catch (e) {};
    var additionalLink1 = xmlAccess.getChildren(node, 'schmap:additionalLink1');
    this.additonalLink1 = '';
    try{
    var additional = additionalLink1.next();
    }catch(e){
        }
        if( additional) {
            this.additonalLink1 = {};
            var linkName = xmlAccess.getSingleChildText(additional, 'vcard:label');
            var value = xmlAccess.getSingleChildText(additional, 'rdf:value');
            this.additonalLink1.name = linkName;
            this.additonalLink1.linkValue = value;  
        }
    //logDebug("this.tel:" + this.tel);
    this.geo = xmlAccess.getSingleChildText(node, 'vcard:GEO').split(/ /);
    // logDebug("this.geo:" + this.geo);
    this.addr1 = xmlAccess.getSingleChildText(node, 'vcard:ADR/vcard:Street');
    this.addr2 = xmlAccess.getSingleChildText(node, 'vcard:ADR/vcard:Extadd');
    this.city = xmlAccess.getSingleChildText(node, 'vcard:ADR/vcard:Locality');
    this.staduimDetails = xmlAccess.getSingleChildText(node, 'vcard:ADR/vcard:StaduimDetails');
    this.region = xmlAccess.getSingleChildText(node, 'vcard:ADR/vcard:Region');
    this.zip = xmlAccess.getSingleChildText(node, 'vcard:ADR/vcard:Pcode');
    //logDebug("my place entry:" + this.zip);
    
	}
}

function scalify(number) {
    if (number >= 450) {
        return Math.round(number / 100) / 10 + "K";
    } else {
        return Math.round(number / 100) * 100;
    }
}

function parse_colorset(text) {
    ctext = text.replace(/\s/g, '');
    colors = [null];
    while(ctext) {
        colors.push(ctext.substring(0, 6));
        ctext = ctext.substring(6);
    }
    return colors;
}


function apply_colorset(colorset, template, stylesheet) {
    /* this is a bit slow, but can't be optimised much due to how
       brokenly browsers implement css manipulation */
    while(colorset.length < 19) {
        //logDebug("colorset.length:" + colorset.length);
        colorset.push(null);
    }
    var templateLen = template.length;
    var sheetLen = document.styleSheets.length ;
    for(var i = 0; i < sheetLen; i++) {
        var thisSheet = document.styleSheets[i];
        var s = thisSheet;
        if(!s.href.match(stylesheet)) continue;

        var rules = s.cssRules || s.rules;
    if(!schmapplet.stylesheets) 
        schmapplet.stylesheets = rules;
        
    var rulesLen = rules.length;
        for(var i2 = 0; i2 < rulesLen; i2++) {
            var r = rules[i2];
            var st = r.selectorText;
        //logDebug("colorset: rules selector:", r.selectorText);
            for(var i3 = 0; i3 < templateLen; i3++) {
                var crs = template[i3];
                var crs0 = crs[0];
                if(!st.match(crs0)) {
                   continue;
        }
        //logDebug("colorset: matched rule selector:", r.selectorText);
        crsLen = crs.length;
                for(var i4 = 1; i4 < crsLen; i4++) {
                    var cr = crs[i4];
                    var cr0 = cr[0];
                    var cr1 = cr[1];
                    var rStyle = r.style;
                    if(rStyle[cr0] && colorset[cr1]) {
                    
                        try {
                            rStyle[cr0] = '#' + colorset[cr1];
                            //logDebug('colorset: consumed', crs[0], cr[0], cr[1], colorset[cr[1]]); NPF
                        } catch(e) {
                            logDebug('colorset: failed to apply', crs[0], cr[0],
                                     repr(colorset[cr[1]]));
                        }
                        
                   }
                }
            }
        }

        break;
    }
}

function addScript(url,callback,param1,param2) {
    var s = document.createElement("script");
    s.type = "text/javascript";
    s.language = "javascript";
    s.src = url;
	if(callback) {
	    s.onload = partial(callback, param1, param2);
		s.onreadystatechange= function () {
		if (this.readyState == 'loaded'||this.readyState == 'complete') callback(param1, param2);
		}
	}

    logDebug("adding script:", url);
    //document.getElementsByTagName("head")[0].appendChild(s);
	appendChildNodes(document.getElementsByTagName("head")[0],s);	
	if(isSafari2 && callback){
		callLater(3,partial(callback, param1, param2));
	}
}

function getCsurrentGMapUrl() {
    return "http://maps.google.com/maps?file=api&v=2.151&key=" +
        google_api_key + '&async=2&callback=loadedGMap';
}

function getCurrentGMapUrl() {
	var map = map_api_order[0];
	if( map == 'Google'||map == 'Schmap'||map == 'Cgoogle'){
		return "http://maps.google.com/maps?file=api&v=2.151&key=" +google_api_key + '&async=2&callback=loadedGMap'; 
	}else{
		return map_api_src  ;
	}
}

function importGMapUrl() {
    addScript(getCurrentGMapUrl());
}

function loadedGMap() {
    addScript('http://' + document.location.host +
              '/common/lib/MochiMaps__Google.js');
}
function loadedMap() {
    addScript('http://' + document.location.host +
              '/common/lib/MochiMaps__'+map_api_order[0]+'.js');
}
boxManager = {
    boxes: [],
    register: function (box) {
        this.boxes.push(box);
    },
    updateAll: function (content) {
    }
}

reactor = {
    boxManager: boxManager,
    respond: function (content) {}
}

function Nexus(pid) {
    this.placeid = arguments[0];
}

Nexus.prototype.equals = function (onexus) {
    if(this.placeid == onexus.placeid) {
        return 1;
    }
    return 0;
}

function Box() {
    this.items = {};
}

Box.prototype.getItem = function () {};
Box.prototype.addItem = function () {};
Box.prototype.onclick = function () {};
Box.prototype.onmouseover = function () {};
Box.prototype.onmouseout = function () {};

function discardElement(element) {
    var garbageBin = document.getElementById('IELeakGarbageBin');
    if (!garbageBin) {
        garbageBin = document.createElement('DIV');
        garbageBin.id = 'IELeakGarbageBin';
        garbageBin.style.display = 'none';
        document.body.appendChild(garbageBin);
    }

    // move the element to the garbage bin
    garbageBin.appendChild(element);
    garbageBin.innerHTML = '';
}

function StringBuffer() { 
    this.buffer = []; 
}

StringBuffer.prototype.append = function(str) {
    this.buffer.push(str);
    return this;
}

StringBuffer.prototype.toString = function() {
    return this.buffer.join("");
}

StringBuffer.prototype.getLength = function() {
    return this.buffer.length;
}

function concat(arr) {
    return arr.join('');
}

function clearMapLeaks() {
    if(typeof(GUnload) != "undefined") {
        GUnload();
    }
}


function createMap(container) {
    var map;
    var orderLen = map_api_order.length ;
    for(var i = 0; i < orderLen; i++) {
        var thisOrder = map_api_order[i];
        MochiKit.Maps = MochiKit['Maps__' + thisOrder];
        try {
            map = new MochiKit.Maps.Map(container);
            break;
        } catch (e) {
            replaceChildNodes(container);
        }
    }
    return map;
}

function makeIcons(mapapi,map,next,thisone) {
	if(!thisone) thisone  = schmapplet.places.length;
	if(!next) next = 0;
	if(!map) map =schmapplet.map;
	if(!mapapi) mapapi = MochiKit.Maps;
	var mochkitmap = mapapi;
    var userPlaceIconsPath = '/images/minitemplate/usericons/';
    if(schmapplet.nextIconToMake === undefined|| schmapplet.nextIconToMake === null
            || isNaN(schmapplet.nextIconToMake)) {
        logDebug('making icons');
        schmapplet.nextIconToMake = schmapplet.places.length - 1;
    }
    place = schmapplet.places[schmapplet.nextIconToMake];
    mapIconIndex = map.provider + place.schmapIcon;
    var icon = schmapplet.mapIcons[mapIconIndex];
    var icon_big;
    if(typeof(icon) != 'undefined' && icon !== undefined) {
        icon_big = icon[1];
        icon = icon[0];
    } else {
    	var icon_big_path, icon_path;
    	var over_icon_size = [];
    	var normal_icon_size = [];
    	
    	if (place.stickyPlaceType == 2) {
 			icon_big_path = userPlaceIconsPath + place.schmapIcon + '-over.png';
			icon_path = userPlaceIconsPath + place.schmapIcon + '-normal.png';
			over_icon_size[0] = Number(schmapplet.uplace.id.substr(0,2));
			over_icon_size[1] = Number(schmapplet.uplace.id.substr(2,2));
			normal_icon_size[0] = over_icon_size[0];
			normal_icon_size[1] = over_icon_size[1];	
		} else {
			icon_big_path = mapiconspath+place.schmapIcon+'-over.png';
			icon_path = mapiconspath+place.normalMapIcon+'-normal.png';
			over_icon_size[0] = settings.OverIconSize[0];
			over_icon_size[1] = settings.OverIconSize[1];
			normal_icon_size[0] = settings.NormalIconSize[0];
			normal_icon_size[1] = settings.NormalIconSize[1];		
		}
    	
        icon_big = new mochkitmap.Icon(icon_big_path,
                                         new MochiKit.Style.Dimensions(over_icon_size[0], over_icon_size[1]),
                                         new MochiKit.Style.Coordinates(schmapplet.overAnchorX, schmapplet.overAnchorY));

        icon = new mochkitmap.Icon(icon_path,
                                      new MochiKit.Style.Dimensions(normal_icon_size[0], normal_icon_size[1]),
                                      new MochiKit.Style.Coordinates(schmapplet.normalAnchorX, schmapplet.normalAnchorY));
        schmapplet.mapIcons[mapIconIndex] = [icon, icon_big];
    }
    if((place.geo[0].toString().toUpperCase()=='NONE') ||
       (place.geo[1].toString().toUpperCase()=='NONE')) {
        place.geocode = place.marker = place.markerbig = null;
    } else {
        place.geocode = new mochkitmap.Point(place.geo[0], place.geo[1]);
        var bigMarker = new mochkitmap.Marker(place.geocode, icon_big);
        var smallMarker = new mochkitmap.Marker(place.geocode, icon);
        bigMarker.placeid = place.id;
        smallMarker.placeid = place.id;
		map.addItem(smallMarker);
		if(place.marker){
			place.Gmarker = smallMarker;
	        place.Gmarkerbig = bigMarker;
			place.Gmarker.hide();
			place.connectGMarkerSignals(); 
		}else{
	        place.marker = smallMarker;
	        place.markerbig = bigMarker;
			place.connectMarkerSignals();
		}
    }
    if(schmapplet.nextIconToMake--&&!next) {
        if(schmapplet.nextIconToMake % 10) {
            return makeIcons(mochkitmap,map);
        } else {
            callLater(0.001, partial(makeIcons,mochkitmap,map));
        }
    } else {
        callLater(1, function() {
                var i = thisone;
                while(next!==i--) {
                    if(schmapplet.places[i].Gmarkerbig) {
                        map.addItem(schmapplet.places[i].Gmarkerbig);
                        schmapplet.places[i].Gmarkerbig.hide();
                    }else if(schmapplet.places[i].markerbig){
						map.addItem(schmapplet.places[i].markerbig);
                        schmapplet.places[i].markerbig.hide();
					}
                }
                schmapplet.marker = true;
                logTime('end of making icons');
                return postMakeIcons2();
        });
        return postMakeIcons1(map);
    }
}
var logTimeMessage ='';
function logTime(message,putout) {
    //return;
    var prevTime = schmapplet.lastLoggedTime;
    schmapplet.lastLoggedTime = new Date();
    if(prevTime === undefined) {
        //logDebug(message, '-- counting time');
		var logMessage = message+'-- counting time';
    } else {
	var logMessage = message+ '--'+
                 (schmapplet.lastLoggedTime - prevTime) / 1000+'seconds';
    }
	logMessage = logMessage + '<br/>';
	logTimeMessage +=  logMessage ;	
//	logDebug(logTimeMessage);
	if(putout){
		try{
            if(parent.document.getElementById('logtime'))
			   parent.document.getElementById('logtime').innerHTML = logTimeMessage
			}catch(e){
				//alert(e);
				}
		
		}
}

function unshiftElement(arr, obj) {
    if(!obj) return arr;
    if(arr.length < 2) return arr;
    if(arr[0] == obj) return arr;
    var ix = 1;
	while(true) {
        if(arr[ix ++] == obj) {
            arr.splice(ix - 1, 1);
            break;
        }
    }
    arr.unshift(obj);
    return arr;
}

function errLog(err) {
    logError("my error is:", err);
    if(err.fileName && err.lineNumber)
        var errmsg = err + ' on ' + err.fileName + ':' + err.lineNumber;
    else
        var errmsg = repr(err) + ':' + err.message;
    logError(errmsg);
}
/*
function logMsg(logger, msg) {
 			MochiKit.Logging[logger](msg);
 }

function logDebug(msg) {
	logMsg('logDebug', msg);
}

function logError(msg) {
	logMsg('logError', msg);
}
*/
function analyticsConnect (element, eventName, func, hook, registerRepeats) 
{
    connect (element, eventName, func);
	if(trackPage && (!hook.isRegistered || (registerRepeats != null)))
    {
        var hookText;
        if (schmapplet.si && typeof(schmapplet.si) != 'undefined')
        {
            hookText = hook.text.replace('%si%',schmapplet.si);
        }
        else
        {
            hookText = hook.text.replace('%si%','none');
        }
        connect (element, eventName, function() {pageTracker._trackPageview(hookText);});
        hook.isRegistered = true;
    }
}

