/*
Example:
<div id="zone-tiscali-wide"></div>
<script src="zone.js"></script>
<script>
    ZONE.setDebug(1)
    ZONE.setPrefix('zone-')
    ZONE.setCond({'sex':'m','age':17}) // cileni
    ZONE.setCharset('iso-8859-2')
</script>
<div style="sourceadv">
    <div><script>ZONE.place('tiscali-wide');</script></div> <!-- nacteni reklamy do stranky -->
</div>
<script>
    ZONE.move();                        // presun vsech reklam na spravne pozice
</script>

History:
 2.0.2: minHeight - pro IE se musi pozdeji nastavit auto
 2.0.3: oprava fake mode pokud neni zadny banner
 2.1.1: rand pro uzivatele do cook na 24h
 2.1.2: geoip tahane vzdy
 2.1.3: oprava testBanner (pouziti moveLast)
 2.2.1: group pro multi
 2.2.7: erikovina - spousta souboru pro banner-zona
 2.2.8: fake pres url, replace ${ZONE}, logovani a nastavovani free do 100%, dot vcetne free
 2.2.9: posouvani nadpisu zleva. place je span
 2.2.12: podpora https, domeny
 2.2.14: predelano move na konec, ff iframe bug fix, sslForce, mene poskakovani, lepsi log
 2.2.16: iframe fix se nesmi delat v chrome (dela po reloadu iframe focus na iframe) + oprava preklepu
 2.2.18-19: iframe fix V2
 2.2.21: indexOf->search
 2.2.22: [n]->0-9, sticky bannery
 2.2.25: ban.data, text sort
 2.2.26: fix iframe src="", sticky podtejkani
*/

