/**
 * SWFAddress v1.2: Deep linking for Flash - http://www.asual.com/swfaddress/
 *
 * SWFAddress is (c) 2006-2007 Rostislav Hristov and is released under the MIT License:
 * http://www.opensource.org/licenses/mit-license.php
 *
 */

if(typeof asual == "undefined") var asual = new Object();
if(typeof asual.util == "undefined") asual.util = new Object();

asual.util.Browser = new function() {

    var supported = false;
    var version = -1;
    
    var agent = navigator.userAgent;
    var ie = false;
    var camino = false;
    var safari = false;
    var opera = false;
    var mozilla = false;
    
    if (/MSIE/.test(agent)) {
        ie = true;
        version = parseFloat(agent.substring(agent.indexOf('MSIE') + 4));
        supported = version >= 6;
    } else if (/AppleWebKit/.test(agent)) {
        safari = true;
        version = parseFloat(agent.substring(agent.indexOf('Safari') + 7));
        supported = version >= 312;
    } else if (/Opera/.test(agent)) {
        opera = true;
        version = parseFloat(navigator.appVersion);
        supported = version >= 9.02;
    } else if (/Camino/.test(agent)) {
        camino = true;
        version = parseFloat(agent.substring(agent.indexOf('Camino') + 7));
        supported = version >= 1;
    } else if (/Firefox/.test(agent)) {
        mozilla = true;
        version = parseFloat(agent.substring(agent.indexOf('Firefox') + 8));
        supported = version >= 1;
    } else if (/Netscape/.test(agent)) {
        mozilla = true;
        version = parseFloat(agent.substring(agent.indexOf('Netscape') + 9));
        supported = version >= 8;
    } else if (/Mozilla/.test(agent) && /rv:/.test(agent)) {
        mozilla = true;
        version = parseFloat(agent.substring(agent.indexOf('rv:') + 3));
        supported = version >= 1.8;
    }
    
    this.isSupported = function() {
        return supported;
    }
    
    this.getVersion = function() {
        return version;
    }
    
    this.isIE = function() {
        return ie;
    }

    this.isSafari = function() {
        return safari;
    }

    this.isOpera = function() {
        return opera;
    }

    this.isCamino = function() {
        return camino;
    }

    this.isMozilla = function() {
        return mozilla;
    }
    
}

asual.util.Functions = new function() {

    this.extend = function(superclass, subclass) {
        function inheritance() {}
        inheritance.prototype = superclass.prototype;
        subclass.prototype = new inheritance();
        subclass.prototype.constructor = subclass;
        subclass.superConstructor = superclass;
        subclass.superClass = superclass.prototype;
        for (var p in superclass) {
            if (p != 'prototype') subclass[p] = superclass[p];
        }
        return subclass;
    }
    
    this.bindAsListener = function(method, object, win) {
        return function(evt) {
            return method.call(object, evt || ((win) ? win.event : window.event));
        }
    }    
}

asual.util.Events = new function() {

    var cache = new Array();
    
    this.addListener = function (obj, type, listener) {
        if (obj.addEventListener){
            obj.addEventListener(type, listener, false);
        } else if (obj.attachEvent){
            obj.attachEvent('on' + type, listener);
        } else {
            obj['on' + type] = listener;        
        }
        cache.push({o: obj, t: type, l: listener});
    }
    
    this.removeListener = function (obj, type, listener) {  
        if (obj.removeEventListener){
            obj.removeEventListener(type, listener, false);
        } else if (obj.detachEvent){
            obj.detachEvent('on' + type, listener);
        } else {
            obj['on' + type] = listener;
        }
    }
    
    var unload = function() {
        for (var i = 0, evt; evt = cache[i]; i++) {
            asual.util.Events.removeListener(evt.o, evt.t, evt.l);
        }
    }
    
    if (asual.util.Browser.isIE() || asual.util.Browser.isSafari()) {    
        this.addListener(window, 'unload', asual.util.Functions.bindAsListener(unload, this));    
    }
}

