YAHOO.namespace('zoeyui');

YAHOO.zoeyui.Page = function(pcm, element) {
    this.widgets = [];
    this.links = [];
    this.pcm = pcm;
}
/*
YAHOO.lang.extend(YAHOO.tunetrack.Page, YAHOO.util.Element, {
    addWidget: function(widget) {
        this.widgets[this.widgets.length] = widget;
    }, 
    loadHtml: function(html) {
        YAHOO.plugin.Dispatcher.process(this.get('element'), html);
        this.processDom();
    },
    processDom: function() {
        this.processLinks();
    },
    processLinks: function() {
        var links = YAHOO.util.Dom.getElementBy(function(){return true;}, 'a', this.get('element'));
        for (link_index in links) {
            try {
                var link = links[link_index];
                if (link != undefined) {
                    var page_link = new this.pcm.conf.page_link_type(this, link);
                    if (page_link.shouldHashify()) {
                        page_link.hashify();
                    }
                    this.links.append(page_link);
                }
            } catch(e) {
            }
        }
    },
    empty: function() {
        var i;
        for (i in this.widgets) {
            try {
                var widget = this.widgets[i];
                widget.destroy()
            } catch(e) {
            }
        }
        for (i in this.links) {
            try {
                var link = this.links[i];
                link.destroy()
            } catch(e) {
            }
        }
        this.widgets = [];
        this.links = [];
        this.get('element').innerHTML = '';
    }
});
*/

YAHOO.zoeyui.PageLink  = function(pcm, element) {
    this.pcm = pcm;
    YAHOO.zoeyui.PageLink.superclass.constructor.call(this, element);
}

YAHOO.lang.extend(YAHOO.zoeyui.PageLink, YAHOO.util.Element, {
    isLocal: function() {
        var href = this.get('href');
        return this.pcm.isLocalUrl(href);
    },
    getAbsolutePath: function() {
        var href = this.get('href');
        return href.replace(this.pcm.conf.site_url, '/');
    },
    shouldHashify: function() {
        if (this.isLocal()) {
            var path = this.getAbsolutePath();
            if (path.indexOf('#') != -1) {
                return false;
            }
            return true;
        }
        return false;
    },
    navigate: function() {
        var path = this.getAbsolutePath();
        this.pcm.navigate(path);
        if (!!(window.history && history.pushState)) {
            history.pushState(null, null, path);
        } else {
            window.location.hash = path;
        }
    },
    hashify: function() {
        this.on('click', function(e) {
            YAHOO.util.Event.preventDefault(e);
            YAHOO.util.Event.stopEvent(e);
            this.navigate();
        }, this); 
        return;
    },
    destroy: function() {
        this.unsubscribe('click'); 
    }

});

YAHOO.zoeyui.pcm_defaults = {
    page_container_id: 'doc',
    site_url: 'http://' + document.domain + '/',
    page_link_type: YAHOO.zoeyui.PageLink
};

YAHOO.zoeyui.PageContextManager = function(conf) {
    this.conf = YAHOO.lang.merge(YAHOO.zoeyui.pcm_defaults, conf);
    this.hash_href = this.conf.site_url + '#';
    this.request_status_indicator_id = 'request-status-indicator';
    this.content_transition_in = null;
    this.content_transition_out = null;
    this.style_element = null;
    this.style_url = null;
    this.widgets = [];
    var current_url = window.location + '';
    this.current_path = current_url.replace(this.conf.site_url, '/');
    this.fetching_path = null;
    YAHOO.zoeyui.pcm = this;
    var self = this;

    if (!!(window.history && history.pushState)) {
        window.onpopstate = function(e) {
            self.navigate(location.pathname);
        };
    }
};

