jQuery.getFeed = function (options) {
    options = jQuery.extend({
        url: null,
        data: null,
        success: null
    },
    options);
    if (options.url) {
        $.ajax({
            type: 'GET',
            url: options.url,
            data: options.data,
            dataType: 'xml',
            success: function (xml) {
                var feed = new JFeed(xml);
                if (jQuery.isFunction(options.success)) options.success(feed)
            }
        })
    }
};

function JFeed(xml) {
    if (xml) this.parse(xml)
};
JFeed.prototype = {
    type: '',
    version: '',
    title: '',
    link: '',
    description: '',
    parse: function (xml) {
        if (jQuery('channel', xml).length == 1) {
            this.type = 'rss';
            var feedClass = new JRss(xml)
        } else if (jQuery('feed', xml).length == 1) {
            this.type = 'atom';
            var feedClass = new JAtom(xml)
        }
        if (feedClass) jQuery.extend(this, feedClass)
    }
};

function JFeedItem() {};
JFeedItem.prototype = {
    title: '',
    link: '',
    description: '',
    updated: '',
    id: ''
};

function JAtom(xml) {
    this._parse(xml)
};
JAtom.prototype = {
    _parse: function (xml) {
        var channel = jQuery('feed', xml).eq(0);
        this.version = '1.0';
        this.title = jQuery(channel).find('title:first').text();
        this.link = jQuery(channel).find('link:first').attr('href');
        this.description = jQuery(channel).find('subtitle:first').text();
        this.language = jQuery(channel).attr('xml:lang');
        this.updated = jQuery(channel).find('updated:first').text();
        this.items = new Array();
        var feed = this;
        jQuery('entry', xml).each(function () {
            var item = new JFeedItem();
            item.title = jQuery(this).find('title').eq(0).text();
            item.link = jQuery(this).find('link').eq(0).attr('href');
            item.description = jQuery(this).find('content').eq(0).text();
            item.updated = jQuery(this).find('updated').eq(0).text();
            item.id = jQuery(this).find('id').eq(0).text();
            feed.items.push(item)
        })
    }
};

function JRss(xml) {
    this._parse(xml)
};
JRss.prototype = {
    _parse: function (xml) {
        if (jQuery('rss', xml).length == 0) this.version = '1.0';
        else this.version = jQuery('rss', xml).eq(0).attr('version');
        var channel = jQuery('channel', xml).eq(0);
        this.title = jQuery(channel).find('title:first').text();
        this.link = jQuery(channel).find('link:first').text();
        this.description = jQuery(channel).find('description:first').text();
        this.language = jQuery(channel).find('language:first').text();
        this.updated = jQuery(channel).find('lastBuildDate:first').text();
        this.items = new Array();
        var feed = this;
        jQuery('item', xml).each(function () {
            var item = new JFeedItem();
            item.title = jQuery(this).find('title').eq(0).text();
            item.link = jQuery(this).find('link').eq(0).text();
            item.description = jQuery(this).find('description').eq(0).text();
            item.updated = jQuery(this).find('pubDate').eq(0).text();
            item.id = jQuery(this).find('guid').eq(0).text();
            feed.items.push(item)
        })
    }
};