asual.SWFAddress = new function() {

    var browser = asual.util.Browser;
    var iframe, form, supported = browser.isSupported();
    var swfaddr, swfobj, swfid, swfupdate = false;
    var swftitle = document.title;
    var swflength = history.length;
    var swfhistory = new Array();   
    var listeners = new Object();    
    var swftrackingEnabled = true;
    var swfhistoryEnabled = true;
    var js = 'swfaddress.js';
    var html = 'swfaddress.html';
    var swf = 'swfaddress.swf';
    var d = top.document;
    var h = top.history;
    var l = top.location;
    
    if ((!supported && l.href.indexOf('#') != -1) || 
        (browser.isSafari() && browser.getVersion() < 412 && l.href.indexOf('#') != -1 && l.search != '')){
        d.open();
        d.write('<html><head><meta http-equiv="refresh" content="0;url=' + l.href.substr(0, l.href.indexOf('#')) + '" /></head></html>');
        d.close();
    }

    var getURL = function(url) {
        var scripts = document.getElementsByTagName('script');
        for (var i = 0, s; s = scripts[i]; i++) {
            if (s.src.indexOf(js) > -1) {
                return (new String(s.src)).replace(js, url);
            }
        }
    }

    var getHash = function() {
        var index = l.href.indexOf('#');
        if (index != -1) {
            return l.href.substring(index).replace(/^#/g, '');
        }
        return '';
    }

    var hash = getHash();

    var titleListener = function() {
        if (browser.isIE() && d.title != swftitle) {
            asual.SWFAddress.setTitle(swftitle);
        }
    }

    var listen = function() {
        if (browser.isSafari()) {
            if (swflength != h.length && !swfupdate) {
                swflength = h.length;
                if (typeof swfhistory[swflength - 1] != 'undefined') {
                    hash = swfhistory[swflength - 1];
                }
                update();
            }        
        } else if (browser.isIE()) {
            if (hash != getHash()) {
                if (browser.getVersion() < 7) {
                    l.reload();
                } else {
                    setValue(getHash(), false);
                }
            }
        } else if (hash != l.hash) {
            hash = getHash();
            if (browser.isMozilla()) {
                var hcheck = false;
                for (var i = 0; i < swfhistory.length; i++) {
                    if (swfhistory[i] == hash) {
                        hcheck = true; break;
                    }
                }
                if (!hcheck) {
                    l.reload(); return;
                }
            }
            update();
        }
        titleListener();
    }
    
    var init = function() {
        dispatch('init');
    }
    
    var change = function() {
        dispatch('change');
    }

    var dispatch = function(type) {
        if (SWFAddress.hasEventListener(type)) {
            var e = {target: SWFAddress, type: type};
            SWFAddress.dispatchEvent(e);
        }
        type = type.substr(0, 1).toUpperCase() + type.substring(1);
        if(typeof SWFAddress['on' + type] == 'function') {
            SWFAddress['on' + type]();
        }        
    }

    var update = function() {
        var addr = hash;
        if (addr != swfaddr) {
            swfaddr = addr;
            var obj = document[swfid] || document.getElementById(swfid);
            if (obj && obj.setSWFAddressValue) {
                obj.setSWFAddressValue(addr);
            }
            if (swfobj && swfobj.call) {
                swfobj.call('setSWFAddressValue', addr);
            }
            change();
        }
    }

    var track = function() {
        if (swftrackingEnabled && typeof urchinTracker != 'undefined'){
            var path = l.pathname + this.getValue();
            path = path.replace(/\/\//, '/');
            path = path.replace(/^\/$/, '');            
            urchinTracker(path);
        }
    }

    var loadSuccess = function() {
        if (iframe.contentWindow && iframe.contentWindow.location) {
            var win = iframe.contentWindow;
            win.document.title = d.title = swftitle;
            var src = win.location.href;
            if (src.indexOf('?') > -1) {
                hash = src.substring(src.indexOf('?') + 1);
            } else {
                hash = '';
            }
            if (hash != getHash()) {
                update();
                l.hash = '#' + hash;
            }
        }
    }
    
    var load = function() {
        if (browser.isIE() || browser.isSafari()) {
            var content = document.createElement('div');
            document.body.appendChild(content);
            content.id = 'swfaddress';
            content.style.position = 'absolute';
            content.style.left = content.style.top = '-9999px';
            content.innerHTML = '<iframe id="swfaddress-iframe" src="' + getURL(html) + '?' + getHash() + '" frameborder="no" scrolling="no"></iframe>';
            iframe = content.getElementsByTagName('iframe')[0];
        }
        if (browser.isIE()) {
            asual.util.Events.addListener(iframe, 'load', asual.util.Functions.bindAsListener(loadSuccess, this));  
        }
        if (browser.isSafari()) {
            form = document.createElement('form');
            form.id = 'swfaddress-form';        
            form.method = 'get';
            content.appendChild(form);        
            if (typeof l.swfaddress == 'undefined') {
                l.swfaddress = new Object();
            }
            if (typeof l.swfaddress.history != 'undefined') {
                swfhistory = l.swfaddress.history.split(',');
            }
        }
        if (browser.isOpera() && typeof swfid == 'undefined') {
            document.body.innerHTML += '<embed src="' + getURL(swf) + '" width="1" height="1" style="position: absolute; top: -9999px; left: -9999px" type="application/x-shockwave-flash" />';
        }
        track.call(this);
        update.call(this);
        setTimeout(init, 1);
        setTimeout(change, 2);
        setInterval(listen, 50);
    }

    var setValue = function(addr, force) {
        if (!supported) return null;
        if (addr == 'null') {
            addr = '';
        }
        if (swfaddr == addr) {
            return;
        }
        hash = addr;
        if (force) {
            swfaddr = addr;
            update();
        } else {
            update();
            swfaddr = addr;
        }
        swfhistory[history.length] = hash;
        if (browser.isSafari()) {
            if (swfhistoryEnabled) {
                l.swfaddress.history = swfhistory.toString();
                swfupdate = true;
                swflength = history.length + 1;
                if (browser.getVersion() < 412) {
                    if (l.search == '') {
                        form.action = '#' + hash;
                        form.submit();
                    }
                } else {
                    var evt = document.createEvent('MouseEvents');
                    evt.initEvent('click', true, true);
                    var anchor = document.createElement('a');
                    anchor.href = '#' + hash;
                    anchor.dispatchEvent(evt);
                }
                swfupdate = false;
            } else {
                l.hash = '#' + hash;
            }
        } else if (force) {
            if (swfhistoryEnabled) {
                l.hash = '#' + hash;
            } else {
                l.replace('#' + hash);
            }
        }
        if (browser.isIE() && swfhistoryEnabled) {
            var win = iframe.contentWindow;
            var query = '?' + getHash();
            win.location.assign(win.location.pathname + query);
        }
        track.call(this);
        change.call(this);
    }

    this.toString = function() {
        return '[object SWFAddress]';
    }

    /**
     * Loads the previous URL in the history list.
     */
    this.back = function() {
        h.back();
    }

    /**
     * Loads the next URL in the history list.
     */    
    this.forward = function() {
        h.forward();
    }

    /**
     * Loads a URL from the history list.
     * @param {Number} delta An integer representing a relative position in the history list
     */    
    this.go = function(delta) {
        h.go(delta);
    }

    /**
     * Registers an event listener.
     * @param {String} type Event type
     * @param {Function} listener Event listener
     */ 
    this.addEventListener = function (type, listener) {
        if (typeof listeners[type] == 'undefined') {
            listeners[type] = new Array();
        }
        listeners[type].push(listener);
    }

    /**
     * Removes an event listener. 
     * @param {String} type Event type
     * @param {Function} listener Event listener
     */     
    this.removeEventListener = function (type, listener) {
        if (typeof listeners[type] != 'undefined') {
            for (var i = 0, l; l = listeners[type][i]; i++) {
                if (l == listener) break;
            }
            listeners[type].splice(i, 1);
        }
    }

    /**
     * Dispatches an event to all the available listeners. 
     * @param {Object} event Event object
     */       
    this.dispatchEvent = function (event) {
        if (typeof listeners[event.type] != 'undefined') {
            event.target = this;
            for (var i = 0, l; l = listeners[event.type][i]; i++) {
                l(event);
            }
        }
    }

    /**
     * Checks the existance of any listeners registered for a specific type of event. 
     * @param {String} event Event type
     * @type Array
     */     
    this.hasEventListener = function (type) {
        return (typeof listeners[type] != 'undefined' && listeners[type].length > 0);
    }

    this.getHistoryEnabled = function() {
        return swfhistoryEnabled;
    }

    this.setHistoryEnabled = function(enabled) {
        swfhistoryEnabled = enabled;
    }

    this.getTrackingEnabled = function() {
        return swftrackingEnabled;
    }

    this.setTrackingEnabled = function(enabled) {
        swftrackingEnabled = enabled;
    }

    /**
     * Opens a new URL in the browser. 
     * @param {String} url The resource to be opened
     * @param {String} target Target window
     */
    this.openLink = function(url, target) {
        switch(target) { 
            case '_blank':  
                window.open(url); 
                break; 
            case '_self': 
                self.location = url; 
                break;
            case '_top': 
                loc = url; 
                break; 
            default:
                self.location = url; 
                break; 
        }
    }

    /**
     * Opens a browser popup window. 
     * @param {String} url The resource to be opened
     * @param {String} name The name of the popup window
     * @param {String} options Popup window options in a format compatible window.open()
     * @param {String} handler Optional handler function for window manipulation     
     */
    this.openPopup = function(url, name, options, handler) {
        var w = window.open(url, name, options);
    }

    this.getSWFObject = function() {
        if (!supported) return null;
        return swfobj;
    }

    this.setSWFObject = function(swfobject) {
        if (!supported) return null;    
        swfobj = swfobject;
    }

    this.getId = function() {
        if (!supported) return null;
        return swfid;
    }

    this.setId = function(id) {
        if (!supported) return null;    
        swfid = id;
    }

    this.getTitle = function() {
        if (!supported) return null;    
        return d.title;
    }

    this.setTitle = function(title) {
        if (!supported) return null;
        if (title == 'null') {
            title = '';
        }        
        if (typeof title != 'undefined') {
            swftitle = title;
            d.title = swftitle;
        }
    }

    this.getStatus = function() {
        if (!supported) return null;    
        return top.status;
    }

    this.setStatus = function(status) {
        if (!supported) return null;
        if (!browser.isSafari()) {
            if (status == 'null' || typeof status == 'undefined') {
                status = '';
            }        
            var index = l.href.indexOf('#');
            if (index == -1) {
                status = l.href + '#' + status;
            } else {
                status = l.href.substr(0, index) + '#' + status;
            }
            top.status = status;
        }
    }

    this.resetStatus = function() {
        top.status = '';
    }

    this.getValue = function() {
        if (!supported) return null;
        return hash;
    }

    this.setValue = function(value) {
        setValue(value, true);
    } 

    this.getPath = function() {
        var value = this.getValue();
        if (value.indexOf('?') != 1) {
            return value.split('?')[0];
        } else {
            return value;   
        }
    }

    this.getQueryString = function() {
        var value = this.getValue();
        var index = value.indexOf('?');
        if (index != -1 && index < value.length) {
            return value.substr(index + 1);
        }
        return '';
    }

    this.getParameter = function(param) {
        var value = this.getValue();
        var index = value.indexOf('?');
        if (index != -1) {
            value = value.substr(index + 1);
            var params = value.split('&');
            var p, i = params.length;
            while(i--) {
                p = params[i].split('=');
                if (p[0] == param) {
                    return p[1];
                }
            }
        }
        return '';
    }

    if (!supported) return;
    
    for (var i = 1; i < swflength; i++) {
        swfhistory.push('');
    }
    swfhistory.push(l.hash.replace(/^#/g, ''));

    if (browser.isIE() && l.hash != getHash()) {
        l.hash = '#' + getHash();
    }

    swfaddr = this.getValue();
    titleListener();
    asual.util.Events.addListener(window, 'load', asual.util.Functions.bindAsListener(load, this));
}
SWFAddress = asual.SWFAddress;

if (typeof deconcept != 'undefined' && deconcept.SWFObject) {
    asual.SWFAddressObject = asual.util.Functions.extend(deconcept.SWFObject, 
        function(swf, id, w, h, ver, c, quality, xiRedirectUrl, redirectUrl, detectKey) {
            asual.SWFAddressObject.superConstructor.apply(this, arguments);
            SWFAddress.setSWFObject(this);
            SWFAddress.setId(id);
            this.setAttribute('style', ';');
            if (this.getAttribute('version').major < 8)
                this.addVariable('$swfaddress', SWFAddress.getValue());
        }
    )
    SWFObject = deconcept.SWFObject = asual.SWFAddressObject;
}