YAHOO.zoeyui.PageContextManager.prototype = {
    fetch_stylesheet: function(stylesheet_url) {
        this.style_url = stylesheet_url;
        this.transitionOut();
        var req = YAHOO.util.Connect.asyncRequest('GET', stylesheet_url, {
            success: function(req) {
                var head = document.getElementsByTagName('head')[0];
                head = new YAHOO.util.Element(head);
                if (this.style_element != null) {
                    try {
                        head.removeChild(this.style_element);
                    } catch(e) {
                    }
                }
                var style_el = document.createElement('style');
                style = new YAHOO.util.Element(style_el);
                style.set('type', 'text/css');
                if (style_el.styleSheet) {
                    // IE Hack here, imagine that
                    style_el.styleSheet.cssText = req.responseText;
                } else {
                    style.appendChild(document.createTextNode(req.responseText));
                }
                head.appendChild(style);
                this.style_element = style;
                this.transitionIn();
            },
            failure: function(req) {
                this.style_element = null;
                this.style_url = null;
                this.transitionIn();
            },
            scope: this
        });
    },
    haltLoading: function() {
        var images = YAHOO.util.Dom.getElementsBy(function(){return true;}, 'img');
        var i = 0;
        for (i in images) {
            var image = images[i];
            image.removeAttribute('src');
        }
    },
    transitionOut: function() {
        try {
            var el = new YAHOO.util.Element(document.body);
            el.addClass('hijaxloading');
        } catch(e) {
        }
    },
    transitionIn: function() {
        try {
            var el = new YAHOO.util.Element(document.body);
            el.removeClass('hijaxloading');
        } catch(e) {
        }
    },
    navigate: function(absolute_path) {
        if(absolute_path == '' || absolute_path == null || this.current_path == absolute_path || this.fetching_path == absolute_path) {
            return;
        } else {

        }
        this.fetching_path = absolute_path;
        this.transitionOut();
        var url = this.getPageUrl(absolute_path);
        if (url.indexOf('?') == -1) {
            url = url + '?ajax=1';
        } else {
            url = url + '&ajax=1';
        }


        var req = YAHOO.util.Connect.asyncRequest('GET', url, {
            success: this.onNavigateSuccess,
            failure: this.onNavigateFailure,
            scope: this,
            argument: url
        }); 
    },
    getPageUrl: function(absolute_path) {
        return 'http://' + document.domain + absolute_path;
    },
    setStylesheet: function(stylesheet_url) {
        if (stylesheet_url == null && this.style_url != null) {
            var head = document.getElementsByTagName('head')[0];
            head = new YAHOO.util.Element(head);
            try {
                if (this.style_element != null) {
                    head.removeChild(this.style_element);
                }
            } catch(e) {
                //console.log(e);
            }
            this.style_element = null;
            this.style_url = null;
        } else if (stylesheet_url != this.style_url) {
            this.fetch_stylesheet(stylesheet_url);
        }
    },
    onNavigateSuccess: function(req) {
        this.destroyWidgets();                           
        this.fetching_path = null;
        this.transitionIn();
        YAHOO.plugin.Dispatcher.process(this.conf.page_container_id, req.responseText);
        this.processMarkup();
        try {
            pageTracker._trackPageview(this.current_path);
        } catch(e) {
            //console.log(e);
        }
        document.title = 'TuneTrack';
    },
    destroyWidgets: function() {
        var i;
        for (i in this.widgets) {
            try {
                this.widgets[i].destroy();
            } catch(e) {
            }
        }
        this.widgets = [];
    },
    processLinks: function() {
        var links = document.getElementsByTagName('a');
        for (link_index in links) {
            try {
                var link = links[link_index];
                if (link != undefined) {
                    var page_link = new this.conf.page_link_type(this, link);
                    if (page_link.shouldHashify()) {
                        page_link.hashify();
                    } 
                    this.widgets[this.widgets.count] = page_link;
                }
            } catch(e) {
                //console.log(e);
            }
        }
    },
    isLocalUrl: function(href) {
        if (href == undefined || href == null) {
            return false;
        }
        if (href.indexOf(this.conf.site_url) == 0 && href.indexOf(this.hash_href) != 0) {
            return true;
        }
        if (href.indexOf('/') == 0 ) {
            return true;
        }
        return false;
    },
    processMarkup: function() {
        this.processLinks();
    },
    onNavigateFailure: function(req) {
        this.fetching_path = null;
        this.transitionIn();
    }
};