var protocol = document.location.protocol; /* obsahuje http: https: ... vcetne dvojtecky! */
if (protocol=='file:') { protocol='http:' }
var ZONE = {
    author      : 'network.image',
    version     : '2.2.26',
    condVars    : {},
    clearTarget : 1,    /* smazat na zacatku obsah divu */
    prefix      : 'zone-',
    debug       : 0,
    debugOpacity: 98,
    debugDiv    : null,
    debugList   : [],
    noCache     : 0,    /* 0/1 ... nic nechci cachovat */
    presetHeight: 1,    /* 0/1 ... prednastavit vysku? */
    domainN     : 10, /* dela modulo 10 z zoneId a bannerId a zameni [n] => 0-9 */
    urlZone     : [protocol+'//one1-cz.net4ge.net/zone', protocol+'//two6-cz.net4ge.net/zone'],
    urlBann     : [protocol+'//one[n]-cz.net4ge.net/bann', protocol+'//two[n]-cz.net4ge.net/bann'],
    urlDot      :  protocol+'//dot[n]-cz.net4ge.net/dot/dot.gif',
    urlClick    :  protocol+'//network-image.net4ge.net/redir', // TODO: sledovani prokliku k url se doplni ?zoneId=xxx&bannerId=xxx&url=escapovane_url
    urlGeoIP    :  protocol+'//geoip.net4ge.net/?',
    useGeoIP    : 1,
    useClick    : 0,
    fake        : 0, // pokud je pozice prazdna, vlozi jen prazdnej box a nazev pozice + pripadny text, 'flash'=vsude vlozi demo flash
    fakeFlash   : '<embed src="'+protocol+'//network-image.net4ge.net/data/fake.swf?clickthru=/demo/bla1/bla2?a%3D10" width="100%" height="300" />',
    protocol    : protocol,

    conflictDict: {}, // TODO: nutne doresit reload


    //body        : document.getElementsByTagName('body')[0],   // presunuto do setDebug a place
    head        : document.getElementsByTagName('head')[0],
    charset     : 'utf8',
    className   : 'titadv',     // class pro reklamni boxy

    stickyClass : 'sticky',
    stickySkip  : 'sticky-skip', /* class="sticky-skip" */
    stickyStop  : 'sticky-stop-', /* prefix: napr. id="sticky-stop-tiscali-hp-bigsquare" */
    //HTMLstart   : 'aaa',
    //HTMLend     : 'bbb',

    bannerCache : {}, // cache na samotna data banneru, aby se nestahoval znovu
    zoneInfoDict: {}, // hlavne na jakou zonu jakej banner
    stickyList  : [], // seznam sticky banneru a info k nim
    zoneId      : null,  // jaka zona se prave zpracovava (pri seriovem zpracovani)
    zoneIdLast  : null,
    writeTarget : null, // kam zapisovat pro fake document.write
    randInt     : Math.round( Math.random()*9999 ),     // TODO: pro nahodne pojmenovani vsech vytvarenych elementu
    geoIPInfo   : null,

    cookBanShow    : 'ZONEban',    // pod co ukladat pocet zobrazeni
    cookBanInterval: 'ZONEbanInterval', // pod co ukladat interval mezi zobrazenimi
    cookUser       : 'ZONEuser', // rand pro uzivatele
    cookExpire     : 21*86400,  // 21 dnu, na jak dlouho ulozim kukinu s poctem zobrazeni banneru

    timeStart   : null,

    testZoneBanner : {},   // umozni natvrdo vynutit banner na pozici (pro testovani)

    sslForce    : 0,    // vynuti zamenu vsech http za https
    sslReplace  : {
        'http://data-cz.net4ge'      : 'https://network-image.net4ge',
        'http://gdecz.hit.gemius.pl' : 'https://gdecz.hit.gemius.pl',
        'http://tiscali-cz.net4ge'   : 'https://tiscali-cz.net4ge',
        'http://tiscali.cz.net4ge'   : 'https://tiscali-cz.net4ge',
        'http://network-image.net4ge': 'https://network-image.net4ge',
        'http://download.macromedia.com':'https://download.macromedia.com',
        ''                      : ''
    },

    fillFreeRate: 0,    // pokud soucet neni 100%, doplni prazdnym bannerem

    '':'' // vycpavka kvuli carkam na konci
};
ZONE.init = function() {

    var obj = this.urlZone;
    if (typeof obj=='object' && obj.length) {
        // vyberu jeden
        this.urlZone = obj[Math.floor(Math.random()*obj.length)];
    }
    var obj = this.urlBann;
    if (typeof obj=='object' && obj.length) {
        this.urlBann = obj[Math.floor(Math.random()*obj.length)];
    }

    /* vlozi styly */
    var el = document.createElement('style');
    var txt = "#sourceadv { display:none; } " +
              "#dbglog"+this.randInt+" { z-index:100; text-align:left; margin:0!important; padding:2px; padding-left: 1px; border: 1px solid red; position: absolute; " +
              "top:0; right: 0; background: #fff; color:#000; max-height: 60%; _height: 300px; min-height: 100px; overflow: auto; width:320px; font-size: 11px; font-family: sans-serif; "+
              "         opacity: 0."+this.debugOpacity+"; filter: alpha(opacity="+this.debugOpacity+"); -moz-opacity: 0."+this.debugOpacity+"; -khtml-opacity: 0."+this.debugOpacity+"; } " +
              "li.dbglog { margin:0!important; padding:0!important; line-height: 12px; list-style: inside decimal; } " +
              "#dbglog"+this.randInt+" a { color: blue; } " +
              ".dotzone { } " +
              ".zonefake { height: 100px; background: yellow; border:none; text-align: center; font-family: Arial; } " +
              "span.zone-place { display: inline; width: auto; height: auto; overflow: visible; margin:0; padding: 0; background: none; } " +
              ".titadv { padding-top: 12px; background: url("+this.protocol+"//network-image.net4ge.net/data/nadpis.gif) no-repeat top left; }" +
              ".titoff { padding:0 !important; background:none !important; } ";
    el.type= 'text/css';
    el.media= 'screen';
    if(el.styleSheet) el.styleSheet.cssText= txt;      // ie method
    else el.appendChild(document.createTextNode(txt)); // others
    this.head.appendChild(el);

    /* user rand */
    var userHash = this.readCookie(this.cookUser);
    if(!userHash) {
        userHash = Math.floor(Math.random()*4294967295);
        var domain = this.hostLevel2(location.hostname);
        this.createCookie(this.cookUser, userHash, 86400, domain);
    }
    this.userHash = userHash;
    this.log("Zone version: "+this.version);
    this.log('userHash='+userHash);

    /* nechce neco testovat? */
    if (window.location.hash) {
        var re = /testBanner\(["']?(.+?)["']?,(\d+)\)/; //'
        var m = re.exec(window.location.hash);
        if (m) {
            this.log("From url hash: zone="+m[1]+' bannerId='+m[2], 'Indigo');
            this.testZoneBanner[m[1]] = m[2];
        }
        if (window.location.hash=='#fake') {
            this.log("From url hash: fake=1", 'Indigo');
            this.fake=1;
        }
    }
    if (this.urlGeoIP && this.useGeoIP) {
        var url = this.urlGeoIP
        var user = this.readCookie('WEBUSER') || '';
        url += "user="+user+"&rand="+this.randInt+'&version='+this.version;
        this.fetchURLjs(url);
    }
}
/* konfigurace */
ZONE.setPrefix = function(prefix) {
    this.prefix = prefix;
}
ZONE.setFake = function(fake) {
    this.fake = fake;
}
ZONE.setDebug = function(debug) {
    this.debug = debug;
    this.startDebug();
}
ZONE.setSSLForce = function(val) {
    this.sslForce = val;
}
ZONE.setFillFreeRate = function(fillFree) {
    this.fillFreeRate = fillFree
}
ZONE.testBanner = function(zoneId,bannerId) {
    this.testZoneBanner[zoneId] = bannerId;
}
ZONE.startDebug = function() {
    if (!this.body) {
        this.body = document.getElementsByTagName('body')[0];
    }

    if (this.debug==1 && this.debugDiv==null) {
        var div = document.createElement('ul');
        div.id = 'dbglog'+this.randInt;
        //this.body.appendChild(div);
        var prvni = this.body.childNodes[0];
        this.body.insertBefore(div, prvni); // do body jako prvni elem
        this.debugDiv = div;
        this.debugDiv.style.display = 'block';
        for(i=0;i<this.debugList.length;i++) {
            this.log(this.debugList[i].txt, this.debugList[i].color);
        }
        this.debugList = [];
    }
    else {
        if (this.debugDiv) {
            this.debugDiv.style.display = 'none';
        }
    }
}
ZONE.setCond = function(condVars) {
    this.condVars = condVars;
}
ZONE.setClass = function(className) {
    this.className = className;
}
ZONE.setCharset = function(val) {
    this.charset = val;
}
/* uzitecne funkce */
ZONE.log = function(txt,color) {


    if (this.debug!=1) {
        this.debugList.push({txt:txt,color:color}) // pokud netisknu, tak jen skladuju
        return;
    }
    var div = document.createElement('li');
    if(color) {
        div.style.color = color;
    }
    div.innerHTML = txt;
    div.className = 'dbglog';
    this.debugDiv.appendChild(div);
    this.debugDiv.scrollTop = this.debugDiv.scrollHeight;
}
ZONE.$ = function(name) {
    return document.getElementById(name);
}
ZONE.fetchURLjs = function(url) {
    document.write("<sc"+"ript src='"+url+"' charset='"+this.charset+"' type='text/javascript'></scr"+"ipt>");
}
//ZONE.randTime = function() {
ZONE.cacheTime = function() {
    /* pro lepsi cachovani na 30 minut */
    var d = new Date();
    return Math.floor(d.getTime()/1000/1800);
}
/* reklama */
ZONE.place = function(zoneId) {

    if (!this.body) {
        this.body = document.getElementsByTagName('body')[0];
    }


    /* prvni stazeni reklamy zaznamena start time */
    if (!this.timeStart) { this.timeStart = new Date().getTime()/1000; }

    if (zoneId.substring(0,this.prefix.length) == this.prefix) {
        /* kdyby nahodou nekdo napsal prefix i k vlozeni banneru */
        zoneId = zoneId.substring(this.prefix.length,zoneId.length);
    }

    var target = this.$(this.prefix+zoneId);
    if (!target) {
        this.log("Cilovy div "+this.prefix+zoneId+" nenalezen! (nestahuju)",'red');
        return;
    }

    if (target.className && (' '+target.className+' ').indexOf(' '+this.stickyClass+' ') > -1) {
    //if (target.className==this.stickyClass) {
        this.stickyAdd(zoneId,target)
    }

    this.zoneInfoDict[zoneId] = null;

    var sourceId = "tmp-source-"+zoneId;
    document.write('<div id="'+sourceId+'">');

    // prazdna struktura (bannerIdList - jake bannery zobrazit)
    var zoneInfo = { useBannerList:[], errZone:1, control:{}, bannerList: [], bannerDict:{} };
    this.zoneInfoDict[zoneId] = zoneInfo;
    // zruseno: bannerId: 0, placed: 0,  errBann:1

    /* jen test v zone */
    if (this.testZoneBanner[zoneId]) {
        var bannerId = this.testZoneBanner[zoneId];
        var bi = {id:bannerId, ver:Math.random(),click:0,err:1};
        this.log("Test bannerId="+bannerId+' zone='+zoneId, 'indigo');
        zoneInfo.useBannerList.push(bi);
        zoneInfo.errZone=0;
        zoneInfo.bannerDict[bannerId] = bi;
        if (this.clearTarget) {
            target.innerHTML = '';
        }
        this.fetchTestBanner(zoneId, bi);
        document.write('</div>');
        this.moveLast(zoneId); // k choose nikdy nedojde, tak to musim volat sam
        return;
    }

    /* stahnu seznam banneru na pozici - domena podle zony */
    var n = 0
    for (i=0; i<zoneId.lenght;i++) { n+=zoneId.charCodeAt(i) }
    var urlZone = this.urlZone.replace('[n]',n%this.domainN)
    url = urlZone+"/"+zoneId+".js?rand="+this.cacheTime();
    if (this.noCache) { url += "&rand2="+Math.random() }
    this.log('fetch zone '+zoneId+' <a href="'+url+'" target="_blank">&raquo;</a>');
    this.fetchURLjs(url);
    document.write('</div>');

    //this.moveLast(zoneId); /* tady to nefunguje */

}
ZONE.setGeoIP = function(geoIPInfo) {
    this.geoIPInfo = geoIPInfo;
    this.log("GeoIp OK: "+geoIPInfo.country_code+', '+geoIPInfo.region_name+'('+geoIPInfo.region_nuts+'), '+geoIPInfo.city,'blue');
    //this.condVars.geoip = this.geoIPInfo;
}
ZONE.chooseBanner = function(zoneId, bannerList, control) {
    /* vyberu ze seznamu jeden vhodny banner pro tuto pozici */

    if (bannerList[ bannerList.length-1 ] == 0) {
        bannerList.length--;
    }

    var target = this.$(this.prefix+zoneId);
    if (!target) {
        this.log('mas blbe nazev zony v zone/'+zoneId+'.js','red');
        return;
    }
    if (this.clearTarget && bannerList.length>0) {
        target.innerHTML = '';
    }
    if (bannerList.length==0 && this.fake==0) {
        this.zoneInfoDict[zoneId].errZone = 0;
        this.log("No banners zone="+zoneId, 'blue');
        return;
    }


    /* vyrobim dict a pomocne polozky */
    var bannerDict = {}
    for (i=0;i<bannerList.length;i++) {
        var ban = bannerList[i];
        ban.click = 0;
        ban.err = 1;
        bannerDict[ban.id] = ban;
    }

    if (!this.geoIPInfo) {
        this.log("Warning: GeoIP se nestahlo", 'red');
    }

    /* cileni: nejdriv oznacim to co nevyhovuje cileni */
    vars = this.condVars;
    for (i=0;i<bannerList.length;i++) {
        var ban = bannerList[i];
        ban.skip = 0;
        if (!ban.cond) continue;
        vars.geoip = this.geoIPInfo || {};
        try {
            ban.skip = !eval(ban.cond);
        }
        catch(err) {
            this.log('chybne zapsane cileni: zone='+zoneId+' bannerId='+ban.id+ ' err='+err, 'red');
            ban.skip = 1;
        }
        if (ban.skip) { this.log('condition SKIP: zone='+zoneId+' bannerId='+ban.id+' cond='+ban.cond,'Darkorange'); }
        else { this.log('condition OK: zone='+zoneId+' bannerId='+ban.id+' cond='+ban.cond,'seagreen'); }
    }
    /* cileni end */

    /* max pocet zobrazeni a interval */
    for (i=0;i<bannerList.length;i++) {
        var ban = bannerList[i];
        var keyShow = this.cookBanShow+ban.id;
        var keyInterval = this.cookBanInterval+ban.id;

        var cntShow = Number(this.readCookie(keyShow));
        if (ban.maxShow && cntShow>ban.maxShow) {
            ban.skip = 1;
            this.log('Max show: limit='+ban.maxShow+' show='+cntShow+ ' zone='+zoneId+' ban='+ban.id, 'blue');
        }
        var showIntervalExist = Number(this.readCookie(keyInterval));
        if (ban.showInterval && showIntervalExist) {
            ban.skip = 1;
            this.log('Interval exist: limit='+ban.showInterval+' zone='+zoneId+' ban='+ban.id, 'blue');
        }
    }

    /* konflikty - zjistim jestli tam je neco aktivniho a bez konfliktu (z minule zony) a pokud ano, konfliktni polozky oznacim jako skip*/
    // spocitam pocet nekonfliktnich
    // dale vyuziju na pripravu skupin (pokud jsou)
    var unconfCnt = 0;
    var groupDict = {};
    for (i=0;i<bannerList.length;i++) {
        var ban = bannerList[i];
        if (ban.skip) { continue }
        if (!this.conflictDict[ban.id]) {
            unconfCnt++;
        }
        /* pripravim skupiny pro multi */
        if (ban.group) {
            if (!groupDict[ban.group]) { groupDict[ban.group]=[]; }
            groupDict[ban.group].push( ban.id );
        }
    }
    if(unconfCnt>0) {
        for (i=0;i<bannerList.length;i++) {
            var ban = bannerList[i];
            if (ban.skip) { continue }
            // jsem v konfliktu, tak vynecham
            if(this.conflictDict[ban.id]) {
                this.log('Conflict zoneId='+zoneId+' banId='+ban.id+' with '+this.conflictDict[ban.id],'pink');
                ban.skip = 1;
            }
        }
    }
    /* konflikty end */


    // doplnim polozku pro nevyuzita procenta (pokud jsou)
    var fillFreeRate = this.fillFreeRate;
    if (control.fillFreeRate!=undefined) {
        fillFreeRate = control.fillFreeRate;
        this.log('control: fillFreeRate='+fillFreeRate+' zone='+zoneId+'');
    }
    var rateSum = 0;
    for (i=0;i<bannerList.length;i++) { rateSum += bannerList[i].rate; }
    if (rateSum<100 && fillFreeRate) {
        var freeBan = {id:0, rate:100-rateSum}
        bannerList.push(freeBan)
        this.log('Add free space: '+freeBan.rate+'% zone='+zoneId+' rateSum='+rateSum+'%', 'red');
    } // empty vypln (free banner)


    /* ze stejnych group vyberu jednu polozku */
    if (control.quantity == 'all') {
        for (groupName in groupDict) {
            var idx = Math.floor(Math.random()*groupDict[groupName].length);
            var banId = groupDict[groupName][idx];
            this.log('Group "'+groupName+'": '+groupDict[groupName]+' => '+banId, 'darkgreen');
            groupDict[groupName] = banId; // necham si jedno banId
        }
        for (i=0;i<bannerList.length;i++) {
            var ban = bannerList[i];
            if (ban.group && groupDict[ ban.group ] && groupDict[ ban.group ]!=ban.id) {
                ban.skip=1;
            }
        }
    }

    // filtrovani do noveho pole podle skip
    var rateSumF = 0;
    var bannerListF = [];
    for (i=0;i<bannerList.length;i++) {
        var item = bannerList[i];
        if (item.skip) { continue }
        bannerListF.push( item );
        rateSumF += item.rate;
    }
    // TODO: free banneru upravit rate podle zmeny 100% na rateSumF a rateSumF opravit nastedne podle zmeny rate u free

    if (!control) { control = {} }
    if (!control.quantity) { control.quantity = 'one' }

    /* zamichat */
    if (control.quantity == 'all') {
        if (control.quantitySort == 'rand') {
            bannerListF.sort(function(a,b) {return b.rate-a.rate || 0.5 - Math.random()});
        }
    }

    zoneInfo = this.zoneInfoDict[zoneId];
    zoneInfo.errZone = 0;
    zoneInfo.control = control;
    zoneInfo.bannerList = bannerList; // vsechno na pozici
    zoneInfo.useBannerList = []; // jen co pouziju
    zoneInfo.bannerDict = bannerDict; // pro lepsi hledani banneru na pozici (multipozici)
    zoneInfo.isFree = 0; // byla zona prazdna kvuli tomu, ze ma mit urcita % nevyuzita?

    /* nahodny vyber podle vahy */
    //var rand = Math.round( Math.random()*rateSumF ); // nemusim prepocitavat rate, kdyz zmenim max
    var rand = Math.floor( Math.random()*rateSumF+1 ); // nemusim prepocitavat rate, kdyz zmenim max
    this.log("choose: zone="+zoneId+" rand="+rand+ ' sum='+rateSumF+' banners='+bannerListF.length+'' , 'blue');

    var offset = 0;
    for (i=0;i<bannerListF.length;i++) {
        offset += bannerListF[i].rate;
        var use = 0;
        if (rand<=offset) {
            use = 1;
        }
        var ban = bannerListF[i];
        if (!ban.id) {
            if (zoneInfo.useBannerList.length==0) {
                this.log('choosed: zone='+zoneId+' used free space empty banner', 'red');
                zoneInfo.isFree = 1;
            }
            continue
        } // empty vypln vynecham (je az na konci, takze se nic nestane)

        if (control.quantity == 'all') {
            use = 1;
        }
        if (use==1) {
            var height = 0;
            if (ban.height && this.presetHeight==1) {
                if (document.all) {
                    target.style.height = (ban.height+2)+'px'; // v look pak nastavim pro IE auto
                }
                target.style.minHeight = (ban.height+2)+'px';
                target.className += ' '+this.className; // kvuli padding z classu - v look u empty zase vynuluju
                height = (ban.height+2);
            }
            this.log('choosed: zone='+zoneId+' bann_id='+ban.id+' minHeight='+height);
            zoneInfo.useBannerList.push(ban)
            this.fetchBanner(zoneId, ban);
            // vlozim konflikty ( a[kdo] = s cim(kdo_vlozil)
            if (ban.conflict) {
                for (j=0;j<ban.conflict.length;j++) { this.conflictDict[ ban.conflict[j] ] = ban.id; }
            }

            if (control.quantity != 'all') {
                //return;
                break;
            }
        }
    }
    if (zoneInfo.useBannerList.length==0) {
        this.log("EMPTY zone="+zoneId);
        zoneInfo.errZone=0;
    }
    this.moveLast(zoneId);
}
ZONE.moveLast = function(zoneId) {
    return
    if (this.zoneIdLast && zoneId!=this.zoneIdLast) {
        this.moveZone(this.zoneIdLast); // stehuju predchozi (kvuli iframe bugu)
        this.look(this.zoneIdLast);
    }
    this.zoneIdLast = zoneId;
}

ZONE.fetchBanner = function(zoneId, bannerInfo) {

    this.zoneId = zoneId;
    var bannerId = bannerInfo.id;

    if (bannerInfo.data) {
        this.log("ban.data: zone="+zoneId+" banner "+bannerId,'magenta');
        this.addBanner(bannerId, bannerInfo.data);
    }
    else if(this.bannerCache[bannerId]) {
        this.log("banner in cache: zone="+zoneId+" banner "+bannerId,'magenta');
        this.addBanner(bannerId, this.bannerCache[bannerId]);
    }
    else {
        var urlBann = this.urlBann.replace('[n]',bannerId%this.domainN)
        var url = urlBann+"/bann"+bannerId+"_"+zoneId+".js?ver="+bannerInfo.ver;
        this.log("fetch banner: zone="+zoneId+" banner="+bannerId+ ' <a href="'+url+'" target="_blank">&raquo;</a>', 'green');
        if (this.noCache) { url += "&rand="+Math.random() }
        this.fetchURLjs(url);
    }
}

ZONE.fetchTestBanner = function(zoneId, bannerInfo) {

    this.zoneId = zoneId;
    var bannerId = bannerInfo.id;

    if(this.bannerCache[bannerId]) {
        this.log("testBanner in cache: zone="+zoneId+" banner "+bannerId,'magenta');
        this.addBanner(bannerId, this.bannerCache[bannerId]);
    }
    else {
        var urlBann = this.urlBann.replace('[n]',bannerId%this.domainN)
        var url = urlBann+"/bann"+bannerId+".js?ver="+bannerInfo.ver;
        this.log("fetch test banner: zone="+zoneId+" banner="+bannerId+ ' <a href="'+url+'" target="_blank">&raquo;</a>', 'green');
        if (this.noCache) { url += "&rand="+Math.random() }
        this.fetchURLjs(url);
    }
}

ZONE.addBanner = function(bannerId, data) {

    var zoneId = this.zoneId; // lze pouzit jen pri JS v kodu bez defer

    // zamenim ${ZONE} za nazev zony
    data = data.replace(new RegExp( this.regEscape('${ZONE}'), 'g'), zoneId);
    if (this.protocol == 'https:') {
        if (this.sslForce) {
            this.sslReplace['http://'] = 'https://'
        }
        for (key in this.sslReplace) {
            if (!key) { continue }
            var val = this.sslReplace[key];
            key = this.regEscape(key);
            data = data.replace(new RegExp(key,'g'), val);
        }
    }

    var zoneInfo = this.zoneInfoDict[zoneId];
    if(!this.bannerCache[bannerId]) {
        this.bannerCache[bannerId] = data;
    }
    // obalim kazdej banner kvuli quantity:all a zapocitani zobrazeni do cookie pocitane v place
    if (this.fake == 'flash') {
        data = this.fakeFlash;
    }

    if (data.search(/iframe/i)>-1) {
        this.log('iframe banner: zone='+zoneId+' bannerId='+bannerId, 'LightCoral')
    }
    if (data.search(/script/i)>-1) {
        this.log('script banner: zone='+zoneId+' bannerId='+bannerId, 'LightCoral')
    }

    var dataOut = ''
    dataOut += '<span class="zone-place" id="place-'+zoneId+'-'+bannerId+'">'+data+'</span>';
    if (data.search(/script/i)>-1) {
        this.log('addBanner document.write: zone='+zoneId+' bannerId='+bannerId)
        document.write(dataOut);       // js reklamu vkladam na konec a presunu.
    }
    else {
        this.log('addBanner innerHTML: zone='+zoneId+' bannerId='+bannerId)
        var target = this.$(this.prefix+zoneId);
        target.innerHTML += dataOut; // simple banner umistim hned na pozici
        //zoneInfo.bannerDict[bannerId].moved = 1;
    }
    zoneInfo.bannerDict[bannerId].err = 0;
    //this.moveLast(zoneId);

}
ZONE.move = function() {
    /* musi se delat az mimo divy s reklamou! */
    this.log("moving");
    var zoneId = 0;

    //if (this.zoneIdLast) {
    //    this.moveZone(this.zoneIdLast); // stehuju predchozi
    //    this.look(this.zoneIdLast);
    //}
    this.moveLast(0);

    for (zoneId in this.zoneInfoDict) {
        if (this.zoneInfoDict[zoneId].errZone) {
            this.log("Banner error zoneId="+zoneId+" (404 nebo syntax)" ,'red');
        }
        this.moveZone(zoneId); // vse presunu najednou
        this.look(zoneId);
    }
    //this.zoneId = null;

    // souhrn
    this.log('----------------','gray')
    for (zoneId in this.zoneInfoDict) {
        var zoneInfo = this.zoneInfoDict[zoneId]
        for (i=0;i<zoneInfo.useBannerList.length;i++) {
            var ban = zoneInfo.useBannerList[i]
            this.log(zoneId+': '+ban.id+' - '+ban.comment)
        }
    }


    // dodatecne upravy vzhledu a dot
    //for (zoneId in this.zoneInfoDict) {
    //    this.look(zoneId);
    //}
    var runTime = (new Date().getTime()/1000) - this.timeStart;
    this.log("Runtime: "+runTime+" sec");
}
ZONE.moveZone = function(zoneId) {

    this.log("moving zone="+zoneId);

    var zoneInfo = this.zoneInfoDict[zoneId];
    if (!zoneInfo || zoneInfo.errZone) {
        this.log("Zone error zoneId="+zoneId+" (404 nebo syntax)",'red');
        return;
    }

    var target = this.$(this.prefix+zoneId);
    if (!target) {
        this.log("Cilovy div "+this.prefix+zoneId+" nenalezen!",'red');
        return;
    }

    if (zoneInfo.useBannerList.length==0) {
        this.log("Zone "+zoneId+" empty",'blue');
        return;
    }

    for (i=0;i<zoneInfo.useBannerList.length;i++) {
        var ban = zoneInfo.useBannerList[i];
        if(ban.err == 1) {
            this.log("Banner error bannerId="+ban.id+" zoneId="+zoneId+" (404 nebo syntax)" ,'red');
        }
    }

    var sourceId = "tmp-source-"+zoneId;
    var source = this.$(sourceId);
    if (source) {
        // samotny presun
        target.appendChild(source.parentNode);
        setTimeout( "ZONE.iframeFix('"+zoneId+"')",200)
    }
    else {
        this.log("Source "+sourceId+" neexistuje!",'red');
    }
}
ZONE.iframeFix = function(zoneId) {
    // oprava iframe ve ff a safari, pokud tam iframe je

    if (navigator.userAgent.search(/Chrome/i) > -1) {
        return
    }
    if( navigator.userAgent.search(/Firefox/i)==-1 && navigator.userAgent.search(/safari/i)==-1) {
        return
    }
    var target = this.$(this.prefix+zoneId);
    var f = target.getElementsByTagName('iframe');
    if (f.length==0) {
        return
    }
    this.log('iframe bug fix zone='+zoneId+' cnt='+f.length+' '+navigator.userAgent,'red')
    for(var i=0;i<f.length;i++){
        if(!f[i].src || f[i].src==document.location.href) { continue }
        if(f[i].src.indexOf('?')==-1) { f[i].src += '?'+this.randInt; }
        else { f[i].src += "&"+this.randInt; }
        //f[i].src += '#'
    }
}

ZONE.look = function(zoneId) {
    // dodatecne upravy vzhledu a dot
    var target = this.$(this.prefix+zoneId);
    if (!target) { return }
    var zoneInfo = this.zoneInfoDict[zoneId];

    this.log("start look zone "+zoneId+' height='+target.offsetHeight,'gray');
    if (document.all) {
        target.style.height = 'auto';
    }

    var nuts3   = (this.geoIPInfo || {})['region_nuts'] || ''
    var country = (this.geoIPInfo || {})['country_code'] || ''
    var cntFull = 0;
    /* doplnim dot a pocitani do cookie */
    var dotTxt = '';
    var dotTxtShare = '&zoneId='+zoneId+'&nuts3='+nuts3+'&country='+country+'&user='+this.userHash+'&version='+this.version+'&rand='+Math.random();
    var minOffsetLeft = 999


    for (i=0;i<zoneInfo.useBannerList.length;i++) {
        var ban = zoneInfo.useBannerList[i];
        var bannerId = ban.id;
        var place = this.$('place-'+zoneId+'-'+bannerId);
        var emptyPlace = 0;
        if (!place) {
            this.log('No place: zone='+zoneId+' banner='+bannerId, 'red');
        }
        if (place && place.offsetLeft < minOffsetLeft) {
            minOffsetLeft = place.offsetLeft;
        }

        var testing = place; // u slozitejsich js (opera, ie) jsou data mimo place
        if (zoneInfo.useBannerList.length==1) { testing = target; }
        if (!testing || testing.offsetHeight<14 || testing.innerHTML=='') {
            emptyPlace = 1;
        }

        if (emptyPlace==0) {
            cntFull++;
            var domain = this.hostLevel2(location.hostname);
            if (ban.maxShow) {
                var key = this.cookBanShow+bannerId;
                this.createCookie(key, Number(this.readCookie(key))+1, this.cookExpire, domain);
            }
            if (ban.showInterval) {
                var key = this.cookBanInterval+bannerId;
                this.createCookie(key, 1, ban.showInterval, domain);
            }
            this.link(place, zoneId, bannerId);
        }
        var urlDot = this.urlDot.replace('[n]',bannerId%this.domainN)
        dotTxt += '<img src="'+urlDot+'?banId='+bannerId+'&empty='+emptyPlace+'&click='+ban.click+'&err='+ban.err+dotTxtShare+'" ' +
                  ' style="position:absolute;width:1px;height:1px;top:-100px;left:-100px;">';
        this.log("dot: "+zoneId+' bannerId='+bannerId+' empty='+emptyPlace+' click='+ban.click+' err='+ban.err);
    }
    if (zoneInfo.useBannerList.length==0) {
        var urlDot = this.urlDot.replace('[n]','0')
        dotTxt += '<img src="'+urlDot+'?banId=0&empty=1&click=0&err=0&free='+zoneInfo.isFree+''+dotTxtShare+'" '+
                  ' style="position:absolute;width:1px;height:1px;top:-100px;left:-100px;">';
        this.log("dot: "+zoneId+' bannerId=0 empty=1 click=0 err=0 (no banners) free='+zoneInfo.isFree);
    }


    var dot = document.createElement('div');
    dot.className = 'dotzone';
    dot.id = 'dotzone'+zoneId;
    dot.innerHTML = dotTxt;
    target.appendChild(dot);

    /* nadpis */
    if (cntFull==0) {
        if (this.className && target.className) {
            target.className = target.className.replace(this.className,'');
        }
    }
    else {
        if (this.className && target.className.indexOf(this.className) == -1) {
            target.className += ' '+this.className;
        }
        if (minOffsetLeft<999 && target.style.position!='absolute') {
            target.style.backgroundPosition = (minOffsetLeft-target.offsetLeft)+'px 0px';
        }
    }
    /* start+end html */
    if (cntFull) {
        // TODO
        //if (data) { dataOut += this.HTMLend; }
        //if (data) { dataOut += this.HTMLstart; }
    }

    /* fake mode */
    if (cntFull==0) {
        if (this.fake) {
            this.log("Fake empty "+zoneId,"gray");
            var msg = "Fake mode: prazdna";
            if (typeof this.fake == 'string') {
                msg = this.fake;
            }
            var div = document.createElement('div')
            if (this.fake=='flash') {
                div.innerHTML = this.fakeFlash;
            }
            else {
                div.innerHTML = '<div class="zonefake"><br><br>'+msg+'<br><small>(zona '+zoneId+')</small></div>';
            }
            target.appendChild( div );
            target.className = this.className;
        }
    }

}
ZONE.link = function(banElem, zoneId, bannerId) {
    /* proklik - pokud uz neni hlidany */
    if (!this.urlClick || this.useClick==0) {
        return
    }
    /* a href */
    var els = banElem.getElementsByTagName('a');
    for (x=0; x<els.length; x++) {
        var el = els[x];
        if (el.href.indexOf(this.urlClick) == -1) {
            this.log("href: zone="+zoneId+" ban="+bannerId+" "+el.href)
            el.href = this.urlClick+'?zoneId='+zoneId+'&bannerId='+bannerId+'&url='+encodeURIComponent(el.href);
            this.zoneInfoDict[zoneId].bannerDict[bannerId].click = 'href';
        }
        else {
            this.zoneInfoDict[zoneId].bannerDict[bannerId].click = 'href-inline';       // uz je presmerovani v kodu banneru
        }
    }
    /* flash - clickthru, clickTag */
    // pres innerHTML (pres atributy nefungovalo spravne v IE)
    var re_flash = /(clickthru|clickTag)=([^\&\"]+)/ig;      // "
    this.tmp_zoneId = zoneId
    this.tmp_bannerId = bannerId

    data = banElem.innerHTML
    if (data.search(/object/i)>-1 || data.search(/embed/i)>-1) {
        banElem.innerHTML = data.replace(re_flash, ZONE.flashReplace)
    }
}
ZONE.flashReplace = function(m) {
    var aa = m.split('=');
    if (aa[1].indexOf(ZONE.urlClick) == -1) {
        ZONE.log("flash: zone="+ZONE.tmp_zoneId+" ban="+ZONE.tmp_bannerId+" "+m)
        var ret = aa[0]+'='+encodeURIComponent(ZONE.urlClick+'?zoneId='+ZONE.tmp_zoneId+'&bannerId='+ZONE.tmp_bannerId+'&url='+encodeURIComponent(aa[1]));
        ZONE.zoneInfoDict[ZONE.tmp_zoneId].bannerDict[ZONE.tmp_bannerId].click = 'flash';
    }
    else {
        ZONE.zoneInfoDict[ZONE.tmp_zoneId].bannerDict[ZONE.tmp_bannerId].click = 'flash-inline'; // presmerovani clickthru je uz v banneru
        var ret = m;
    }
    return ret
}
/* sticky */
ZONE.stickyInit = function(info) {
    /* doplni puvodni pozici, najde parenta ktery je vyssi a najde jeho spodek - spusti se az pri scrollu */
    var obj = info.obj;
    var zoneId = info.zoneId;
    var pos = ZONE.findPos(obj);
    info.startTop = pos[1];
    var stickyHeight = obj.clientHeight || obj.offsetHeight

    var objParent = obj;
    stickyStop = ZONE.$(ZONE.stickyStop+zoneId)
    if (stickyStop) {
        objParent = stickyStop;
    }
    else {
        for (i=0;i<5;i++) {
            objParent = objParent.parentNode;
            if ((' '+objParent.className+' ').indexOf(' '+ZONE.stickySkip+' ') > -1) { continue; }
            if (!objParent) { break }
            var parentHeight = objParent.clientHeight||objParent.offsetHeight
            if (parentHeight>stickyHeight) { break }
        }
    }
    var posParent = ZONE.findPos(objParent);
    var parentHeight = objParent.clientHeight||objParent.offsetHeight
    info.endTop = posParent[1]+parentHeight-stickyHeight;
    //alert(posParent[1]+'+'+objParent.clientHeight+'-'+stickyHeight);
    ZONE.log("stickyInit: "+obj.id+" start="+info.startTop+" end="+info.endTop+" parent="+objParent.id+" "+objParent.className+" ("+objParent.tagName+")")
    info.init=1
}
ZONE.stickyAdd = function(zoneId,obj) {
    obj.style.position = 'relative'
    this.stickyList.push( {zoneId:zoneId, obj:obj, init:0} )
}
ZONE.stickyScroll = function(e) {

    var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
    for (i=0;i<ZONE.stickyList.length;i++) {
        var sticky = ZONE.stickyList[i]
        if (sticky.init==0) { ZONE.stickyInit(sticky)}

        var obj = sticky.obj

        if (scrollTop>sticky.endTop) {
            obj.style.marginTop = (sticky.endTop-sticky.startTop)+'px';
            obj.style.position = 'static'
        }
        else if (scrollTop > sticky.startTop && scrollTop < sticky.endTop) {
            obj.style.position = 'fixed'
            obj.style.marginTop = '0px'
            obj.style.top = '0'
        }
        else {
            obj.style.position = 'static'
            obj.style.marginTop = '0px'
            obj.style.top = 'auto'
        }

    }
}
/* reload */
ZONE.write = function(data) {
    /* fake za document.write(), this nelze pouzit */

    var target = ZONE.writeTarget;
    ZONE.log('write '+target.id);

    var node = document.createElement('span');
    node.innerHTML = '&nbsp;'+data+'&nbsp;';
    //alert(data);
    //var target = ZONE.$(ZONE.prefix+ZONE.zoneId);
    var scriptList = node.getElementsByTagName('script');
    target.innerHTML += data;
    for (var i=0; i<scriptList.length; i++) {
        var newScript = document.createElement('script');
        var s = scriptList[i];
        //if (s.id == 'skip') { /*s.parentNode.removeChild(s);*/ continue }
        newScript.type = "text/javascript";
        newScript.language = "javascript";
        //newScript.id = 'skip';
        if (s.charset) {
            newScript.charset = s.charset;
        }
        if (s.src) {
            ZONE.log("script src="+s.src);
            newScript.src  = s.src;
            //alert("src="+s.src)
        }
        else if(s.text) {
            ZONE.log("script inline");
            newScript.text = s.text;
        }
        if(s.src) {
            ZONE.head.appendChild(newScript);
        }
        else {
            target.appendChild(newScript);
        }
    }
    //target.innerHTML += node.innerHTML;
}
ZONE.reload = function(zoneId) {
    /* vzhledem k asynchnosti dotahovanych JS nelze pouzit na vic jak jednu reklamu v jeden okamzik !!! */
    this.log("Reload "+zoneId, 'gray');
    bannerList = this.zoneInfoDict[zoneId].bannerList;
    control = this.zoneInfoDict[zoneId].control;
    var dw = document.write;
    document.write = this.write; //function(data) { alert(data) }
    if (bannerList) {
        var target = this.$(this.prefix+zoneId);
        if (!target) { return }
        target.innerHTML = '';
        //this.zoneId = zoneId;
        this.writeTarget = target;
        this.chooseBanner(zoneId,bannerList,control);
    }
    setTimeout("ZONE.look('"+zoneId+"');",500); // nutne kvuli async js
    //document.write = dw;
    //this.look(zoneId)
}
ZONE.reloadElem = function(name,data) {
    /* bez 'data' prakticky nepouzitelne */
    this.log("Reload elem "+name, 'gray');
    var target = this.$(name);
    if (!target) { return }
    if (!data) { data = target.innerHTML; }
    this.writeTarget = target;
    target.innerHTML = '';
    document.write = this.write; //function(data) { alert(data) }
    document.write(data);
}

/* cookie a domeny */
ZONE.hostLevel2 = function(hostname) {
    /* z domeny udela jen level2 domenu napr .tiscali.cz */
    if (/^(\d{1,3}\.){3}\d{1,3}$/.test(hostname)) {
         return hostname;
    }
    else {
        var arr = hostname.split('.');
        return "."+arr[arr.length-2]+"."+arr[arr.length-1];
    }
}
ZONE.createCookie = function(name,value,expire,domain) {
    var txt = name+"="+value+"; path=/;";
    if (expire) {
        var date = new Date();
        //date.setTime(date.getTime()+(days*24*60*60*1000));
        date.setTime(date.getTime()+(expire*1000));
        txt += "; expires="+date.toGMTString();
    }
    if (domain) {
        txt += "domain="+domain+";";
    }
    document.cookie = txt;
}
ZONE.readCookie = function(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') c = c.substring(1,c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
    }
    return null;
}
ZONE.eraseCookie = function(name) {
    createCookie(name,"",-1);
}
/* John Resig events */
ZONE.addEvent = function(obj, type, fn) {
    if (obj.addEventListener)
        obj.addEventListener( type, fn, false );
    else if (obj.attachEvent) {
        obj["e"+type+fn] = fn;
        obj[type+fn] = function() { obj["e"+type+fn]( window.event ); }
        obj.attachEvent( "on"+type, obj[type+fn] );
    }
}
ZONE.removeEvent = function(obj, type, fn) {
    if (obj.removeEventListener)
        obj.removeEventListener( type, fn, false );
    else if (obj.detachEvent) {
        obj.detachEvent( "on"+type, obj[type+fn] );
        obj[type+fn] = null;
        obj["e"+type+fn] = null;
    }
}
/* end */
ZONE.DOMReady = function(f){
  if (/(?!.*?compatible|.*?webkit)^mozilla|opera/i.test(navigator.userAgent)){ // Feeling dirty yet?
    document.addEventListener("DOMContentLoaded", f, false);
  }
  else {
    window.setTimeout(f,0);
  }
}
ZONE.findPos = function(obj) {
    var curleft = curtop = 0;
    if (obj.offsetParent) {
        do {
            curleft += obj.offsetLeft;
            curtop += obj.offsetTop;
        } while (obj = obj.offsetParent);
    }
        return [curleft,curtop];
}
/* string addon - only for ZONE */
ZONE.trim = function(txt) { return (txt.replace(/^[\s\xA0]+/, "").replace(/[\s\xA0]+$/, "")) }
ZONE.endswith = function(txt,str) { return (txt.match(str+"$")==str) }
ZONE.startswith = function(txt,str) { return (txt.match("^"+str)==str) }
ZONE.regEscape=function(str) {
    var specials = ['/', '.', '*', '+', '?', '|','(', ')', '[', ']', '{', '}', '\\'];
    sRE = new RegExp('(\\' + specials.join('|\\') + ')', 'gim');
    return str.replace(sRE, '\\$1');
}

ZONE.init();
ZONE.DOMReady( function(){a=ZONE.addEvent(document,'scroll',ZONE.stickyScroll);if(!a){window.onscroll=ZONE.stickyScroll} } )

