/* makes window.addEvent('hashchange', function () {}); possible in all browsers */
Element.Events.hashchange = {
    onAdd: function () {
        var hash = self.location.hash;

        var hashchange = function(event) {
            if (hash == self.location.hash) return;
            else hash = self.location.hash;

            var value = (hash.indexOf('#') == 0 ? hash.substr(1) : hash);
            //window.fireEvent('hashchange', event);
            document.fireEvent('hashchange', event);
        };

        if ("onhashchange" in window){
            window.onhashchange = hashchange;
        }
        else {
            hashchange.periodical(50);
        }
    }
};

/* used to easily initialize our objects */
Map = {
    /* used for the form: $$(selector).each(function (ele) { new Object(ele, [params, ...]); } */
    ResolveObjects: function (mapping) {
        mapping.each(function (ele) {
            $$(ele.selector).each(function (i) {
                new ele.type(i);
            });
        });
    }
}
/* this is a map of request queues  that need to fire
 * in order of priority 
 * default is 3 unless otherwise specified for lazy load
 * and ajax request classes
 **/
RequestMap = {
    init: function(){
        this.map = [];
        this.map[1] = new Array();
        this.map[2] = new Array();
        this.map[3] = new Array();
        this.map[4] = new Array();
        this.runningRequest = false;
        this.currentRequest = null;
        // set to lowest priority
        this.currentPriority = 4;
        this.checkForRequests();
    },
    addRequest: function(request,priority){
        
        this.map[parseInt(priority)].push(request);
        this.checkForRequests();
    },
    checkForRequests: function(){
        var requestToRun = null;
        var requestPriorityRequested = false;
       
        if(this.map[1].length){
            //requestToRun = this.map['1'].shift();
            requestPriorityRequested = 1;
        }else if(this.map[2].length){
            //requestToRun = this.map['2'].shift();
            requestPriorityRequested = 2;
        }else if(this.map[3].length){
            //requestToRun = this.map['3'].shift();
            requestPriorityRequested = 3;
        }
        else if(this.map[4].length){
            //requestToRun = this.map['3'].shift();
            requestPriorityRequested = 4;
        }
        // did we find a request to run?
        if(requestPriorityRequested){
            // are we already running a request?
            if(this.runningRequest){
                // if we are then check the priority
                // is the priority of the request we want to run higher than the one we are currently running?
                if(requestPriorityRequested < this.currentPriority){
                    //we need to interrupt the current request and get the new request to run
                    if(this.currentRequest.isRunning()){
                        
                        this.currentRequest.cancel();
                        this.currentRequest.removeEvent('complete',this.finishedRequest.bind(this));
                       
                        this.map[this.currentPriority].unshift(this.currentRequest);
                        
                    }
                    requestToRun = this.map[requestPriorityRequested].shift();
                    requestToRun.addEvent('complete',this.finishedRequest.bind(this));
                    this.runningRequest = true;
                    this.currentRequest = requestToRun;
                    this.currentPriority = requestPriorityRequested;
                    requestToRun.send(); 
                           
                }
                // if the request priority is not higher than the one currently running then dont interrupt
            }else{
                // if not then just run this request
                requestToRun = this.map[requestPriorityRequested].shift();
                requestToRun.addEvent('complete',this.finishedRequest.bind(this));
                this.runningRequest = true;
                this.currentRequest = requestToRun;
                this.currentPriority = requestPriorityRequested;
                requestToRun.send(); 
            }
            
            
        }else{
            this.runningRequest = false;
            this.currentPriority = 4;
        }
        
        
    },
    finishedRequest: function(){
        this.runningRequest = false;
        this.currentRequest = null;
        this.currentPriority = 4;
        this.checkForRequests();
    }
};
RequestMap.init();

var AHashUpdate = new Class({
    initialize: function (element) {
        var lis = $(element).getChildren(); // the li tags
        var new_hash = window.location.hash.replace('#', '');

        $$('a.sort_link').each(function (a) {
            var index = a.getProperty('href').indexOf('#')+1;
            var current_hash = a.getProperty('href').substr(index);

            a.setProperty('href', a.getProperty('href').replace(current_hash, new_hash));
        });

        lis.each(function (li) {
            li.getFirst().addEvent('click', function (e) {
                $$('a.sort_link').each(function (a) {
                    var index = a.getProperty('href').indexOf('#')+1;
                    var current_hash = a.getProperty('href').substr(index);

                    var new_hash = e.target.getProperty('href').replace('#', '');

                    a.setProperty('href', a.getProperty('href').replace(current_hash, new_hash));
                });
            });
        });
    }
});

var Tabs = new Class({
    initialize: function (element, options) {
        this.e = $(element);
        if (!this.e)
            return;

        /* set up options */
        if (options)
            this.onFinish = options.onFinish ? options.onFinish.bind(this) : function () {};
        else
            this.onFinish = function () {};

        this.default_tab = this.e.getProperty('sel') || 'summary';       
        this.min_height = this.e.getSize().y || 30;
        
        this.children = this.e.getChildren(); // li elements
        this.current_hash = this.getCurrentHash();
        this.interval = false;
        this.loading = false;

        this.setObserves();

        // load up initial tab
        this.active_tab = this.current_hash;
        this.active_li = this.children[0];
        this.findActiveLi();

        /* make sure content still shows up if we're not using hash/nesting */
        if (this.e.hasClass('no_hash')) {
            this.active_tab = this.default_tab;
            this.setTab(this.default_tab);
        } else {
            this.setTab(this.current_hash);
        }
    },
    findActiveLi: function () {
        this.children.each(function (li) {
            if (li.getFirst().getProperty('href').replace('#', '') == this.current_hash) {
                this.active_li = li;
            }
        }.bind(this));
    },
    setObserves: function () {
        this.children.each(function (child) {
            child.getFirst().addEvent('click', this.load.bind(this));
            var imgs = child.getFirst().getChildren('img');
            imgs.each(function(i){
                i.addEvent('click',this.loadFromImage.bind(this));
            }.bind(this));
        }.bind(this));

        /* make sure that anything changing the hash cause a tab move
         * this helps with the back button */
        if (!this.e.hasClass('no_hash')) {
            document.addEvent('hashchange', function () {
                this.current_hash = this.getCurrentHash();

                /* find active li */
                this.children.each(function (li) {
                    if (li.getFirst().getProperty('href').replace('#', '') == this.current_hash) {
                        this.active_li = li;
                    }
                }.bind(this));

                this.setTab(this.current_hash);
            }.bind(this));
        }
    },
    getCurrentHash: function () {
        hash = location.hash ? location.hash : window.location.hash;
        if (!hash) {// default if no hash listed
            hash = this.default_tab;
        }
        return hash.replace('#', '');
    },
    loadFromImage: function(event){
        event.stop();
        var a = $(event.target).getParent();
        var dest = a.getProperty('href').replace('#', ''); // the hash in the link w/o the #

        // let everyone know which li to modify
        this.active_li = a.getParent();

        if (!this.e.hasClass('no_hash'))
            window.location.hash = dest; // triggers hashchange event

        this.setTab(dest);

        a.blur();
    },
    load: function (event) {
        if(event.stop){
           event.stop();
            var a = $(event.target); // the element that was clicked 
        }else{
            var a = event;
        }
        
        var dest = a.getProperty('href').replace('#', ''); // the hash in the link w/o the #

        // let everyone know which li to modify
        this.active_li = a.getParent();

        if (!this.e.hasClass('no_hash'))
            window.location.hash = dest; // triggers hashchange event

        this.setTab(dest);

        a.blur();
    },
    setTab: function (active_id) {
        // select a tab from query parameter or initial load, not from click event
        this.hideTabs();
        this.showTab(active_id);
        this.onFinish();
    },
    hideTabs: function () {
        this.children.each(function (child) {
            var id = child.getFirst().getProperty('href').replace('#', '');
            var data = $(id+'_tab');
            if (data) {
                child.removeClass('current');
            }
            data.setStyle('display', 'none');
        });
    },
    showTab: function (id) {
        var ele = $(id + '_tab');

        // don't try to set a tab that doesn't exist
        if (!ele) {
            if (this.e.getProperty('sel')) {
                id = this.default_tab;
                ele = $(id + '_tab');
            }
            // @TODO: make this work ...
            else if (this.e.hasClass('default:login')) {
                // try to get it from a class name instead of sel attribute

            }
        }

        //ele.setStyle('display', 'block');
        //ele.setStyle('opacity', 0);
        //new Fx.Morph(ele, {duration: 300}).start({
        //    'opacity': 1
        //});
        ele.show();
        
        var children = ele.getElements('.load_on_show');
        children.each(function(c){
            var r = new Request.HTML({
                url: c.getProperty('url'),
                update: c
            });
            
            RequestMap.addRequest(r,'1');
            c.removeClass('load_on_show');
  
        });

        $(this.active_li).addClass('current');
        this.active_tab = id;

        if (this.e.hasClass('match_height')) {
            if (ele.getSize().y > this.min_height) {
                this.e.setStyle('height', ele.getSize().y);
            } else {
                this.e.setStyle('height', this.min_height);
            }
        }
    }
});

var VerticalTabs = new Class({
    initialize: function (element) {
        this.e = $(element);
        if (!this.e)
            return;
        this.children = this.e.getChildren();
        this.interval = false;
        this.active_tab = this.e.getProperty('sel') || this.default_tab;

        this.setObserves();
        // load up initial tab
        this.setTab(this.active_tab);

    },
    setObserves: function () {
        this.children.each(function (child) {
            child.getFirst().addEvent('click', this.load.bind(this));
            child.getChildren().each(function(c){
                c.addEvent('click', this.load.bind(this));
            }.bind(this));
        }.bind(this));

    },
    load: function (a) {
        this.hideTabs();
        this.showTab(a.target.rel || a.target.getParent().rel || this.active_tab);
        $(a.target).blur();
    },
    setTab: function (active_id) {
        // select a tab from query parameter or initial load, not from click event
        this.hideTabs();
        this.showTab(active_id);

    },
    hideTabs: function () {
        this.children.each(function (child) {
            var data = $(child.get('id')+'_tab');
            if (data) {
                child.removeClass('current');
            }
            data.setStyle('display', 'none');
        });
    },
    showTab: function (id) {
        var ele = $(id + '_tab');
        // don't try to set a tab that doesn't exist
        if (!ele){
            id= this.e.getProperty('sel') || 'summary';
        }

        ele.setStyle('display', 'block');
        ele.setStyle('opacity', 0);
        new Fx.Morph(ele, {duration: 300}).start({
            'opacity': 1
        });

        $(id).addClass('current');
        this.active_tab = id;
    }
});

var FollowButton = new Class({
    initialize: function (form) {
        this.form = $(form);
        if (!this.form)
            return;

        this.form.addEvent('submit', this.process.bind(this));
    },
    process: function (e) {
        e.preventDefault();
        new Form.Request(this.form, 'follow_div_'+ this.form.type.value + '_' + this.form.id.value, {
            onSuccess: function () {
                $$('.follow_button').each(function (form) {
                    new FollowButton(form);
                });
            },
            onComplete: function () {
                alert('done');
            }
        }).send();
    }
});

var AgreeButton = new Class({
    initialize: function (a) {
        this.a = $(a);
        if (!this.a)
            return;
        this.type = parseInt(this.a.rel);
        this.id = this.a.rel.replace(this.type+'_', '');

        this.a.addEvent('click', this.process.bind(this));
    },
    process: function (e) {
        e.stop();
        new Request.HTML({
            url: this.a.href,
            update: $('agree_'+this.type+'_'+ this.id),
            data: {
                type: this.type,
                id: this.id
            },
            onSuccess: function (tree, elems) {
                /* reset the event handlers */
                var buttons = elems.filter(function (elem) {
                    return elem.hasClass('agree');
                });
                buttons.each(function (a) {
                    new AgreeButton(a);
                });
            }.bind(this)
        }).send();
    }
});

// @TODO: finish this
var ModalLink = new Class({
    /**
     * @param an anchor element or anchor element id
     */
    initialize: function (a) {
        this.a = $(a);
        this.url = this.a.get('href');
    },
    /**
     * load all event observers to respond to user interaction
     */
    loadEvents: function () {
        this.a.addEvent('click', this.handleClick.bind(this));
    },
    /**
     * handle the click event.
     * @param Event
     */
    handleClick: function (event) {
        event.stop();

        this.show();
    },
    /**
     * show the modal window
     */
    show: function () {
        // show modal with spinning loader
    }
});

var ModalButton = new Class({
    initialize: function (b, title, url) {
        this.title = title;
        this.url = url;
        b.addEvent('click', this.click.bind(this));
    },
    click: function (e) {
        e.stop();

        this.buildModal();
        this.request();
    },
    buildModal: function () {
        options = {
            'parentEl': $$('body')[0],
            'title': this.title,
            'content': '...loading...',
            'width': 300
        }

        if (this.height)
            options.height = this.height;
        if (this.width)
            options.width = this.width;

        this.modal = new Modal(options);
    },
    request: function () {
        // gather the form
        new Request({
            url: this.url,
            method: 'get',
            onSuccess: function (responseText) {
                if (this.modal)
                    this.modal.setContent(responseText);
                this.success();
            }.bind(this),
            evalScripts: true
        }).send();
    },
    success: function () {
        
    }
});

var RegisterButton = new Class({
    Extends: ModalButton,
    initialize: function (b) {
        this.init(b, 'Register', '/user/register');
    },
    init: function (b, title, url) {
        b.addEvent('click', function (e) {
            e.stop();

            var modal = new Modal({
                'parentEl': $$('body')[0],
                'title': title,
                'content': '...loading...',
                'width': 800,
                'height': 400
            });

            // gather the form
            new Request({
                url: url,
                method: 'get',
                onSuccess: function (responseText) {
                    modal.setContent(responseText);
                    this.success();
                }.bind(this),
                evalScripts: true
            }).send();
        }.bind(this));
    }
});

var SigninButton = new Class({
    Extends: ModalButton,
    initialize: function (b) {
        var url = $(b).getProperty('href') || '/sfGuardAuth/signin';
        this.parent(b, 'Sign In', url);
        this.height = 200;
        this.width = 520;
    },
    request: function () {
        if (window.mobile_app)
            window.location = '/login';
        else
            this.parent();
    }
});

var StarRater = new Class({
    initialize: function (ele, highlight_one) {
        var children = ele.getChildren();
        highlight_one = highlight_one ? highlight_one : false;
        locked = children[4] ? children[4].get('value') : false;
        new Stars(ele, {
            average: children[0].get('value'),
            id: children[1].get('value'),
            type: children[2].get('value')
        }, {
            onRate: function (rating) {
                // call some ajax here to handle rating an object
                new Request({
                    url: children[3].get('value')
                }).send('rating='+rating+'&parent_id='+children[1].get('value')+'&type='+children[2].get('value'));
            },
            highlight_one: highlight_one,
            locked: locked
        });
    }
});

var Slant = new Class({
    initialize: function (ele, score) {
        this.e = $(ele);
        this.img = this.e.getChildren()[0];
        this.orig_src = this.img.src;
        this.score = score;
        this.orig_score = score;

        /* get images */
        this.images = this.getSlantImages();

        this.setImageFromSrc(this.getImgSrcFromScore(this.score));

        this.e.addEvent('mousemove', this.hover.bind(this));
        this.e.addEvent('mouseout', this.revert.bind(this));
        this.e.addEvent('click', this.rank.bind(this));
    },
    getSlantImages: function () {
        var images = $H({
            far_left: new Image(),
            moderate_left: new Image(),
            neutral: new Image(),
            moderate_right: new Image(),
            far_right: new Image()
        });

        images.far_left.src = '/images/img_slant_far_left.png';
        images.moderate_left.src = '/images/img_slant_moderate_left.png';
        images.neutral.src = '/images/img_slant_neutral.png';
        images.moderate_right.src = '/images/img_slant_moderate_right.png';
        images.far_right.src = '/images/img_slant_far_right.png';

        return images;
    },
    hover: function (e) {
        this.showPosition(e.client.x-this.e.getPosition().x);
    },
    showPosition: function (x) {
        if (x < 38) {
            this.setImage(this.images.far_left);
            this.score = 1;
        }
        else if (x >= 38 && x < 71) {
            this.setImage(this.images.moderate_left);
            this.score = 2;
        }
        else if (x >= 71 && x < 100) {
            this.setImage(this.images.neutral);
            this.score = 3;
        }
        else if (x >= 100 && x < 129) {
            this.setImage(this.images.moderate_right);
            this.score = 4;
        }
        else if (x >= 129) {
            this.setImage(this.images.far_right);
            this.score = 5;
        }
    },
    setImage: function (img) {
        this.img.src = img.src;
    },
    setImageFromSrc: function (src) {
        this.img.src = src;
    },
    revert: function () {
        this.img.src = this.orig_src;
    },
    rank: function () {
        var children = this.e.getChildren();
        new Request({
            url: children[4].value
        }).send('rating='+this.score+'&parent_id='+children[2].get('value')+'&type='+children[3].get('value'));
        this.orig_src = this.getImgSrcFromScore(this.score);
    },
    getImgSrcFromScore: function (score) {
        if (score == 1)
            return this.images.far_left.src;
        else if (score == 2)
            return this.images.moderate_left.src;
        else if (score == 3)
            return this.images.neutral.src;
        else if (score == 4)
            return this.images.moderate_right.src;
        else if (score == 5)
            return this.images.far_right.src;
        else
            return this.orig_src;
    }
})

//*************************************
//Pager class that can be added to any html table
// it will ignore any thead or tfoot data and leave that static
// and paginate the tbody data
// the table must have a class of pagedTable and have an id that is unique on the page
// allowing for multiple paged tables on an html page
// it must have a pager reference to a div id where the pagination navigation
// will be placed below the table
// optionally you can pass into the table and showPerPage option to default the number of
// rows per page otherwise it will default to 10
var Pager = new Class({
    initialize: function(tableName) {
        // the id of the table we are paging
        this.tableName = tableName;

        if (!$(this.tableName))
            return;

        // the id of the page navigation div
        this.navName = $(this.tableName).getProperty('pager') || null;
        if(!this.navName){
            return null;
        }
        // the number of items per page, default to 10 or pass in from a table parameter
        this.itemsPerPage = parseInt($(this.tableName).getProperty('showPerPage')) || 10;
        this.currentPage = 1;
        this.pages = 0;
        // the initial table rows
        this.rows = $(this.tableName).getElement('tbody') ? $(this.tableName).getElement('tbody').rows : 0;
        if (this.rows.length > this.itemsPerPage){
            this.setUpPages();
        }
    },
    setUpPages: function(){
        // get total # of records
        var records = (this.rows.length);
        this.pages = Math.ceil(records / this.itemsPerPage);
        this.setUpPageNav();
        this.showPage(this.currentPage);
    },
    setUpPageNav: function() {
        var element = $(this.navName);

        // create prev link
        var ele = new Element('span',{
            id: this.navName+"prev",
            html: "&#171 Prev&nbsp;|"
        });
        ele.setProperty('class',"pg-normal");
        ele.addEvent('click', this.prev.bind(this));
        ele.inject(element);

        // create page links
        this.pageLinks = new Element('span',{
            id: this.navName+"pagelinks"
            });

        var pglnk;
        for (var page = 1; page <= this.pages; page++){

            pglnk = new Element('span', {
                id:this.navName+page,
                html:"&nbsp;" + page
                });
            pglnk.setProperty('class',"pg-normal");
            pglnk.setProperty('page', page);
            pglnk.addEvent('click', this.show.bind(this));
            pglnk.setProperty('style','display:none');
            pglnk.inject(this.pageLinks);
        }
        this.pageLinks.inject(element);
        // create next link
        ele = new Element('span',{
            id: this.navName+"next",
            html:"&nbsp;|&nbsp;Next &#187;"
        });
        ele.setProperty('class', "pg-normal");
        ele.addEvent('click', this.next.bind(this));
        ele.inject(element);
    },
    showRecords: function(from, to) {
        for (var i = 0; i < this.rows.length; i++) {
            if (i < from || i > to)
                this.rows[i].style.display = 'none';
            else
                this.rows[i].style.display = '';
        }
    },
    showPage: function(pageNumber) {

        var oldPageAnchor = $(this.navName+this.currentPage);
        oldPageAnchor.setProperty('class',"pg-normal");

        this.currentPage = pageNumber;
        var newPageAnchor = $(this.navName+this.currentPage);
        newPageAnchor.setProperty('class', "pg-selected");

        var from = (pageNumber - 1) * this.itemsPerPage ;
        var to = from + this.itemsPerPage - 1;
        this.showRecords(from, to);
        this.updatePageNav(pageNumber);
    },
    prev: function() {
        if (this.currentPage > 1)
            this.showPage(parseInt(this.currentPage) - 1);
    },
    next: function() {

        if (this.currentPage < this.pages) {
            this.showPage(parseInt(this.currentPage) + 1);
        }
    },
    show: function(a) {
        this.showPage(a.target.getProperty('page'));
    },

    updatePageNav: function(sel){

        // our range of numbers to show is 10 for now
        var from = parseInt(sel)-5;
        var to = parseInt(sel)+5;
        var left = 0;
        var right = 0;

        if (from < 0){
            // try to rebalance by adding to the "to" portion
            left = -(from);
        }
        if (to > this.pages){
            // try to rebalance by adding to the "from" portion
            right = (to-this.pages);
        }


        if (left || right){

            if (from < 0){
                // pad right
                to += left;
            }else {
                // pad left
                from -= right;
            }
        }
        // final bounds checking
        if (from < 0){
            from = 0;
        }
        if (to > this.pages)
            to = this.pages;
        var pages = $(this.pageLinks).getChildren();

        for (var i = 0; i < pages.length; i++) {
            if (i < from || i >= to){
                pages[i].style.display = 'none';

            }
            else{
                pages[i].style.display = '';

            }
        }
    }
});

/* Create nice graphs using the canvas element */
var CanvasGraph = new Class({
    initialize: function (canvas, data, options) {
        this.canvas = $(canvas);
        if (!this.canvas)
            return;
        this.context = this.canvas.getContext('2d');
        this.data = data;
        this.options = $H(options);
        this.height = 100;
        this.width = 400;
        this.offset = 20;
        this.x_iterations = 30;
        this.y_iterations = 10;
        this.points = new Array();
        this.click_radius = 3;

        /* this div is used to display values to the user */
        this.div = new Element('div', {
            'class': 'graph_overlay'
        });
        $$('body')[0].grab(this.div);

        // handlers
        //this.canvas.addEvent('click', this.canvasClicked.bind(this));
        this.canvas.addEvent('mousemove', this.canvasMouseMoved.bind(this));

        // set the actual height and width of the canvas to match our settings more closely
        this.canvas.height = this.height+this.offset;
        this.canvas.width = this.width+this.offset+10; // the 10 is a right buffer

        this.drawGrid(this.height, this.width);
        this.plotPoints();
    },
    canvasClicked: function (e) {
        var x = e.event.offsetX;
        var y = e.event.offsetY;
        this.points.each(function (point) {
            if (point.coordsMatch(x, y, this.click_radius)) {
        // make the point do stuff
        }
        }.bind(this));
    },
    canvasMouseMoved: function (e) {
        var x = e.event.offsetX;
        var y = e.event.offsetY;
        this.points.each(function (point) {
            if (point.coordsMatch(x, y, this.click_radius)) {
                point.highlight(this.div);
            }
            else {
                point.removeHighlight(this.div, this);
            }
        }.bind(this));

        // also move the div to next to the mouse
        this.div.setStyle('top', e.event.clientY+3);
        this.div.setStyle('left', e.event.clientX+10);
    },
    plotPoints: function () {
        var x_multiplyer = this.width/this.x_iterations;
        var x_offset = x_multiplyer+this.offset;
        this.data.each(function (d, index) {
            var x = index*x_multiplyer+x_offset;
            var y = this.height-d.count;
            this.points.push(new CanvasPoint(x, y, this.context, {
                x: d.day,
                y: d.count,
                x_label: this.options.label
            }));
        }.bind(this));
        this.drawPoints();
    },
    drawPoints: function () {
        this.points.each(function (point, index) {
            point.draw();
            if (this.points[index+1] && index+1 < 30)
                point.connect(this.points[index+1]);
        }.bind(this));
    },
    drawGrid: function (height, width) {
        // x and y lines
        this.context.beginPath();
        this.context.moveTo(this.offset, 0);
        this.context.lineTo(this.offset, height);
        this.context.lineTo(width+this.offset+1, height); // the 1 resolves a 1 px gap
        this.context.stroke();

        // hashes on x line
        this.context.beginPath();
        var current_x = this.offset+this.width/30;
        this.context.moveTo(current_x, height);
        for (i = 0; i < this.x_iterations; i++) {
            this.context.lineTo(current_x, height+5);
            current_x += this.width/this.x_iterations;
            this.context.moveTo(current_x, height);
        }
        this.context.stroke();

        // hashes on the y line
        this.context.beginPath();
        var current_y = 0;
        this.context.moveTo(this.offset, current_y);
        for (i = 0; i < this.y_iterations; i++) {
            this.context.lineTo(this.offset-5, current_y);
            current_y += this.height/this.y_iterations;
            this.context.moveTo(this.offset, current_y);
        }
        this.context.stroke();
    },
    drawXLine: function (width) {

    }
});

var CanvasPoint = new Class({
    initialize: function (x, y, ctx, values) {
        this.context = ctx;
        this.x = x;
        this.x_value = values.x;
        this.y = y;
        this.y_value = values.y;
        this.x_label = values.x_label;
        this.highlighted = false;
        this.radius = 2.5;
    },
    draw: function () {
        this.context.beginPath();
        this.context.arc(this.x, this.y, this.radius, 0, Math.PI*2, false);
        this.context.fill();
    },
    position: function () {
        return this.x+', '+this.y;
    },
    coordsMatch: function (x, y, match_radius) {
        return (x >= this.x-match_radius && x <= this.x+match_radius &&
            y >= this.y-match_radius && y <= this.y+match_radius);
    },
    highlight: function (target) {
        if (!this.highlighted) {
            target.set('html', this.x_value + '<br />'+this.x_label+': <strong>'+ this.y_value +'</strong>');
            target.setStyle('display', 'block');
            this.context.beginPath();
            this.context.arc(this.x, this.y, this.radius+3, 0, Math.PI*2);
            this.context.stroke();
            this.highlighted = true;
        }
    },
    removeHighlight: function (target, graph) {
        if (this.highlighted) {
            // we need to redraw the graph
            graph.context.clearRect(0, 0, graph.canvas.width, graph.canvas.height);
            graph.drawGrid(graph.height, graph.width);
            graph.drawPoints(); // drawPoints, not plotPoints .. since they're already plotted

            target.setStyle('display', 'none');

            this.highlighted = false;
        }
    },
    connect: function (point) {
        this.context.beginPath();
        this.context.moveTo(this.x, this.y);
        this.context.lineTo(point.x, point.y);
        this.context.stroke();
    }
});

var ExternalOpener = new Class({
    external_holder: 'http://localhost/external/link',
    initialize: function (ele) {
        this.e = $(ele);
        if (!this.e)
            return

        this.e.addEvent('click', this.open.bind(this));
    },
    open: function (e) {
        e.stop();
        var group_id = this.e.rel.replace('group_', '');
        var escaped_url = escape(this.e.href).replace(/\+/g,'%2B').replace(/%20/g, '+').replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40');
        var link = this.external_holder + '?group_id=' + group_id + '&url=' + escaped_url;
        var win = window.open(link);
    }
});

var Modal = new Class({
    Implements: [Options],
    options:{
        parentEl: '',
        title: '',
        subTitle: '',
        content: '',
        height: 175,
        width: 800,
        closeButton: true
    },
    initialize: function(options){
        this.setOptions(options);
        this.SaveButtonId = '';
        this.drawModal();
    },
    drawModal: function(){

        $('container').setStyle('opacity', .5);

        // create surounding divs
        var ModalElement = null;
        if(typeof(this.options.parentEl)=='string'){
            ModalElement = new Element('div',{
                'class' : 'generic_dialog',
                'id' : 'fb-modal'
            }).inject($(this.options.parentEl),'bottom');
        }
        else if(typeof(this.options.parentEl)=='object'){
            ModalElement = new Element('div',{
                'class' : 'generic_dialog',
                'id' : 'fb-modal'
            }).inject(this.options.parentEl,'bottom');
        }
        new Element('div',{
            'class' : 'generic_dialog_popup',
            'id' : 'fb-modal2'
        }).inject($('fb-modal'),'top');

        // create table
        new Element('table',{
            'class' : 'pop_dialog_table',
            'id' : 'fb-pop_dialog_table'
        }).inject($('fb-modal2'),'top');

        new Element('tbody',{
            'id' : 'fb-table-body'
        }).inject($('fb-pop_dialog_table'),'top');

        $('fb-modal').setStyles({
            opacity:0,
            display:'block'
        });

        // third row
        new Element('tr',{
            'class' : '',
            'id' : 'fb-tr3'
        }).inject($('fb-table-body'),'top');

        new Element('td',{
            'class' : 'pop_bottomright'
        }).inject($('fb-tr3'),'top');

        new Element('td',{
            'class' : 'pop_border pop_bottom'
        }).inject($('fb-tr3'),'top');

        new Element('td',{
            'class' : 'pop_bottomleft'
        }).inject($('fb-tr3'),'top');

        // second row
        new Element('tr',{
            'class' : '',
            'id' : 'fb-tr2'
        }).inject($('fb-table-body'),'top');

        new Element('td',{
            'class' : 'pop_border pop_side'
        }).inject($('fb-tr2'),'top');

        new Element('td',{
            'class' : 'pop_content',
            'id' : 'pop_content'
        }).inject($('fb-tr2'),'top');

        // title
        new Element('h2',{
            'class' : 'dialog_title',
            'id' : 'dialog_title',
            'text' : this.options.title
        }).inject($('pop_content'),'top');

        // modal body
        new Element('div',{
            'class' : 'dialog_content',
            'id' : 'dialog_content'
        }).inject($('pop_content'),'bottom');

        // sub title
        new Element('div',{
            'class' : 'dialog_summary',
            'id' : 'ModalSubTitle',
            'html' : this.options.subTitle
        }).inject($('dialog_content'),'top');

        // modal content wrapper
        new Element('div',{
            'class' : 'dialog_body',
            'id' : 'dialog_content_wrapper',
                'styles':
                {
                    'height' : this.options.height+'px'
                }
        }).inject($('dialog_content'),'bottom');

        // modal content uber wrapper
        new Element('div',{
            'class' : 'ubersearch search_profile',
            'id' : 'uber_content_wrapper'
        }).inject($('dialog_content_wrapper'),'bottom');

        // finally the real content area
        new Element('div',{
            'class' : 'result clearfix',
            'id' : 'ModalContent',
            'html' : this.options.content,
            'styles':
            {
                'height' : this.options.height+'px',
                'overflow-y' : 'auto'
            }
        }).inject($('uber_content_wrapper'),'bottom');

        // modal footer
        new Element('div',{
            'class' : 'dialog_buttons',
            'id' : 'dialog_buttons',
            'html' : ''
        }).inject($('dialog_content'),'bottom');

        /*		$(document).addEvent('click',function(e) {
			try{
				if($('fb-modal').get('opacity') == 1 && !e.target.getParent('.generic_dialog')) {
					$('fb-modal').fade('out');
					$('fb-modal').destroy();
				}
			}
			catch(err){}
		});*/

        new Element('td',{
            'class' : 'pop_border pop_side'
        }).inject($('fb-tr2'),'top');

        // first row
        new Element('tr',{
            'class' : '',
            'id' : 'fb-tr1'
        }).inject($('fb-table-body'),'top');

        new Element('td',{
            'class' : 'pop_topright'
        }).inject($('fb-tr1'),'top');

        new Element('td',{
            'class' : 'pop_border pop_top'
        }).inject($('fb-tr1'),'top');

        new Element('td',{
            'class' : 'pop_topleft'
        }).inject($('fb-tr1'),'top');

        $('fb-modal').set({
            'styles':
            {
                'margin-top' : window.getScroll().y+25,
                'display' : 'block'
            }
        });
        $('fb-pop_dialog_table').set({
            'styles':
            {
                'width' : this.options.width+'px'
            }
        });
        $('fb-modal').fade('in');

        if(this.options.closeButton){
            this.createCloseButton();
        }
        
        // prevents modal from overflowing the x and y screen
        var winSize = $(document.body).getSize();
        var modalSize = $('fb-pop_dialog_table').getSize();

        var yOffset = (modalSize.y+5) - winSize.y;
        var xOffset = (modalSize.x+5) - winSize.x;
        var uberSize = $('uber_content_wrapper').getSize();

        if(yOffset > 0){
            $('uber_content_wrapper').setStyle('height', uberSize.y-(yOffset+5));
        }
        if(xOffset > 0){
            $('uber_content_wrapper').setStyle('width', uberSize.x-(xOffset+5));
        }   
    //alert(xOffset+' '+yOffset);


    },
    createCloseButton: function(){
        // modal footer
        new Element('a',{
            'href' : 'javascript:void(0);',
            'id' : 'FbClose',
            'value' : 'Close',
            'html' : 'x',
            'styles': {
                'float': 'right',
                'color': '#444'
            },
            'events' : {
                'click' : function(e){
                    e.stop();
                    $('fb-modal').setStyle('opacity',1);
                    $('fb-modal').destroy();
                    $('container').setStyle('opacity', 1);
                }
            }
        }).inject($('dialog_title'),'top');
    },
    /**
	 * createSaveButton
	 * @param id(str),value(str)
	 * @return void
	 */
    createSaveButton: function(id,value){
        if(value == undefined){
            value = 'Save';
        }

        new Element('input',{
            'type' : 'button',
            'id' : id,
            'value' : value
        }).inject($('dialog_buttons'),'bottom');

        this.SaveButtonId = id;
    },
    destroySaveButton: function(){
        try{
            $(this.SaveButtonId).destroy();
        }
        catch(err){}
    },
    setTitle: function(str){
        $('pop_content').innerHTML = str;
    },
    setSubTitle: function(str){
        $('ModalSubTitle').innerHTML = str;
    },
    setContent: function(str){
        $('ModalContent').innerHTML = str;
    },
    isModalVisible: function(){
        if($('fb-modal')){
            return 1;
        }
        else{
            return 0;
        }
    },
    /**
	 * destroy: destroys this instance of facebook modal
	 * @param void
	 * @return void
	 */
    destroy: function(){
        try{
            $('fb-modal').fade('out');
        }
        catch(err){}

        try{
            $('fb-modal').destroy();
        }
        catch(err){}

        this.isVisible = 0;

    }
});

var Stars = new Class({
    initialize: function (ele, data, json) {
        this.element = $(ele);
        this.average = data.average;
        this.parent_id = data.id;
        this.parent_type = data.type;
        this.image_path = '/images/starbox/';
        this.star = new Array();
        this.locked = false;
        this.revote = true;
        this.highligh_one = false;

        if (json) {
            this.json = json;
        }
        else {
            this.json = false;
        }
        this.setOptions();
        this.setAverage(this.average);
        this.buildHTML();
        this.setObserve();
    },
    setOptions: function () {
        if (this.json.stars) {
            this.stars = this.json.stars;
        }
        else {
            this.stars = 5;
        }

        /* Set Star width/height */
        if (this.json.star_width) {
            this.star_width = this.jason.star_width;
        }
        else {
            this.star_width = '23';
        }
        if (this.json.star_height) {
            this.star_height = this.jason.star_height;
        }
        else {
            this.star_height = '22';
        }

        this.total_width = Math.floor(this.star_width * this.stars);
        var cur_width = this.total_width;
        for (var i = this.stars; i >= 1; i--) {
            cur_width = cur_width - this.star_width;
            this.star[i] = cur_width;
        }

        if (this.json.star_image) {
            this.star_image = this.image_path+this.json.star_image;
        }
        else {
            this.star_image = this.image_path+'pointy.png';
        }
        if (this.json.locked == true) {
            this.locked = true;
        }
        if (this.json.revote == false) {
            this.revote = false;
        }
        if (this.json.highlight_one)
            this.highlight_one = true;
    },
    setAverage: function (average) {
        this.average = Math.floor((this.stars - average)*this.star_width);
    /*
        if (this.highlight_one) {

        }
        */
    },
    buildHTML: function(){
        this.element.addClass('starbox');

        var div1 = new Element('div', {
            'styles': {
                'position': 'relative'
            },
            'class': 'default'
        });
        var div2 = new Element('div', {
            'class': 'rated'
        });
        var div3 = new Element('div', {
            'class': ''
        });
        var div4 = new Element('div', {
            'styles': {
                'overflow': 'hidden',
                'position': 'relative',
                'width': this.total_width+'px',
                'height': this.star_height+'px'
            },
            'class': 'stars'
        });
        /* this is the yellow bar */
        var div5_left = (this.highlight_one) ? this.average+'px' : '-'+this.average+'px';
        var div5 = new Element('div', {
            'id': 'anonymous_element_2',
            'styles': {
                'position': 'absolute',
                'top': '0pt',
                'left': div5_left,
                'width': (this.highlight_one?this.star_width:this.total_width)+'px',
                'height': this.star_height+'px'
            },
            'class': 'colorbar'
        });
        var div6 = new Element('div', {
            'styles': {
                'position': 'absolute',
                'top': '0pt',
                'left': '0pt',
                'width': this.total_width+'px',
                'height': this.star_height+'px'
            }
        });
        var div7 = new Element('div', {
            'id': 'innerStars',
            'styles': {
                'position': 'relative',
                'width': this.total_width+'px',
                'height': this.star_height+'px'
            }
        });

        div7.inject(div6);
        div5.inject(div4);
        div6.inject(div4);

        div4.inject(div3);
        div3.inject(div2);
        div2.inject(div1);

        this.anon_elm = div5;

        this.star.each(function(e) {
            new Element('div', {
                'styles': {
                    'background': 'url(\''+this.star_image+'\') no-repeat scroll left top transparent',
                    'left': (e?e:0)+'px',
                    'position': 'absolute',
                    'top': '0pt',
                    'width': this.star_width+'px',
                    'height': this.star_height+'px'
                }
            }).inject(div7);
        }.bind(this));

        this.stars = new Array();

        this.star.each(function(e){
            var new_star = new Element('div', {
                'class': 'star_star',
                'styles': {
                    'position': 'absolute',
                    'top': '0pt',
                    'left': (e?e:0)+'px',
                    'width': this.star_width+'px',
                    'height': this.star_height+'px',
                    'cursor': 'pointer'
                }
            });
            new_star.inject(div7);
            this.stars.push(new_star);
        }.bind(this));

        div1.inject(this.element);
    },
    setObserve: function(){
        if(!this.locked){
            this.stars.each(function(ele){
                ele.addEvent('mouseover', function(e){
                    ele_left_val = ele.getStyle('left').replace('px', '');
                    ele_left_val = parseInt(ele_left_val);
                    newWidth = parseInt(this.star_width);


                    ele_left_val = ele_left_val+newWidth;

                    val = (this.total_width-ele_left_val);
                    if (this.highlight_one)
                        val = e.target.offsetLeft;
                    var new_left = (this.highlight_one ? e.target.offsetLeft+'px' : '-'+val+'px');

                    this.anon_elm.setStyle('left', new_left);
                }.bind(this));

                ele.addEvent('mouseout', function(){
                    var new_left = this.highlight_one ? this.average+'px' : '-'+this.average+'px';
                    this.anon_elm.setStyle('left', new_left);
                }.bind(this));

                ele.addEvent('click', function(){
                    this.average = val;
                    var new_left = this.highlight_one ? '-'+this.average+'px' : '-'+this.average+'px';
                    this.anon_elm.setStyle('left', new_left);
                    ele_left_val = ele_left_val/newWidth;

                    /* ugly ugly hack TODO: FIXME: SOMETHING: please */
                    if (this.highlight_one) {
                        if (ele_left_val == 1)
                            ele_left_val = 5;
                        else if (ele_left_val == 2)
                            ele_left_val = 4;
                        else if (ele_left_val == 4)
                            ele_left_val = 2;
                        else if (ele_left_val == 5)
                            ele_left_val = 1;
                    }
                    /* end ugly - there has to be a better way to handle this */

                    if(!this.revote){
                        this.stopObserve();
                    }
                    if(this.json.onRate){
                        this.json.onRate(ele_left_val);
                    }
                }.bind(this));
            }.bind(this));
        }
        else{
            this.stars.each(function(ele){
                ele.setStyle('cursor', 'auto');
            }.bind(this));
        }
    },
    stopObserve: function(){
        this.stars.each(function(ele){
            ele.removeEvents('mouseover');
            ele.removeEvents('mouseout');
            ele.removeEvents('click');
            ele.setStyle('cursor', 'auto');
        }.bind(this));
    }
});

var NewsFeed = new Class({
    initialize: function (ele) {
        this.e = $(ele);
        this.left = $('left_button');
        this.right = $('right_button');
        this.current_item_index = 0;
        if (!this.e)
            return;

        this.feed_items = this.getFeedItems();
        this.left.addEvent('click', this.moveLeft.bind(this));
        this.right.addEvent('click', this.moveRight.bind(this));
    },
    getFeedItems: function () {
        var result = new Array();
        $$('.newsfeed .feeditem').each(function (a, index) {
            var showing = index >= 0 && index <= 2;
            var item = new FeedItem(a, index, this, showing);
            if (index == 0)
                item.highlight();
            result.push(item);
        }.bind(this));
        return result;
    },
    moveLeft: function (e) {
        e.stop();
        if (this.current_item_index > 0) {
            this.current_item_index--;
            this.feed_items[this.current_item_index].highlight();
            for (i = this.current_item_index+3; i < this.feed_items.length; i++) {
                this.feed_items[i].hide();
            }
            this.updateNumbers();
        }
    },
    moveRight: function (e) {
        e.stop();
        if (this.current_item_index < this.feed_items.length-1) {
            this.current_item_index++;
            this.feed_items[this.current_item_index].highlight();
            for (i = 0; i < this.current_item_index-2; i++) {
                this.feed_items[i].hide();
            }
            this.updateNumbers();
        }
    },
    updateNumbers: function () {
        var showing = new Array();
        this.feed_items.each(function (item) {
            if (item.showing) {
                showing.push(item.index);
            }
        });
        $('first_number').set('text', showing[0]+1);
        $('last_number').set('text', showing[2]+1);
    }
});

var FeedItem = new Class({
    initialize: function (ele, index, newsfeed, showing) {
        this.showing = showing;
        this.newsfeed = newsfeed;
        this.title = $('activity_title');
        this.description = $('activity_description');
        this.link = $('activity_link');
        this.index = index
        this.e = $(ele);

        /* verify that everything exists like it should */
        if (!this.title || !this.description || !this.e || !this.link)
            return;

        /* get an array of all the other feeditem elements - filtering out this.e */
        this.others = $$('.feeditem').filter(function (item) {
            return item != this.e;
        }.bind(this));

        this.e.addEvent('mouseenter', this.highlight.bind(this));
        if (!this.showing){
            this.hide();
        }
    },
    highlight: function () {
        this.showing = true;
        this.newsfeed.current_item_index = this.index;
        /* highlight this.e */
        this.e.setStyle('display', 'block');
        this.e.removeClass('feed1');
        this.e.addClass('feedhover');

        /* unhighlight the others */
        this.others.each(function (e) {
            e.addClass('feed1');
            e.removeClass('feedhover');
        });

        /* now update the title and desc and link */
        this.title.set('text', this.e.getChildren()[0].get('text'));
        this.description.set('text', this.e.getChildren()[2].get('text'));
        this.link.set('href', this.e.getChildren()[0].get('href'));
    },
    hide: function () {
        this.showing = false;
        this.e.setStyle('display', 'none');
    }
});

// expandable menu, div class of listmenu
// it will search for any child divs with class of title and
// look for the ul with the id that matches
// the rel id to toggle
// example:
//
//<div class="listmenu">
//    <div class="title" rel="issuemenu"><h2>Issues</h2></div>
//    <ul  id="issuemenu">
//       <li>one</li>
//    </ul>
//    <div class="title" rel="peoplemenu"><h2>People</h2></div>
//    <ul id="peoplemenu">
//       <li>a</li>

var ListMenu = new Class({
    initialize: function (element) {
        this.e = $(element);
        if (!this.e)
            return;

        this.titles = this.e.getChildren('.title');
        this.setObserves();
    },
    setObserves: function () {
        this.titles.each(function (child) {
            if (child.getProperty('rel')){
                child.getFirst().addEvent('click', this.toggle.bind(this));
                child.getFirst().addClass('activeMenuTitle');
                this.collapse(child.getProperty('rel'));
                if(child.hasClass('menuopen')){
                    child.setProperty('open','true');
                    this.expand(child.getProperty('rel'));
                }else{
                    child.setProperty('open', "false");
                }
            }

        }.bind(this));

    },
    toggle: function (a) {
        var rel = a.target.getParent().getProperty('rel') || null;
        var open = a.target.getParent().getProperty('open') || "false";
        // if we don't have a list to point to then don't try to expand
        if (rel){
            if (open == "true"){
                this.collapse(rel);
                a.target.getParent().setProperty('open', "false");
                if(a.target.getParent().hasClass('menuopen')){
                    a.target.getParent().removeClass('menuopen');
                }
                a.target.getParent().addClass('menuclosed');
            }
            else{
                this.expand(rel);
                a.target.getParent().setProperty('open', "true");
                if (a.target.getParent().hasClass('menuclosed')){
                    a.target.getParent().removeClass('menuclosed');
                }
                a.target.getParent().addClass('menuopen');
            }
        }
    },
    collapse: function (id) {
        var children = $(id).getChildren('li');
        children.each(function (child) {
            child.setStyle('display','none');
        });
    },
    expand: function (id) {
        var children = $(id).getChildren('li');
        children.each(function (child) {
            child.setStyle('display','block');
        });

    }
});


// adding div with accordionmenu class will add all wallpostsopen and wallpostsclosed classes
// add the toggler where you want the open/close to be and the element class to where you want
// the main content to be displayed
// add the allowmultiple=true to have the normal toggles and classes
// without the accordion functionality
//
//<div class="accordionmenu" >
//<div> this is the main accordian child
//<div class="wall_h2 ">one</div> accordian header
//<div class="toggler"></div> toggler

//<div class="clear"></div>
//<div class="element article">one blah blah blah</div>  content
//</div>
//</div>

var AccordionMenu = new Class({
    initialize: function (element){
        this.e = $(element);
        this.children = this.e.getChildren();
        this.width = this.e.getProperty('width') || null;
        this.Items = new Array();
        this.init();
    },
    init: function() {
        // create the children
        this.children.each(function(child){
            this.Items.push(new AccordionItem(child));

        }.bind(this));

        if (!this.e.getProperty('allowmultiple')){
            this.Items.each(function (itm) {
                itm.toggler.addEvent('click', this.hideElements.bind(this));
                itm.titles.each(function(t){
                    t.addEvent('click', this.hideElements.bind(this));
                }.bind(this));
            }.bind(this));
        }

        this.hideElements();
        if (this.Items && this.Items[0]){
            this.Items[0].show();
        }

    },
    hideElements: function () {

        this.Items.each(function (itm) {
            itm.hide();
        });
    }
})
var AccordionItem = new Class({
    initialize: function (element) {
        this.e = $(element);
        if (!this.e)
            return;
        this.hidden = false;
        this.toggler = this.e.getChildren('.toggler');
        this.titles = this.e.getChildren('.accordion_title');
        this.element = this.e.getChildren('.element');
        this.setObserves();
    },
    setObserves: function () {
        this.toggler.addEvent('click', this.toggle.bind(this));
        this.titles.each(function(t){
            t.addEvent('click', this.toggle.bind(this));
        }.bind(this));
    },
    toggle: function(evt) {
        // we want this to fire after the parent has fired and closed all the
        // other menu items
        evt.stop();

        var fx = this.hidden ? this.show : this.hide;
        window.setTimeout(fx.bind(this), 100);
    },
    hide: function() {

        this.element.setStyle('display', 'none');
        this.hidden = true;
        this.e.addClass('wallpostsclosed');
        this.e.removeClass('wallpostsopen');
        this.toggler.removeClass('open');
        this.toggler.addClass('close');
    },
    show: function() {

        this.element.setStyle('display', 'block');
        this.e.addClass('wallpostsopen');
        this.e.removeClass('wallpostsclosed');
        this.toggler.removeClass('close');
        this.toggler.addClass('open');
        this.hidden = false;
    }
});

/**
 * An extremely simplfied Accordian.
 *
 * new Accordian('accordian'); expects all divs to be a part of the accordian to
 * have the class "accordian". Each div should also have an 'a' tag somewhere
 * on the page (not a child of the div) with 'rel' set to the id of the target
 * div.
 */
var Accordian = new Class({
    /**
     * @param accordian_class the name of the class that elements that are part
     * of the accordian will receive.
     */
    initialize: function (accordian_class) {
        this.aclass = accordian_class;
        this.hideAll();

        $$('a.'+accordian_class).each(function (a) {
            a.addEvent('click', function (event) {
                event.stop();

                this.hideAll();
                $(a.get('rel')).show();
            }.bind(this));
        }.bind(this));
    },
    /**
     * Hides all divs that are part of the accordian.
     */
    hideAll: function () {
        $$('div.'+this.aclass).each(function (div) {
            div.hide();
        });
    }
});

/**
 * An Accordian class that will look for any load_on_show class children and load if that accordian is selected.
 *
 * new LazyLoadAccordian('accordian'); expects all divs to be a part of the accordian to
 * have the class "accordian". Each div should also have an 'a' tag somewhere
 * on the page (not a child of the div) with 'rel' set to the id of the target
 * div.
 */
var LazyLoadAccordian = new Class({
    /**
     * @param accordian_class the name of the class that elements that are part
     * of the accordian will receive.
     */
    initialize: function (accordian_class) {
        this.aclass = accordian_class;
        this.hideAll();

        $$('a.'+accordian_class).each(function (a) {
            a.addEvent('click', this.show.bind(this));
        }.bind(this));
    },
    show: function(event){
        event.stop();

        
        var ele = $(event.target.get('rel')); 
        var doShow = ele.getStyle('display') != "block" && ele.getStyle('display') != 'inline';
        this.hideAll();
        if(doShow)
            ele.show();
        
        var children = ele.getElements('.load_on_show');
        children.each(function(c){
            //c.load(c.getProperty('url'));
            var r = new Request.HTML({
                url: c.getProperty('url'),
                update: c
            });
            
            RequestMap.addRequest(r,'1');
            c.removeClass('load_on_show');
  
        });
        
    },
    /**
     * Hides all divs that are part of the accordian.
     */
    hideAll: function () {
        $$('div.'+this.aclass).each(function (div) {
            div.hide();
        });
    },
    setActive: function(id){
        if($(id)){
            $(id).show();
            var children = $(id).getElements('.load_on_show');
            children.each(function(c){
                //c.load(c.getProperty('url'));
                var r = new Request.HTML({
                    url: c.getProperty('url'),
                    update: c
                });

                RequestMap.addRequest(r,'1');
                c.removeClass('load_on_show');

            });
        }
            
    }
});

var Help = new Class({
    initialize: function (element) {

        this.e = $(element);
        if (!this.e)
            return;

        this.helpText = this.e.getChildren('.help_text');
        if (this.helpText){
            this.helpIcon = new Element('div',{
                'class' : 'help_icon'
            }).inject(this.e,'top');
            this.setObserves();
        }

    },
    setObserves: function(){
        this.helpIcon.addEvent('mouseover', this.showHelp.bind(this));
        this.helpIcon.addEvent('mouseout', this.hideHelp.bind(this));
    },
    showHelp: function(e){
        this.helpText.setStyle('display','block');
        this.helpText.setStyle('top', e.event.clientY+5);
        this.helpText.setStyle('left', e.event.clientX+15);
    },
    hideHelp: function(e){
        this.helpText.setStyle('display','none');
    }
});

var KeywordSelect = new Class({
    initialize: function (ele, type) {
        this.e = $(ele);
        this.expanded = false;
        this.close = false;
        this.current = 0;
        this.items = new Array();

        this.list = this.buildList();
        this.e.addEvent('keyup', this.lookup.bind(this));
        this.e.addEvent('focus', this.lookup.bind(this));
        this.e.addEvent('keydown', this.selectOption.bind(this));
        this.e.addEvent('blur', this.hide.bind(this));
    },
    selectOption: function (e) {
        if (e.key == 'down') {
            e.stop();
            this.moveDown();
        }
        else if (e.key == 'up') {
            e.stop();
            this.moveUp();
        }
        else if (e.key == 'enter') {
            if (this.expanded) {
                e.stop();
                this.select(this.items[this.current]);
            }
        }
        else if (e.key == 'esc') {
            if (this.expanded)
                this.hide();
        }
    },
    highlight: function (index) {
        this.items[index].addClass('selected');
    },
    unhighlight: function (index) {
        this.items[index].removeClass('selected');
    },
    moveUp: function () {
        if (this.current > 0) {
            this.unhighlight(this.current);
            this.current--;
            this.highlight(this.current);
        }
    },
    moveDown: function () {
        if (this.current < this.items.length-1) {
            this.unhighlight(this.current);
            this.current++;
            this.highlight(this.current);
        }
    },
    select: function (div) {
        a = {}
        a.target = div;
        this.appendKeyword(a);
    },
    lookup: function (e) {
        if (e.key == 'down' || e.key == 'up' || e.key == 'enter') {
            return;
        }

        if (this.e.get('value')) {
            new Request.JSON({
                url: '/keyword/lookup',
                method: 'get',
                data: 'keyword='+ this.e.get('value'),
                onSuccess: function (json) {
                    this.hide();
                    this.list.set('html', '');
                    this.items = new Array();
                    this.current = 0;
                    for (var i = 0; i < json.length; i++) {
                        var div = new Element('div').set('html', json[i].name);
                        if (i == 0)
                            div.addClass('selected');
                        div.addEvent('click', this.appendKeyword.bind(this));
                        div.inject(this.list);
                        this.items[i] = div;
                    }

                    if (json.length > 0)
                        this.show();
                }.bind(this)
            }).send();
        }
        e.stop();
    },
    appendKeyword: function (e) {
        // find the last comma
        var comma_pos = this.e.get('value').lastIndexOf(',');

        // replace everything after the last comma
        var str = e.target.get('html') + ', ';
        if (comma_pos != -1)
            str = this.e.get('value').substring(0, comma_pos) + ', ' + e.target.get('html') + ', ';

        this.e.set('value', str);
        this.e.focus();
    },
    hide: function () {
        this.expanded = false;
        //this.list.setStyle('display', 'none');
        this.close = this.list.setStyle.delay(300, this.list, ['display', 'none']);
    },
    show: function () {
        if (this.close)
            $clear(this.close);
        this.expanded = true;
        this.list.setStyle('display', 'block');
    },
    buildList: function () {
        return new Element('div', {
            'class': 'keyword_list',
            styles: {
                position: 'absolute',
                top: this.e.getPosition().y + this.e.getHeight(),
                left: this.e.getPosition().x,
                width: this.e.getWidth()-2,
                display: 'none'
            }
        }).inject($$('body')[0]);
    }
});

var PollOptionForm = new Class({
    initialize: function (ele) {
        this.e = $(ele);
        this.div = $('poll_add_option_' + this.e.get('rel'));

        this.e.addEvent('click', this.show.bind(this));
    },
    show: function () {
        new Request.HTML({
            url: '/poll/getOptionForm',
            update: this.div,
            data: 'poll_id=' + this.e.get('rel')
        }).send();
    }
});

var ReferContactForm = new Class({
    initialize: function (boxes, emails, checks, unchecks) {
        this.boxes = $$(boxes);
        this.checks = $$(checks);
        this.unchecks = $$(unchecks);
        this.emails = $(emails);

        this.registerChecks();
        this.registerUnchecks();
        this.registerBoxes();
    },
    registerChecks: function () {
        this.check(this.checks, true);
    },
    registerUnchecks: function () {
        this.check(this.unchecks, false);
    },
    check: function (elems, check) {
        elems.each(function (a) {
            a.addEvent('click', function (e) {
                e.stop();
                fields = this.boxes;
                for (i = 0; i < fields.length; i++)
                    fields[i].checked = check;
                this.updateEmails();
            }.bind(this));
        }.bind(this));
    },
    registerBoxes: function () {
        this.boxes.each(function (box) {
            box.addEvent('change', this.updateEmails.bind(this));
        }.bind(this));
    },
    updateEmails: function () {
        // get checked addresses
        checked = this.boxes.filter(function (b) {
            return b.checked;
        });

        // make this a json list
        list = '[';
        checked.each(function (c) {
            if (list != '[')
                list += ', ';
            name = c.value.split('%%')[0];
            email = c.value.split('%%')[1];
            list += '{"name":"'+ name +'", "email":"'+ email +'"}';
        });
        list += ']';

        // place list into hidden field as string
        this.emails.value = list;
    }
});

var Calendar = new Class({
    initialize: function (ele) {
        this.e = $(ele);
        this.groupId = this.e.getProperty('id');
        this.display_div = $('calendar_show');
        this.add_div = $('calendar_event_add');
        if (this.add_div){
            this.add_div.addEvent('click', this.addCalendarEvent.bind(this));
            this.new_event_div = $('new_event_div');
        }
        var edit_events = this.display_div.getChildren();
        for(var i in edit_events){
            var evt = edit_events[i];
            if (evt.getChildren){
                evt.getChildren('.event_edit').addEvent('click', this.editCalendarEvent.bind(this));
            }
        }
    },
    addCalendarEvent: function(){
        this.modal = new Modal({
                 'parentEl': $$('body')[0],
                 'content': '...loading...',
                 'height': 350,
                 'width': 450,
                 'title': 'New Event'
              });
        new Request({
            url: '/calendar/addEvent',
            data: {
                "group":this.groupId
                },
            onSuccess: function (responseText) {
                this.modal.setContent(responseText);
                this.setupEvents();
            }.bind(this)
        }).send();

    },
    setupEvents: function(){
        this.validateBtn = $('eventValidateBtn');
        this.cancelBtn = $('cancelEventBtn');

        if (this.validateBtn){
            var evts = this.validateBtn.retrieve('events');
            if(!evts || !evts['click']){
                this.validateBtn.addEvent('click', this.validateCalendarEvent.bind(this));
            }
        }
        if(this.cancelBtn){
            evts = this.cancelBtn.retrieve('events');
            if(!evts || !evts['click']){
                this.cancelBtn.addEvent('click', this.cancelCalendarEvent.bind(this));
            }
        }
    },
    editCalendarEvent: function(evt){
        this.modal = new Modal({
                'parentEl': $$('body')[0],
                'title': "Edit Event",
                'content': '...loading...',
                'height': 350,
                'width': 450
             });

        new Request({
            url: '/calendar/editEvent',
            data: {
                "id":evt.target.getProperty('id')
                },
            onSuccess: function (responseText) {
                this.modal.setContent(responseText);
                this.setupEvents();
            }.bind(this)
        }).send();
    },
    validateCalendarEvent: function(evt){
        new Request({
            url: '/calendar/validateEventForm',
            data: $('eventform'),
            onSuccess: function (responseText) {
                // if we get a response back it is the form with the validation errors
                // otherwise we just submit the form because it's valid
                if(responseText.length > 10){
                    //this.new_event_div.setProperty('html',responseText);
                    this.modal.setContent(responseText);
                    this.setupEvents();
                }
                else {
                    $('eventform').submit();
                }

            }.bind(this)
        }).send();
    },
    cancelCalendarEvent: function(s){
       this.modal.destroy();
    }
});

var GotvWindow = new Class({
    initialize: function (a) {
        this.e = $(a);
        this.group_id = $(a).get('rel').replace('gotv_', '');

        this.e.addEvent('click', this.open.bind(this));
    },
    open: function () {
        window.open($('gotv_'+this.group_id).get('href'));
    }

});

var OfficeSelector = new Class({
    initialize: function (ele) {
        this.e = $(ele);
        this.e.addEvent('change', this.selectOffice.bind(this));
        this.message = $('office_message');
        this.selectOffice();

    },
    selectOffice: function(){
        new Request({
            url: '/office/selectMessage',
            data: {
                "id":this.e.value
                },
            onSuccess: function (responseText) {
                this.message.setProperty('value',responseText);
            }.bind(this)
        }).send();
    }
});

var PoliticianSelector = new Class({
    initialize: function (ele) {
        this.e = $(ele);
        this.e.addEvent('change', this.selectPolitician.bind(this));
        this.display_div = $('politician_manage');

        this.selected = this.e.getProperty('ref') || null;
        if(this.selected){
            this.e.value=this.selected;
        }
        this.selectPolitician();

    },
    selectPolitician: function(){
        new Request({
            url: '/people/selectPolitician',
            data: {
                "politician":this.e.value
                },
            onSuccess: function (responseText) {
                this.display_div.setProperty('html',responseText);
                // now set up the listeners events for editing the events
                $$('.accordionmenu').each(function (m) {
                    new AccordionMenu(m)
                    });
                $$('.poll_add_option').each(function (a) {
                    new PollOptionForm(a)
                    });
                $$('.ajax_request').each(function (i) {
                    new AjaxRequest(i)
                    });
                $$('.remove_from_client').each(function (i) {
                    new Remove(i)
                });
                $$('.poll_submit').each(function (i) {
                    new PollSubmit(i)
                });
                $$('#nav_links').each(function (i) {
                    new Tabs(i);
                });
                $$('.show_hide').each(function(i) {
                    new ShowHide(i);
                });
                $$('.conversation_modal').each(function(i) {
                    new ConversationButton(i);
                });

            }.bind(this),
            onFailure: function (err) {
                console.debug(err);
            }
        }).send();
    }
});

var LazyLoad = new Class({
    initialize: function (ele) {

        this.e = $(ele);
        this.data = this.e.getProperty('ref') || null;
        this.mod = this.e.getProperty('mod') || null;
        this.priority = this.e.getProperty('priority') || "3";
        if(this.mod){
            this.lazyload();
        }
    },
    lazyload: function(){
        var request = new Request({
            url: this.mod,
            data: {
                "ref":this.data
                },
            onSuccess: function (responseText) {
                this.e.setProperty('html',responseText);
                
                // set up listeners
                $$('.pie_graph').each(function (i) {
                    new CanvasPieChart(i)
                });

                $$('.show_hide').each(function(i){
                    new ShowHide(i);
                });
                $$('form.random_poll').each(function(i){
                    new RandomPoll(i);
                });
                $$('form.ajax_form').each(function(i){
                    new AjaxForm(i);
                });
                $$('.decline_link').each(function(i){
                    new DeclineLink(i);
                });
                var children = this.e.getElements('.ajax_request');

                children.each(function (i) {
                    new AjaxRequest(i)
                    });
                children = this.e.getElements('.lazy_load');
                children.each(function (i) {
                    new LazyLoad(i)
                    });
                children = this.e.getElements('.inline_toggle');
                children.each(function (i) {
                    new InlineToggle(i)
                    });
                children = this.e.getElements('a.agree');
                children.each(function (i) {
                    new AgreeButton(i)
                    });    
                    
                    
        
            }.bind(this),
            onFailure: function (err) {
                console.debug(err);
            }
        });
        this.e.removeClass('lazy_load');
        RequestMap.addRequest(request,this.priority);
        
    }
});


// generic ajax request class
// required:
// class='ajax_request'
// request='/user/ajaxfunction'  url of the ajax request
// ref='some_id'    id of the element where the return value will be put
// params have different options for formatting
// 1.  params="form_id"  this in conjunction with is_form=true will send the form values to the request
// 2.  params="value"  this will send the data:value as the request parameter
// 3.  params={'one':1,'two':2}  this will send the object as the request parameters
// optional:
// confirmMsg="are you sure?"  adds a confirm msg to the request
// is_form="true"  add if you want the request to use a form for the params and put the form_id in the params
// add=true will take the return from the server and add it to the end of the ref element


var AjaxRequest = new Class({
    initialize: function (ele) {
        this.e = $(ele);
        this.data = this.e.getProperty('params') || null;
        var ref = this.e.getProperty('ref') || ele;
        this.refElement = $(ref);
        this.refClassElements = $$('.' + ref);
        this.confirmMsg = this.e.getProperty('confirmMsg') || null;
        this.ajaxRequest = this.e.getProperty('request') || this.e.getProperty('href') || null;
        this.e.addEvent('click', this.sendRequest.bind(this));
     
    },
    sendRequest: function(e){
        if(e && e.stop)
            e.stop();
        
        var confirm = true;
        if(this.confirmMsg){
            confirm = window.confirm(this.confirmMsg);
        }
        if(!confirm)
            return;
        this.refElement.removeEvents();
        // parse the params
        var params = null;
        if(this.e.getProperty('is_form')){
            params = $(this.data);
        }
        else{
            var tmp = this.data;
            if(tmp && tmp.charAt(0)=="{"){
                params = eval("("+ this.data + ")");
            }
            else{
                params = {
                    'data': this.data
                    };
            }
        }

        var request = new Request({
            url: this.ajaxRequest,
            data: params,
            evalScripts: true,
            onSuccess: function (responseText) {
                if (this.e.getProperty('add')) {
                    var ele = new Element('div');
                    ele.setProperty('html',responseText);
                    ele.inject(this.refElement);
                }
                else {
                    this.refClassElements.each(function(e){
                        e.setProperty('html',responseText);
                    });
                    this.refElement.setProperty('html',responseText);
                }
                // set up handlers here
                
                var children = this.refElement.getElements('.ajax_request');

                children.each(function (i) {
                    new AjaxRequest(i)
                    });
                children = this.refElement.getElements('.remove_from_client');
                children.each(function (i) {
                    new Remove(i)
                    });
                children = this.refElement.getElements('.editable');
                children.each(function (i) {
                    new EditableField(i)
                    });
                children = this.refElement.getElements('.poll_submit');
                children.each(function (i) {
                    new PollSubmit(i)
                    });
                children = this.refElement.getElements('.decline_link');
                children.each(function (i) {
                    new DeclineLink(i)
                    });
                children = this.refElement.getElements('.ajax_form');
                children.each(function (i) {
                    new AjaxForm(i)
                    });
                children = this.refElement.getElements('.edit_modal');
                children.each(function (i) {
                    new EditModal(i)
                    });
                children = this.refElement.getElements('.signin_button');
                children.each(function (i) {
                    new SigninButton(i)
                    });
                children = this.refElement.getElements('.lazy_load');
                children.each(function (i) {
                    new LazyLoad(i)
                    });
                children = this.refElement.getElements('.share_button');
                children.each(function (i) {
                    new ShareButton(i)
                    });
                    
                children = this.refElement.getElements('.inline_toggle');
                children.each(function (i) {
                    new InlineToggle(i)
                    });
                children = this.refElement.getElements('.date_picker');   
                children.each(function(e){

                    var date = new Picker.Date(e, {
                        timePicker: false,
                        positionOffset: {x: 5, y: 0},
                        pickerClass: 'datepicker_vista',
                        useFadeInOut: !Browser.ie
                    });

                });
                children = this.e.getElements('a.agree');
                children.each(function (i) {
                    new AgreeButton(i)
                    }); 
        
        
            }.bind(this),
            onFailure: function (err) {
                //console.debug(err);
            }
        //}).send();
        });
        RequestMap.addRequest(request,'2');
    }
});

var PollSubmit = new Class({
    initialize: function (ele) {
        this.e = $(ele);
        this.option_count = 0;
        this.clicked = false;
        this.e.addEvent('click', this.validatePoll.bind(this));
        document.addEvent('request_reload', this.reloadPolls.bind(this));
        var form = $(this.e.getProperty('form_id'));
        
        form.getElements('.custom_poll_options').each(function(ele){
            ele.addEvent('click',this.customOptions.bind(this));
            this.disableOptions(ele);
        }.bind(this));
    },
    customOptions: function(e){       
        var ele = $(e.target);
        this.disableOptions(ele);
            
    },
    disableOptions: function(ele){
        var opts = $(this.e.getProperty('option_list'));
        if(ele.getProperty('value') == 'custom' && ele.getProperty('checked')){
            opts.getElements('input').each(function(e){
                $(e).setProperty('disabled',false);
            });
        }else if(ele && ele.getProperty('value')){
            opts.getElements('input').each(function(e){
                $(e).setProperty('disabled',true);
            });
        }
    },
    validatePoll: function(e) {
        this.e.setProperty('disabled', true);
        e.stop();
        if (!this.clicked) {
            this.clicked = true;

            new Request({
                url: '/poll/validatePollForm',
                data: $(this.e.getProperty('form_id')),
                onSuccess: function (poll_id) {
                    this.clicked = false;
                    this.e.setProperty('disabled', false);

                    // if we get a response back it is the form with the validation errors
                    // otherwise we just submit the form because it's valid
                    if (poll_id.length > 10) {
                        // not valid

                        var errors = poll_id.split("_:_");
                        var errStr = "";
                        errors.each(function (e) {
                            errStr += e + "\n";
                        });
                        window.alert(errStr);
                    }
                    else {
                        this.deleteResponses(poll_id);

                    }
                }.bind(this)
            }).send();
        }
    },
    // this will delete old responses and then save new responses
    deleteResponses: function(poll_id){
        new Request({
            url: '/poll/deleteResponses',
            data: {
                'poll_id': poll_id
            },
            onSuccess: function(){
      
                var response = null;
                var iteration = 0;
                
                $(this.e.getProperty('form_id')).getElements('input.custom_poll_options').each(function (r) {                   
                    response = null;
                    if(r.getProperty('value') !='custom' && r.getProperty('checked')){
                        response = r.getProperty('value');
                        if (response && response != '') {
                            iteration = 1;
                            this.option_count = 1;
                            this.saveResponse(response, poll_id, iteration);
                        }
                    }
                    else if(r.getProperty('value') =='custom' && r.getProperty('checked')){
                        var opt = $$('.' + this.e.getProperty('option_class'));
                        this.option_count = opt.length;
                        var iteration = 0;                       
                        opt.each(function (i) {
                            iteration++;
                            var response = null;
                            i.getElements('input').each(function (e) {
                                if(e.id == 'poll_option_response'){
                                    response = e.getProperty('value');
                                }
                            });
                            if (response && response != '') {
                                this.saveResponse(response, poll_id, iteration);
                            }else{
                                this.option_count--;
                            }
                        }.bind(this));
                    }                   
                }.bind(this));
                // if we have no options still update the page
                if(iteration == 0 && this.option_count == 0){
                    document.fireEvent('request_reload', poll_id);
                }
            }.bind(this)
        }).send();
    },
    saveResponse: function(val, poll_id, iteration) {
        new Request({
            url: '/poll/saveResponse',
            data: {
                'response':val,
                'poll_id': poll_id
            },
            onSuccess: function () {
                if (iteration == this.option_count)
                    document.fireEvent('request_reload', poll_id);
            }.bind(this)
        }).send();
    },
    reloadPolls: function(poll_id) {
        if (!this.reloading) {
            this.reloading = true;

            new Request({
                url: '/poll/reloadPolls',
                data: {
                    'poll_id': poll_id
                },
                onSuccess: function(response) {
                    this.reloading = false;
                    $('poll_list_manage').setProperty('html', response);
                    var map = [
                        {selector: '.ajax_request', type: AjaxRequest},
                        {selector: '.poll_submit', type: PollSubmit},
                        {selector: '.remove_from_client', type: Remove},
                        {selector: '.static_random', type: OptionRandomizer},
                        {selector: '.show_hide', type: ShowHide}
                    ]
                    Map.ResolveObjects(map);
                }
            }).send();
        }
    }

});

var OptionRandomizer = new Class({
    initialize: function (ele) {
        this.e = $(ele);
        this.poll_id = this.e.getProperty('rel');

        this.e.addEvent('click', this.randomize.bind(this));
    },
    randomize: function () {
        new Request({
            url: '/poll/staticRandomSort',
            data: {
                poll_id: this.poll_id
            },
            onSuccess: function () {
                document.fireEvent('request_reload', this.poll_id);
            }.bind(this)
        }).send();
    }
})

var ShowHide = new Class({
    initialize: function (element) {
        this.e = $(element);

        if (!this.e)
            return;
        var evts = this.e.retrieve('events');

        if(evts && evts['click']){

            return;
        }


        this.setObserves();
    },
    setObserves: function () {

        this.e.addEvent('click', this.toggle.bind(this));
        if(this.e.getChildren()){
            this.e.getChildren().each(function(c){
                c.addEvent('click', this.toggle.bind(this));
            }.bind(this));
        }

        if(this.e.hasClass('menuopen')){
            this.expand(this.e.getProperty('rel'));

        }
        else{
            this.collapse(this.e.getProperty('rel'));
        }
    },
    toggle: function (a) {

        var rel = this.e.getProperty('rel') || null;
        var open = this.e.getProperty('open') || "false";

        if (rel){
            if (open == "true"){
                this.collapse(rel);
            }
            else{
                this.expand(rel);
            }
        }
    },
    collapse: function (id) {

        $(id).setStyle('display','none');
        this.e.setProperty('open', "false");
        if(this.e.hasClass('menuopen')){
            this.e.removeClass('menuopen');
        }
        this.e.addClass('menuclosed');
        var msg = this.e.getProperty('showmsg') || "show";
        this.e.setProperty('html',msg);
    },
    expand: function (id) {

        $(id).setStyle('display','block');
        this.e.setProperty('open', "true");
        if (this.e.hasClass('menuclosed')){
            this.e.removeClass('menuclosed');
        }
        this.e.addClass('menuopen');
        var msg = this.e.getProperty('hidemsg') || "hide";
        this.e.setProperty('html',msg);

    }
});
var InlineToggle = new Class({
    initialize: function (element) {
        this.e = $(element);
        if (!this.e)
            return;
        var rel = this.e.getProperty('href') || null;
        if(!rel)
            return;

        this.related = $(rel) || null;
        if(!this.related)
            return;
        var evts = this.e.retrieve('events');

        if(evts && evts['click']){

            return;
        }

        this.setObserves();
    },
    setObserves: function () {

        this.e.addEvent('click', this.toggle.bind(this));
        this.related.setStyle('display','none');
    },
    toggle: function(e){
        e.stop();
        // toggle
        if(this.related.getStyle('display') && this.related.getStyle('display') == "inline"){
            this.related.setStyle('display','none');
            this.e.setProperty('html','...read more');
        }else{
            this.related.setStyle('display','inline');
            this.e.setProperty('html','...hide');
        }
     }

});
// table of contents class
var TOC = new Class({
    initialize: function (element) {
        this.e = $(element);
        if (!this.e)
            return;
        var rel = this.e.getProperty('href') || null;
        if(!rel)
            return;

        this.related = $(rel);
        
        var evts = this.e.retrieve('events');
        if(evts && evts['click']){
            return;
        }
        this.setObserves();
    },
    setObserves: function () {
        this.e.addEvent('click', this.toggle.bind(this));
        this.related.getChildren().each(function(c){
                c.addEvent('click', this.hide.bind(this));
            }.bind(this));
        if(!this.shown){
            this.collapse();
        }
        else{
            this.expand();
        }
    },
    toggle: function (e) {
        e.stop();
        if (this.shown){
            this.collapse();
        }
        else{
            this.expand();
        }
    },
    hide: function() {
        this.related.setStyle('display','none');
        this.shown = false;
    },
    collapse: function () {
        this.related.setStyle('opacity', 1);
        var fx = function(){
            this.related.setStyle('display','none');
        }.bind(this);
        new Fx.Morph(this.related, {duration: 300,
                            onComplete: fx
                    }).start({
            'opacity': 0
        });
        this.shown = false;
        
    },
    expand: function () {
        this.related.setStyle('display', 'block');
        this.related.setStyle('opacity', 0);
        new Fx.Morph(this.related, {duration: 300}).start({
            'opacity': 1
        });
        this.shown = true;
    }
});

var Remove = new Class({
    initialize: function (element) {
        this.e = $(element);
        if (!this.e)
            return;
        this.e.addEvent('click', this.remove.bind(this));

    },
    remove: function (a) {
        if(this.e.getParent('.form_row')){
            this.e.getParent('.form_row').destroy();
        }
        if(this.e.getParent()){
            this.e.getParent().destroy();
        }
        else if(this.e){
            this.e.destroy();
        }

    }
});

var CanvasPieChart = new Class({
    initialize: function (canvas, data) {

        this.canvas = $(canvas);
        if (!this.canvas)
            return;
        this.context = this.canvas.getContext('2d');
        if(!this.context)
            return;
        var ColorArray = new Array(
            '#496481',
            '#B41515',
            '#119011',
            '#B45D15',
            '#3DB6B6'
            );
        this.numColors = ColorArray.length;
        this.lineSpacing = 18;

        var data = eval('(' + this.canvas.getProperty("data") + ')');
        this.slices = new Array();
        // we may want to set the colors ourselves
        //this.colors = new Array();
        this.colors = ColorArray;

        // find total value
        this.total = 0;
        this.numValues = 0;
        for (var piece in data) {
            this.numValues++;
            this.total += parseInt(data[piece]);
        }
        // add height to canvas for each data value we need to display
        this.canvas.setProperty('height',110 + (this.numValues*this.lineSpacing));
        this.canvas.setProperty('width', 200); // by default
        this.height = this.canvas.height;
        this.width = this.canvas.width;
        this.canvas_size = [this.width, this.height];
        this.radius = 50;
        this.labelRadius = 4;
        this.center = [50,50];

        //init the slices
        var sofar = 0; // keep track of progress

        for (piece in data) {
            var thisvalue = data[piece] / this.total;
            var num = thisvalue*100;
            var label = piece + " " + num.toFixed(2) + "%";
            var slice = new CanvasPieSlice(thisvalue,label, sofar, this);
            this.slices.push(slice);
            //this.colors.push(this.getColor());
            sofar += thisvalue; // increment progress tracker
        }


        if(!this.total){
            return;
        }
        this.draw();
    },
    draw: function(){
        var heightsofar = this.center[1] + this.radius + this.lineSpacing;
        var colorcount = 0;

        this.slices.each(function(slice){
            var color = this.colors[colorcount];
            slice.draw(color);
            this.drawLabel(color, heightsofar,slice.label);
            heightsofar += this.lineSpacing;
            colorcount++;
            if(colorcount == this.numColors){
                colorcount = 1;
            }

        }.bind(this));

    },
    // utility - generates random color
    getColor: function() {
        var rgb = [];
        for (var i = 0; i < 3; i++) {
            rgb[i] = Math.round(100 * Math.random() + 155) ; // [155-255] = lighter colors
        }
        return 'rgb(' + rgb.join(',') + ')';
    },
    getBlack: function(){
        var rgb = [75,75,75];
        for (var i = 0; i < 3; i++) {
        //rgb[i] = 0;
        }
        return 'rgb(' + rgb.join(',') + ')';
    },
    drawLabel: function(color, height, label){

        this.context.beginPath();
        this.context.arc(10, height-4, this.labelRadius, 0, Math.PI*2, false);
        this.context.closePath();
        this.context.fillStyle = color;
        this.context.fill();
        this.context.fillStyle = this.getBlack();
        this.context.font = '10pt helvetica';
        this.context.fillText(label,this.lineSpacing,height);

    }
});
var CanvasPieSlice = new Class({
    initialize: function (thisvalue,label,sofar,canvas) {
        this.val = thisvalue;
        this.sofar = sofar;
        this.canvas = canvas;
        this.label = label;

    },
    draw: function(color){
        if(this.canvas.context){
            this.canvas.context.beginPath();
            this.canvas.context.moveTo(this.canvas.center[0], this.canvas.center[1]); // center of the pie

            this.canvas.context.arc(  // draw next arc
                this.canvas.center[0],
                this.canvas.center[1],
                this.canvas.radius,
                Math.PI * (- 0.5 + 2 * this.sofar), // -0.5 sets set the start to be top
                Math.PI * (- 0.5 + 2 * (this.sofar + this.val)),
                false
                );

            this.canvas.context.lineTo(this.canvas.center[0], this.canvas.center[1]); // line back to the center
            this.canvas.context.closePath();
            //context.fillStyle = colors[piece];    // color

            this.canvas.context.fillStyle = color;
            this.canvas.context.fill();
        }

    }


});

var ChartTableWrapper = new Class({
    initialize: function (table) {
        this.table = $(table);
        /* create canvas element */
        this.canvas = new Element('canvas', {
            data: this.tableDataAsJson()
        });
        this.canvas.inject(this.table, 'after');
        new CanvasPieChart(this.canvas);
        this.table.hide();
    },
    tableDataAsJson: function () {
        var data = {}
        var rows = this.table.getChildren('tbody tr');
        rows.each(function (row) {
            var option = row.getChildren()[0].get('html');
            var result = row.getChildren()[1].get('html');
            data[option] = result;
        });

        return JSON.encode(data);
    }
});

var MessageToggle = new Class({
    initialize: function (element) {

        this.e = $(element);

        if (!this.e)
            return;

        this.setObserves();
    },
    setObserves: function () {
        this.e.addEvent('click', this.toggle.bind(this));

        if(this.e.getChildren()){
            this.e.getChildren().each(function(c){
                c.addEvent('click', this.toggle.bind(this));
            }.bind(this));
        }
        if(!this.e.getProperty('show')){
            this.collapse(this.e.getProperty('rel'));
        }
        else{
            this.expand(this.e.getProperty('rel'));
        }
    },
    toggle: function (a) {
        var rel = this.e.getProperty('rel') || null;
        var open = this.e.getProperty('open') || "false";

        if (rel){
            if (open == "true"){
                this.collapse(rel);
            }
            else{
                this.expand(rel);
            }
        }
    },
    collapse: function (id) {

        $(id).setStyle('display','none');
        this.e.setProperty('open', "false");
        if(this.e.hasClass('menuopen')){
            this.e.removeClass('menuopen');
        }
        this.e.addClass('menuclosed');
        var msg = this.e.getProperty('showmsg') || "show";
        this.e.setProperty('html',msg);
        new Request({
            url: '/user/closeMessages',
            onSuccess: function (response) {

            }.bind(this),
            onFailure: function (err) {

            }
        }).send();
    },
    expand: function (id) {

        $(id).setStyle('display','block');
        this.e.setProperty('open', "true");
        if (this.e.hasClass('menuclosed')){
            this.e.removeClass('menuclosed');
        }
        this.e.addClass('menuopen');
        var msg = this.e.getProperty('hidemsg') || "hide";
        this.e.setProperty('html',msg);
        new Request({
            url: '/user/openMessages',
            onSuccess: function (response) {

            }.bind(this),
            onFailure: function (err) {

            }
        }).send();
    }
});
var BillForm = new Class({
    initialize: function (ele) {

        this.e = $(ele);
        this.typeSelect = this.e.getElementById('bill_type');
        this.stateSelect = this.e.getElementById('bill_state_id');
        this.countySelect = this.e.getElementById('bill_county_id');
        this.citySelect = this.e.getElementById('bill_city_id');
        this.stateSelect.addEvent('change', this.selectState.bind(this));
        this.typeSelect.addEvent('change', this.selectType.bind(this));
        // just to initialize the form
        this.selectType();
        this.selectState();
    },
    selectState: function(){
        if(this.stateSelect.getProperty('value')){
            this.selectCounties();
            this.selectCities();
        }
    },
    selectCounties: function(){
        new Request({
            url: '/bill/getCounties',
            data: {
                state: this.stateSelect.getProperty('value')
                },
            onSuccess: function (responseText) {
                county = this.countySelect;
                county.getParent().setProperty('html',responseText);
                this.countySelect = this.e.getElementById('bill_county_id');
                this.selectType();
            }.bind(this),
            onFailure: function (err) {
                s
                console.debug(err);
            }
        }).send();
    },
    selectCities: function(){
        new Request({
            url: '/bill/getCities',
            data: {
                state: this.stateSelect.getProperty('value')
                },
            onSuccess: function (responseText) {
                city = this.citySelect;
                city.getParent().setProperty('html',responseText);
                this.citySelect = this.e.getElementById('bill_city_id');
                this.selectType();
            }.bind(this),
            onFailure: function (err) {
                console.debug(err);
            }
        }).send();
    },
    selectType: function(){
        type = this.typeSelect.getProperty('value');
        if(type == 'national'){
            this.stateSelect.setProperty('disabled',true);
            this.countySelect.setProperty('disabled',true);
            this.citySelect.setProperty('disabled',true);
        }
        else if(type == 'state'){
            this.stateSelect.setProperty('disabled',false);
            this.countySelect.setProperty('disabled',true);
            this.citySelect.setProperty('disabled',true);
        }
        else if(type == 'county'){
            this.stateSelect.setProperty('disabled',false);
            this.countySelect.setProperty('disabled',false);
            this.citySelect.setProperty('disabled',true);
        }
        else if(type == 'city'){
            this.stateSelect.setProperty('disabled',false);
            this.countySelect.setProperty('disabled',false);
            this.citySelect.setProperty('disabled',false);
        }
    }
});
var TestGraph = new Class({
    initialize: function(ele){
        this.canvas = $(ele);

        //canvas = document.getElementById("cv");
        this.ctx = this.canvas.getContext("2d");
        this.particles = new Array();
        for(var i = 0; i < 20; i++) {
            this.particles[i] = new Particle(this.canvas);
        }

        this.ctx.lineWidth = "2";
        this.ctx.strokeStyle = "rgb(255, 255, 255)";
        this.loop();
    },
    loop: function() {
        this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

        for(var i = 0; i < 20; i++) {
            this.particles[i].update();

            this.ctx.beginPath();
            this.ctx.moveTo(this.particles[i].x,this.particles[i].y);
            this.ctx.lineTo(this.particles[i].x - this.particles[i].xvel,
                this.particles[i].y - this.particles[i].yvel);
            this.ctx.stroke();
            this.ctx.closePath();
        }
        var fx = function(){
            this.loop();
        }.bind(this);
    //setTimeout(fx, 10);
    }
});


var Particle = new Class({
    initialize: function(canvas) {
        this.canvas = canvas;
        this.x = Math.random() * this.canvas.width;
        this.y = Math.random() * this.canvas.height;

        this.xvel = Math.random() * 5 - 2.5;
        this.yvel = Math.random() * 5 - 2.5;
    },

    update: function() {
        this.x += this.xvel;
        this.y += this.yvel;

        this.yvel += 0.1;

        if (this.x > this.canvas.width || this.x < 0) {
            this.xvel = -this.xvel;
        }

        if (this.y > this.canvas.height || this.y < 0) {
            this.yvel = -this.yvel;
        }
    }
});

var AutoComplete = new Class({
    initialize: function (ele) {

        this.input = $(ele);

        var ref = this.input.getProperty('ref') || ele;
        this.select = $(ref);

        this.ajaxRequest = this.input.getProperty('request');

        this.input.addEvent('keyup', this.sendRequest.bind(this));
        if(this.input.getProperty('value')){
            this.sendRequest();
        }
    },
    sendRequest: function(){
        if(this.request){
            this.request.cancel();
        }

        this.request = new Request({
            url: this.ajaxRequest,
            data: {
                'data':this.input.getProperty('value'),
                'name': this.input.getProperty('formname')
                },
            onSuccess: function (responseText) {
                this.select.setProperty('html', responseText);
                this.select.getElement('select').addEvent('click', this.fillInText.bind(this));
            }.bind(this),
            onFailure: function (err) {
                console.debug(err);
            }
        });
        this.request.send();



    },
    fillInText: function(e){
        console.debug(e.target.get('tag'));
        if(e.target.get('tag') == "option"){
            this.input.setProperty('value', e.target.getProperty('text'));
        }else if(e.target.get('tag')=='select'){
            var opt = e.target.options[e.target.selectedIndex];
            this.input.setProperty('value', opt.getProperty('text'));
        }
    }
});

var PollForm = new Class({
    initialize: function (e, update) {
        this.form = $(e);
        this.update = update;

        this.form.addEvent('submit', this.submit.bind(this));
    },
    submit: function (e) {

        new Form.Request(this.form, this.update, {
            evalScripts: true,
            onSuccess: function () {
                $$('table.canvas_chart').each(function (i) {
                    new ChartTableWrapper(i)
                });
                $$('form.poll').each(function (a) {
                    new PollForm(a, 'poll_display');
                });
            }
        }).send();
        e.stop();
    }
});
var EnableForm = new Class({
    initialize: function (form) {
        this.form = $(form);
        if (!this.form)
            return;

        this.form.addEvent('submit', this.submit.bind(this));
    },
    submit: function (e) {
        //e.preventDefault();

        var count = this.form.elements.length;
        for(var i=0;i<count;i++){

           this.form.elements[i].disabled=false;
        }
        //this.form.submit();

    }
});
var PublicRecordFilter = new Class({
    initialize: function (ele) {
        this.ele = $(ele);
        this.ele.addEvent('click', this.filter.bind(this));
        this.filter();
    },
    filter: function () {
        if(this.ele.getProperty('checked')){
            $$('.public_record_comment').each(function(c){

                $(c).setStyle('display','block');
            });
            $$('.private_comment').each(function(c){
                $(c).setStyle('display','none');
            });

        }else{
            $$('.public_record_comment').each(function(c){

                $(c).setStyle('display','block');
            });
            $$('.private_comment').each(function(c){
                $(c).setStyle('display','block');
            });

        }
    }
});
var GroupFilter = new Class({
    initialize: function (ele) {
        this.ele = $(ele);
        this.ele.addEvent('click', this.filter.bind(this));

        this.ele.addEvent('click', function () {
            new Request({
                'url': '/feed/saveFilter',
                'data': Object.toQueryString({
                    'field': this.ele.get('id'),
                    'value': this.ele.checked
                })
            }).send();
        }.bind(this));

        this.filter();
    },
    filter: function () {
        var checked = this.ele.getProperty('checked');
        var nm = this.ele.getProperty('name');
        if (checked) {
            $$("."+nm).each(function (c) {
                $(c).setStyle('display','block');
            });
        } else {
            $$("."+nm).each(function (c) {
                $(c).setStyle('display','none');
            });
        }
    }
});
var GenericFilter = new Class({
    initialize: function (ele) {
        this.ele = $(ele);
        this.ele.addEvent('click', this.filter.bind(this));
        this.filter();
    },
    filter: function () {
        var checked = this.ele.getProperty('checked');
        var nm = this.ele.getProperty('name');
        if (checked) {
            $$("."+nm).each(function (c) {
                $(c).setStyle('display','block');
            });
        } else {
            $$("."+nm).each(function (c) {
                $(c).setStyle('display','none');
            });
        }
    }
});

var FeedbackForm = new Class({
    initialize: function (f) {
        this.f = $(f);
        this.tab = this.f.getChildren('#feedback_tab')[0];
        this.form = this.f.getElements('form')[0];
        this.hidden = true;

        this.setEvents();
    },
    setEvents: function () {
        this.tab.addEvent('click', this.toggleForm.bind(this));
        this.form.addEvent('submit', this.submitForm.bind(this));
        this.formrequest = new Form.Request(this.form, 'feedback_response', {});
    },
    submitForm: function (e) {
        e.stop();
        this.formrequest.send();
    },
    toggleForm: function (e) {
        e.stop();

        var hidden = -310;
        var showing = 0;
        var slide = new Fx.Morph(this.f, {
            transition: 'sine:in:out',
            /*
             * on complete and on start so that the form shadow shows at correct
             * times and doesn't bleed on to the page when "hidden"
             */
            onComplete: function () {
                if (this.hidden) {
                    this.form.removeClass('showing');
                }
            }.bind(this),
            onStart: function () {
                if (!this.hidden) {
                    this.form.addClass('showing');
                }
            }.bind(this)
        });

        if (this.hidden) {
            this.hidden = false;
            var end_pos = showing;
        }
        else {
            this.hidden = true;
            var end_pos = hidden;
        }

        slide.start({
            'left': end_pos
        })
    }
});
var ClusterGoogleMap = new Class({
    initialize: function (m) {
        this.m = $(m);
        this.mapData = $('map_data');
        this.markersArr = [];
        this.markerClusters = [];
        this.centerLat = $('center_latitude').getProperty('value');
        this.centerLong = $('center_longitude').getProperty('value');
        this.zoom = $('zoom').getProperty('value');
        this.legend = $('map_legend');

        var latlng = new google.maps.LatLng(this.centerLat, this.centerLong);

        var myOptions = {
            zoom: parseInt(this.zoom),
            maxZoom: 15,
            center: latlng,
            mapTypeId: google.maps.MapTypeId.ROADMAP
        };
        this.map = new google.maps.Map(this.m,myOptions);

        var opts = this.mapData.getChildren('ul.option');
        var imageArr = ['/images/map/marker1.png',
                        '/images/map/marker2.png',
                        '/images/map/marker3.png',
                        '/images/map/marker4.png',
                        '/images/map/marker5.png',
                        '/images/map/marker6.png',
                        '/images/map/marker7.png',
                        '/images/map/marker8.png'];
       var fontColorArr = ['white',
                        '#333333',
                        '#222222',
                        '#555555',
                        '#555555',
                        '#333333',
                        'white',
                        'white'];

       this.styles = new Array();
       var style = null;
       // repeat twice for a max of 16 styles
       for(var i=0;i<2;i++){
           imageArr.each(function(e, idx){
            style = new Array();
            style.push(new Object({
                            url: e,
                            height: 30,
                            width: 36,
                            anchor: [0,0],
                            textColor: fontColorArr[idx],
                            textSize: 14
                        }));
            this.styles.push(style);
            }.bind(this));
       }

        var imageIndex = 0;
        opts.each(function(o, idx){
            // for each option define an icon
            if(imageIndex >= imageArr.length){
                imageIndex = 0;
            }
            var image = new google.maps.MarkerImage(imageArr[imageIndex],
                  new google.maps.Size(48, 40),
                  // The origin for this image is 0,0.
                  new google.maps.Point(0,0));
            this.markersArr[idx] = [];

            o.getChildren('li').each(function(c){
                var lat = $(c).getChildren('span.latitude');
                var lon = $(c).getChildren('span.longitude');
                this.addMarker(lat.getProperty('html'),lon.getProperty('html'), image, idx);
            }.bind(this));
            this.markerClusters.push(new MarkerClusterer(this.map, this.markersArr[idx], {minimumClusterSize:1,styles:this.styles[idx]}));
            var label = o.getChildren('span.label')[0];
            var voteCount = o.getChildren('span.count')[0];
            if(parseInt(voteCount.getProperty('html'))> this.markersArr[idx].length){
                $('anon_users_message').setStyle('display','block');
            }
            this.addLegendLabel(label.getProperty('html'),imageArr[imageIndex], voteCount.getProperty('html'),idx);
            imageIndex++;
        }.bind(this));


    },
    addMarker: function(lat,lon,image,idx){

        var latlong = new google.maps.LatLng(lat,lon);
        marker = new google.maps.Marker({
            position: latlong,
            map: this.map,
            icon: image
        });

        this.markersArr[idx].push(marker);
    },
    clearOverlays: function(idx){
       if(this.markersArr[idx]){
            this.markerClusters[idx].clearMarkers();
        }
    },
    showOverlays: function(idx){
        if(this.markersArr[idx]){
            this.markerClusters[idx] = new MarkerClusterer(this.map, this.markersArr[idx], {minimumClusterSize: 1,styles:this.styles[idx]});
        }
    },
    addLegendLabel: function(label,imageUrl,count,idx){

        var ele = new Element('div');
        var lbl = new Element('span',{html:label,id:'legend_'+idx});
        lbl.addClass('legend_label');
        var cnt = new Element('span',{html:count});
        cnt.addClass('legend_count');
        var img = new Element('img',{src:imageUrl});
        img.addClass('legend_image');
        lbl.addClass('legend_active');
        lbl.addEvent('click', this.markerToggle.bind(this));
        ele.grab(img);
        ele.grab(lbl);
        ele.grab(cnt);

        this.legend.grab(ele);
    },
    markerToggle: function(e){
        var ele = $(e.target);
        var idx = ele.getProperty('id').split("_")[1];
        if(ele.hasClass('legend_active')){
            ele.removeClass('legend_active');
            ele.addClass('legend_inactive');
            this.clearOverlays(idx);
        }else{
            ele.removeClass('legend_inactive');
            ele.addClass('legend_active');
            this.showOverlays(idx);
        }
    }

});

/**
 * RandomPoll
 * Used to control AJAX submission of random polls from the sidebar
 */
var RandomPoll = new Class({
    initialize: function (e) {
        this.form = $(e);

        this.form.addEvent('submit', this.submit.bind(this));
    },
    submit: function (e) {
        e.stop();

        var request = new Form.Request(this.form, 'random_poll', {
            requestOptions: {
                //spinnerTarget: 'random_poll_spinner'
            },
            onSuccess: function () {
                Map.ResolveObjects([
                    {selector: 'form.random_poll', type: RandomPoll}
                ]);
            }
        }).send();
    }
});

var MessageSelector = new Class({
    initialize: function(ele){
        this.e = $(ele);
        this.politicianform = $('politician_message_form');
        this.politicianlink = $('politician_select');
        this.groupform = $('group_message_form');
        this.grouplink = $('group_select');
        this.networkform = $('network_message_form') || null;
        this.networklink = $('network_select') || null;
        this.grouplink.addEvent('click', this.group.bind(this));
        if(this.networklink)
            this.networklink.addEvent('click', this.network.bind(this));
        this.politicianlink.addEvent('click', this.politician.bind(this));
        this.politician();
    },
    group: function(){
        this.politicianform.setStyle('display','none');
        if(this.networkform)
            this.networkform.setStyle('display','none');
        this.groupform.setStyle('display','block');
        if(this.politicianlink.hasClass('current'))
            this.politicianlink.removeClass('current');
        if(this.networklink && this.networklink.hasClass('current'))
            this.networklink.removeClass('current');
        this.grouplink.addClass('current');
        //this.politicianlink.setStyle('font-weight', 'normal');
        //this.grouplink.setStyle('font-weight', 'bold');
    },
    politician: function(){
        this.politicianform.setStyle('display','block');
        if(this.networkform)
            this.networkform.setStyle('display','none');
        this.groupform.setStyle('display','none');
        if(this.grouplink.hasClass('current'))
            this.grouplink.removeClass('current');
        if(this.networklink && this.networklink.hasClass('current'))
            this.networklink.removeClass('current');
        this.politicianlink.addClass('current');
        //this.politicianlink.setStyle('font-weight', 'bold');
        //this.grouplink.setStyle('font-weight', 'normal');
    },
    network: function(){
        
        this.politicianform.setStyle('display','none');
        this.groupform.setStyle('display','none');
        this.networkform.setStyle('display','block');
        if(this.politicianlink.hasClass('current'))
            this.politicianlink.removeClass('current');
        if(this.grouplink.hasClass('current'))
            this.grouplink.removeClass('current');
        this.networklink.addClass('current');
        //this.politicianlink.setStyle('font-weight', 'normal');
        //this.grouplink.setStyle('font-weight', 'bold');
    }
});


var Selected = new Class({
   initialize: function(ele){
       $(ele).scrollIntoView();
   }
});

var ConversationButton = new Class({

    initialize: function (b) {
        if($(b).getProperty('href')){
            this.href = $(b).getProperty('href');
        }
        if(!this.href)
            return;
        
        this.init(b, 'Conversation', this.href);

    },
    init: function (b, title, url) {
        b.addEvent('click', function (e) {
            e.stop();

            this.modal = new Modal({
                'parentEl': $$('body')[0],
                'title': title,
                'content': '...loading...',
                'width': 600,
                'height': 350

            });

            // gather the form
            new Request({
                url: url,
                method: 'get',
                onSuccess: function (responseText) {
                    this.modal.setContent(responseText);
                    this.success();
                }.bind(this),
                evalScripts: true
            }).send();
        }.bind(this));
    },
    success: function () {
       
        $('add_reply').addEvent('click', this.reply.bind(this));
    },
    reply: function(e){
        e.stop();
        
        if($('add_reply').getProperty('href')){
            this.reply_url = $('add_reply').getProperty('href');
        }
        if(!this.reply_url)
            return;
        
        new Request({
                url: this.reply_url,
                method: 'get',
                onSuccess: function (responseText) {
                    this.modal.setContent(responseText);

                }.bind(this),
                evalScripts: true
            }).send();
    }
});
var ReplyModal = new Class({

    initialize: function (b) {
        if($(b).getProperty('href')){
            this.actionUrl = $(b).getProperty('href');
        }

        this.title = $(b).getProperty('name') || 'Reply';
        this.init(b, this.title, this.actionUrl);

    },
    init: function (b, title, url) {
        b.addEvent('click', function (e) {
            e.stop();

            this.modal = new Modal({
                'parentEl': $$('body')[0],
                'title': title,
                'content': '...loading...',
                'width': 450,
                'height': 250

            });

            // gather the form
            new Request({
                url: url,
                method: 'get',
                onSuccess: function (responseText) {
                    this.modal.setContent(responseText);
                    this.success();
                }.bind(this),
                evalScripts: true
            }).send();
        }.bind(this));
    },
    success: function () {

    }
});
var AjaxForm = new Class({
    initialize: function (e) {
        e.addEvent('submit', function (event) {
            event.stop();
            new Form.Request(e, 'nothing', {
                onSuccess: function () {
                    $$('.decline_form_wrap').each(function (target) {
                        target.hide();
                    });

                    /* TODO: get next random poll */
                    $('next_random_poll').fireEvent('click',$('next_random_poll'));
                    
                        
                }
            }).send();
        });
    }
});

var CitySmsForm = new Class({
    initialize: function (e) {
         this.textarea_value = '';

         e.addEvent('submit', function (event) {
            event.stop();
            new Form.Request(e, 'nothing', {
                onSuccess: function () {

                },
                onSend: function () {
                    $('sms_notification').set('html', 'sending . . .');
                },
                onComplete: function () {
                    $('sms_notification').set('html', 'sent!');
                }
            }).send();
        });

        e.getElement('textarea').addEvent('keyup', function (event) {
            if (e.getElement('textarea').get('value').length > 139) {
                e.getElement('textarea').set('value', this.textarea_value);
            }
            else
                this.textarea_value = e.getElement('textarea').get('value');
        });
    }
});

var DeclineLink = new Class({
    initialize: function (e) {
        e.addEvent('click', function (event) {
            $(e.get('rel')).show();
            //$$('.decline_form_wrap').each(function (target) {
                
             //   target.show();
            //});
        });
    }
});
var EditModal = new Class({
    initialize: function (b) {
        if($(b).getProperty('href')){
            this.actionUrl = $(b).getProperty('href');
        }
        else if($(b).getProperty('value')){
            this.actionUrl = $(b).getProperty('value');
        }
        else {
            // no action, so do nothing
            return;
        }
        this.title = $(b).getProperty('name') || 'Edit';
        this.init(b, this.title, this.actionUrl);
       
    },
    init: function (b, title, url) {
        b.addEvent('click', function (event) {
            event.stop();
            var w = $(b).getProperty('width') || 600;
            var h = $(b).getProperty('height') || 300;
            this.modal = new Modal({
                'parentEl': $$('body')[0],
                'title': title,
                'content': '...loading...',
                'width': w,
                'height': h

            });

            // gather the form
            new Request({
                url: url,
                method: 'get',
                onSuccess: function (responseText) {
                    this.modal.setContent(responseText);
                    this.success();
                }.bind(this),
                evalScripts: true
            }).send();
        }.bind(this));
    },
    success: function () {
        $$('.office_form_selector').each(function (i) {new OfficeFormSelector(i)});
        $$('.office_class_selector').each(function (i) {new OfficeClassSelector(i)});
        $$('.state_selector').each(function (i) {new StateSelector(i)});
        
        $$('.date_picker').each(function(e){

            var date = new Picker.Date(e, {
                timePicker: false,
                positionOffset: {x: 5, y: 0},
                pickerClass: 'datepicker_vista',
                useFadeInOut: !Browser.ie
            });

        });
        
    }
});
var RegisterModal = new Class({
    initialize: function (b) {
        if($(b).getProperty('href')){
            this.actionUrl = $(b).getProperty('href');
        }
        else if($(b).getProperty('value')){
            this.actionUrl = $(b).getProperty('value');
        }
        else {
            // no action, so do nothing
            return;
        }
        this.title = $(b).getProperty('name') || 'Register';
        this.init(b, this.title, this.actionUrl);

    },
    init: function (b, title, url) {
        b.addEvent('click', function (e) {
            e.stop();

            this.modal = new Modal({
                'parentEl': $$('body')[0],
                'title': title,
                'content': '...loading...',
                'width': 550,
                'height': 250

            });

            // gather the form
            new Request({
                url: url,
                method: 'get',
                onSuccess: function (responseText) {
                    this.modal.setContent(responseText);
                    this.success();
                }.bind(this),
                evalScripts: true
            }).send();
        }.bind(this));
    },
    success: function () {
        
    }
});
var NewModal = new Class({

    initialize: function (b) {
        if($(b).getProperty('href')){
            this.actionUrl = $(b).getProperty('href');
        }else{
            this.actionUrl = $(b).getProperty('id');
        }
        $(b).removeClass('new_modal');
        this.title = $(b).getProperty('name') || 'New';
        this.init(b, this.title, this.actionUrl);

    },
    init: function (b, title, url) {
        b.addEvent('click', function (e) {
            e.stop();

            this.modal = new Modal({
                'parentEl': $$('body')[0],
                'title': title,
                'content': '...loading...',
                'width': 600,
                'height': 300

            });

            // gather the form
            new Request({
                url: url,
                method: 'get',
                onSuccess: function (responseText) {
                    this.modal.setContent(responseText);
                    $$('.message_selector').each(function (i) {new MessageSelector(i)});
                    this.success();
                }.bind(this),
                evalScripts: true
            }).send();
        }.bind(this));
    },
    success: function () {
        

    }
});
var VideoModal = new Class({

    initialize: function (b) {
        if($(b).getProperty('href')){
            this.actionUrl = $(b).getProperty('href');
        }else{
            this.actionUrl = $(b).getProperty('id');
        }
        this.title = $(b).getProperty('name') || 'Watch';
        this.init(b, this.title, this.actionUrl);

    },
    init: function (b, title, url) {
        b.addEvent('click', function (e) {
            e.stop();

            this.modal = new Modal({
                'parentEl': $$('body')[0],
                'title': title,
                'content': '...loading...',
                'width': 550,
                'height': 320

            });

            // gather the form
            new Request({
                url: url,
                method: 'get',
                onSuccess: function (responseText) {
                    this.modal.setContent(responseText);
                    this.success();
                }.bind(this),
                evalScripts: true
            }).send();
        }.bind(this));
    },
    success: function () {

    }
});
var InfoModal = new Class({

    initialize: function (b) {
        this.actionUrl = $(b).getProperty('href');
        this.ele = $(b);
        this.init(b, '', this.actionUrl);
        
    },
    init: function (b, title, url) {
            var w = $(b).getProperty('width') || 400;
            var h = $(b).getProperty('height') || 300;
            var title = $(b).getProperty('title') || '';
            this.modal = new Modal({
                'parentEl': $$('body')[0],
                'title': title,
                'content': '...loading...',
                'width': w,
                'height': h

            });

            // gather the form
            new Request({
                url: url,
                method: 'get',
                onSuccess: function (responseText) {
                    this.modal.setContent(responseText);
                    this.success();
                }.bind(this),
                evalScripts: true
            }).send();

    },
    success: function () {


    }
});
var ShareModal = new Class({

    initialize: function (b) {
        this.actionUrl = $(b).getProperty('href');
        this.ele = $(b);
        this.init(b, '', this.actionUrl);

    },
    init: function (b, title, url) {

            this.modal = new Modal({
                'parentEl': $$('body')[0],
                'title': title,
                'content': '...loading...',
                'width': 400,
                'height': 200

            });

            // gather the form
            new Request({
                url: url,
                method: 'get',
                onSuccess: function (responseText) {
                    this.modal.setContent(responseText);
                    this.success();
                }.bind(this),
                evalScripts: true
            }).send();

    },
    success: function () {


    }
});
var EmailModal = new Class({

    initialize: function (b) {
        if($(b).getProperty('href')){
            this.actionUrl = $(b).getProperty('href');
        }
        else if($(b).getProperty('value')){
            this.actionUrl = $(b).getProperty('value');
        }
        else {
            // no action, so do nothing
            return;
        }
        this.title = $(b).getProperty('name') || 'Email';
        this.init(b, this.title, this.actionUrl);

    },
    init: function (b, title, url) {
        b.addEvent('click', function (e) {
            e.stop();

            this.modal = new Modal({
                'parentEl': $$('body')[0],
                'title': title,
                'content': '...loading...',
                'width': 600,
                'height': 350

            });

            // gather the form
            new Request({
                url: url,
                method: 'get',
                onSuccess: function (responseText) {
                    this.modal.setContent(responseText);
                    this.success();
                }.bind(this),
                evalScripts: true
            }).send();
        }.bind(this));
    },
    success: function () {

    }
});
var StateSelector = new Class({
    initialize: function (ele) {
        this.e = $(ele);
        this.e.addEvent('change', this.selectState.bind(this));
        this.citySelect = this.e.getProperty('city') || null;
        this.countySelect = this.e.getProperty('county') || null;
        this.issueSelect = this.e.getProperty('issue') || null;
        this.schoolDistrictSelect = this.e.getProperty('school_district') || null;

        this.sendRequest(this.e.getProperty('value'));


    },
    selectState: function(e){
       this.sendRequest(e.target.getProperty('value'));

    },
    sendRequest: function(val){

        if(this.citySelect){
           var selected = $(this.citySelect).getProperty('sel') || null;
           if(selected){
               var city = $(this.citySelect);
              city.setProperty('value',selected);
              city.setProperty('sel',null);

           }else{
                 this.request = new Request({
                    url: '/backend.php/office/selectCity',
                    data: {'state':val},
                    onSuccess: function (responseText) {
                       var ele = new Element('div',{html:responseText});
                       var newCitySelect = ele.firstChild;
                       var oldCitySelect = $(this.citySelect);

                       var nm = oldCitySelect.getProperty('name');
                       var parent = oldCitySelect.getParent();
                       parent.grab(newCitySelect);
                       oldCitySelect.destroy();
                       newCitySelect.id = this.citySelect;
                       newCitySelect.name = nm;
                       // need to update drop down list here
                       
                    }.bind(this),
                    onFailure: function (err) {
                       console.debug(err);
                    }
               });
           this.request.send();
           }

        }
        if(this.countySelect){
           selected = $(this.countySelect).getProperty('sel') || null;
           if(selected){
               var county = $(this.countySelect);
              county.setProperty('value',selected);
              county.setProperty('sel',null);

           }else{
            this.request = new Request({
                url: '/backend.php/office/selectCounty',
                data: {'state':val},
                onSuccess: function (responseText) {
                   var ele = new Element('div',{html:responseText});
                   var newCountySelect = ele.firstChild;
                   var oldCountySelect = $(this.countySelect);

                   var nm = oldCountySelect.getProperty('name');
                   var selectParent = oldCountySelect.getParent();
                   selectParent.grab(newCountySelect);
                   oldCountySelect.destroy();
                   newCountySelect.id = this.countySelect;
                   newCountySelect.name = nm;

                }.bind(this),
                onFailure: function (err) {
                   console.debug(err);
                }
            });
            this.request.send();
           }
        }
        if(this.issueSelect){
           selected = $(this.issueSelect).getProperty('sel') || null;
           if(selected){
              var issue = $(this.issueSelect);
              issue.setProperty('value',selected);
              issue.setProperty('sel',null);

           }else{
            this.request = new Request({
                url: '/issue/selectStateIssue',
                data: {'state':val},
                onSuccess: function (responseText) {
                   var ele = new Element('div',{html:responseText});
                   var newIssueSelect = ele.firstChild;
                   var oldIssueSelect = $(this.issueSelect);

                   var nm = oldIssueSelect.getProperty('name');
                   var selectParent = oldIssueSelect.getParent();
                   selectParent.grab(newIssueSelect);
                   oldIssueSelect.destroy();
                   newIssueSelect.id = this.issueSelect;
                   newIssueSelect.name = nm;

                }.bind(this),
                onFailure: function (err) {
                   console.debug(err);
                }
            });
            this.request.send();
           }
        }
        if(this.schoolDistrictSelect){
           selected = $(this.schoolDistrictSelect).getProperty('sel') || null;
           if(selected){
               var dist = $(this.schoolDistrictSelect);
              dist.setProperty('value',selected);
              dist.setProperty('sel',null);

           }else{
            this.request = new Request({
                url: '/backend.php/office/selectDistrict',
                data: {'state':val},
                onSuccess: function (responseText) {
                   var ele = new Element('div',{html:responseText});
                   var newDistrictSelect = ele.firstChild;
                   var oldDistrictSelect = $(this.schoolDistrictSelect);

                   var nm = oldDistrictSelect.getProperty('name');
                   var selectParent = oldDistrictSelect.getParent();
                   selectParent.grab(newDistrictSelect);
                   oldDistrictSelect.destroy();
                   newDistrictSelect.id = this.schoolDistrictSelect;
                   newDistrictSelect.name = nm;

                }.bind(this),
                onFailure: function (err) {
                   console.debug(err);
                }
            });
            this.request.send();
           }
        }

    }
});
/**
* selects a list of issues based on the value passed in
* can be state, city, group, school_district, or nation
*/
var IssueSelector = new Class({
    initialize: function (ele) {
        this.e = $(ele);
        this.type = this.e.getProperty('related_type');
        var related = this.e.getProperty('related_select');       
        
        if(!this.type || !related)
            return;
        
        this.relatedSelect = $(related);
        if(!this.relatedSelect)
            return;
        
        this.e.addEvent('change', this.selectIssue.bind(this));
        this.sendRequest(this.e.getProperty('value'));
    },
    selectIssue: function(e){
       this.sendRequest(e.target.getProperty('value'));
    },
    getRequestUrl: function(){
        if(this.type == 'school_district')
            return '/issue/selectSchoolDistrictIssue';
        else if(this.type == 'state')
            return '/issue/selectStateIssue';
        else if(this.type == 'city')
            return '/issue/selectCityIssue';
        else if(this.type == 'county')
            return '/issue/selectCountyIssue';
        else 
            return '/issue/selectNationalIssue';
    },
    sendRequest: function(val){
 
       var selected = this.relatedSelect.getProperty('sel') || null;
       if(selected){
          this.relatedSelect.setProperty('value',selected);
          this.relatedSelect.setProperty('sel',null);

       }else{
            this.request = new Request({
                url: this.getRequestUrl(),
                data: {'id':val},
                onSuccess: function (responseText) {
                   var ele = new Element('div',{html:responseText});
                   var newIssueSelect = ele.firstChild;
                   
                   var id = this.relatedSelect.getProperty('id');
                   var nm = this.relatedSelect.getProperty('name');
                   var selectParent = this.relatedSelect.getParent();
                   selectParent.grab(newIssueSelect);
                   this.relatedSelect.destroy();
                   newIssueSelect.id = id;
                   newIssueSelect.name = nm;
                   this.relatedSelect = $(newIssueSelect);

                }.bind(this),
                onFailure: function (err) {
                   console.debug(err);
                }
            });
        this.request.send();
       }
        
        

    }
});
var PoliticianGroupSelector = new Class({
    initialize: function (ele) {
        this.e = $(ele);
        this.list = $(this.e.getProperty('value'));
        this.children = this.list.getChildren('ul li input');
        this.setUpEvents();

    },
    setUpEvents: function(){
        this.e.addEvent('click', this.toggle.bind(this));
        this.children.each(function (e){
            e.addEvent('click', this.selectPolitician.bind(this));
        }.bind(this));
    },
    selectPolitician: function(e){
        // if it's checked and all the children are checked then check the parent
        // if it's not checked then make sure the parent is not checked
        var ele = $(e.target);
        var checked = ele.getProperty('checked');

        if(checked){
            var allChildrenSelected = true;
            this.children.each(function(c){
                if(!c.getProperty('checked')){
                    allChildrenSelected = false;
                }
            });
            this.e.setProperty('checked', allChildrenSelected);
        }else{
            this.e.setProperty('checked', false);
        }
    },
    toggle: function(){
        var checked = this.e.getProperty('checked');
        this.children.each(function (e){
            e.setProperty('checked', checked);
        });
    }
});

var FacebookComment = new Class({
	initialize: function (f) {
		this.f = $(f);

		this.f.addEvent('submit', this.submit.bind(this));
	},
	submit: function (e) {
		e.stop();
		if (window.fbAsyncInit) window.fbAsyncInit();

		try {
			FB.ui({
				method: 'feed',
				message: this.f.getElement('.comment_content').value,
				link: window.location.href,
				caption: 'Icount.com Comment'
			}, function (response) {
				this.f.submit();
			}.bind(this));
		}
		catch(e) {
			this.f.submit();
		}
	}
});

var FacebookPost = new Class({
    initialize: function (f) {
        this.f = $(f);
        this.link = this.f.getProperty('redirectUrl') || 'http://www.icount.com';
        this.caption = this.f.getProperty('title') || null;
        this.description = this.f.getProperty('summary') || 'Participate in polls and public opinion surveys, vote on bills before they become laws, start or sign petitions, and help spread awareness of issues that are important to you.';   
        this.f.addEvent('click', this.sendMessage.bind(this));
    },
    sendMessage: function (e) {
        e.stop();
        if (window.fbAsyncInit) window.fbAsyncInit();
        
        try {
            FB.ui(
            {
                method: 'feed',
                name: 'Icount',
                link: this.link,
                picture: 'http://www.icount.com/images/img_logo_tm.png',
                caption: this.caption,
                message: 'this is the default message',
                description: this.description
            },
            function(response) {
                
                if (response && response.post_id) {
                    var ctaid = this.f.getProperty('cta_id') || null;
                    if(ctaid){
                       new Request({
                            url: 'call_to_action/facebookPostSuccess',
                            data: {
                                id : ctaid
                                
                            },
                            onSuccess: function (response) {
                                
                            }.bind(this)
                        }).send();
                    }
                    
                    
                } else {
                   //alert('Post was not published.');
                }
            }.bind(this));
        }
        catch(e) {
			
        }
    }
});
var FacebookMessage = new Class({
	initialize: function (f) {
		this.f = $(f);
                this.f.addEvent('click', this.sendMessage.bind(this));
	},
	sendMessage: function (e) {
            e.stop();
            if (window.fbAsyncInit) window.fbAsyncInit();
            var link = this.f.getProperty('redirectUrl') || 'http://www.icount.com';
            var des = this.f.getProperty('title') || 'Participate in polls and public opinion surveys, vote on bills before they become laws, start or sign petitions, and help spread awareness of issues that are important to you.';
            var to = this.f.getProperty('id');
            try {
                FB.ui({
                      method: 'send',
                      name: 'Icount',
                      to: to,
                      caption: 'test caption',
                      link: link,
                      picture: 'http://www.icount.com/images/img_logo_tm.png',
                      description: des
                  }, function(response){
                      
                      
                  }.bind(this));

            }
            catch(e) {
                    console.log('error in fb message');
            }
	
             
        }
});
var FacebookPopMessage = new Class({
	initialize: function (f) {
		this.f = $(f);
                this.sendMessage();
	},
	sendMessage: function () {
          
            if (window.fbAsyncInit) window.fbAsyncInit();
            var link = this.f.getProperty('redirectUrl') || 'http://www.icount.com';
            var des = this.f.getProperty('summary') || 'Participate in polls and public opinion surveys, vote on bills before they become laws, start or sign petitions, and help spread awareness of issues that are important to you.';
            var to = this.f.getProperty('id');
            try {
                FB.ui({
                      method: 'send',
                      name: this.f.getProperty('title') || 'Icount',
                      to: to,
                      link: link,
                      picture: 'http://www.icount.com/images/img_logo_tm.png',
                      description: des
                  }, function(response){
                      
                      
                  }.bind(this));

            }
            catch(e) {
                    console.log('error in fb message');
            }
	
             
        }
});
var FacebookInvitation = new Class({
	initialize: function (f) {
		this.f = $(f);
                this.f.addEvent('click', this.sendMessage.bind(this));
	},
	sendMessage: function (e) {
            e.stop();
            if (window.fbAsyncInit) window.fbAsyncInit();

            try {
                FB.ui({
                      method: 'send',
                      name: 'Icount',
                      to: e.target.get('id'),
                      link: 'http://www.icount.com/polloftheweek',
                      picture: 'http://www.icount.com/images/img_logo_tm.png',
                      description: 'Participate in polls and public opinion surveys, vote on bills before they become laws, start or sign petitions, and help spread awareness of issues that are important to you.'
                  }, function(response){
                      this.updateUserInvite(response);
                  }.bind(this));

            }
            catch(e) {
                    this.f.submit();
            }
	},
        updateUserInvite: function(response){
            
            if (response) {
                  new Request({
                    url: '/facebook/addUserInvitation',
                    method: 'post',
                    data: {
                        friend_id : this.f.getProperty('id'),
                        friend_name: this.f.getProperty('name')
                    },
                    onSuccess: function (responseText) {
                        location.reload(true);
                    }.bind(this),
                    onFailure: function(r){
                        location.reload(true);
                    }
                }).send();
            } else {
                // to do: deal with error in response
            }
            
             
        }
});
var FacebookRequest = new Class({
	initialize: function (f) {
		this.f = $(f);
                this.f.addEvent('click', this.sendRequest.bind(this));
	},
	sendRequest: function (e) {
            e.stop();
            if (window.fbAsyncInit) window.fbAsyncInit();

            try {
                FB.ui({
                      method: 'apprequests',
                      message: 'Participate in polls and public opinion surveys, vote on bills before they become laws, start or sign petitions, and help spread awareness of issues that are important to you.'
                  }, function(response){
                      this.handleResponse(response);
                  }.bind(this));

            }
            catch(e) {
                    this.f.submit();
            }
	},
        handleResponse: function(response){
            
            // if there is a response then it will be an array of ids that got sent the invite
            
             
        }
});

// this is a checkbox in a form that when checked will
// send the param "checked" : true/false to the forms action url
var AjaxCheckbox = new Class({
    initialize: function (a) {
        this.a = $(a);
        if (!this.a)
            return;

        this.actionurl = $(this.a.form).getProperty('action');
        this.a.addEvent('click', this.process.bind(this));

    },
    process: function (e) {
        //e.stop();
        new Request.HTML({
            url: this.actionurl,
            data: {
                checked : this.a.checked,
                name: this.a.name || null
            },
            onSuccess: function (response) {
                // is there anything to do here?
            }.bind(this)
        }).send();
    }
});
// this is a checkbox in a form that when checked will
// send the param "checked" : true/false to the forms action url
var PrivacyCheckbox = new Class({
    initialize: function (a) {
        this.a = $(a);
        if (!this.a)
            return;

        this.actionurl = $(this.a.form).getProperty('action');
        this.a.addEvent('click', this.process.bind(this));
    },
    process: function (e) {
        //e.stop();
        var checked = this.a.checked;

        new Request.HTML({
            url: this.actionurl,
            data: {
                checked : checked,
                id: this.a.value || null
            },
            onSuccess: function (response) {
                // is there anything to do here?

            }.bind(this)
        }).send();
    }
});


var User = new Class({
    initialize: function () {

    },
    isAuthenticated: function () {
        return $('user_id').value != '';
    },
    getId: function () {
        return $('user_id').value;
    }
});

var PhoneVerifyModal = new Class({
	initialize: function (a) {
		this.a = $(a);

		this.a.addEvent('click', this.pop.bind(this));
	},
	pop: function (e) {
		e.stop();
		this.modal = new Modal({
            'parentEl': $$('body')[0],
            'title': 'Verify Phone Number',
            'content': '...loading...',
            'width': 400,
            'height': 200
        });

		new Request({
			url: '/twilio/verifyNumber',
			method: 'post',
			onSuccess: function (response) {
				this.modal.setContent(response);

				new PhonePinForm($('phone_pin_form'));
			}.bind(this),
			evalScripts: true
		}).send();
	}
});

var PhonePinForm = new Class({
	initialize: function (f) {
		this.f = $(f);

		this.f.addEvent('submit', this.submitl.bind(this));
	},
	submitl: function (e) {
		e.stop();

		new Form.Request(this.f, 'verify_pin', {
			onSuccess: function (e) {
				$('phone_verified_span').set('text', '');
			}
		}).send();
	}
});

var FeedClose = new Class({
    initialize: function (b) {
        if($(b).getProperty('href')){
            this.actionUrl = $(b).getProperty('href');
        }
        if($(b).getProperty('rel')){
            this.relatedId = $(b).getProperty('rel');
        }

        this.init(b, this.actionUrl, this.relatedId);

    },
    init: function (b, url, relId) {
        b.addEvent('click', function (e) {
            e.stop();

            new Request({
                url: url,
                method: 'get',
                onSuccess: function (responseText) {
                    $(relId).setProperty('html','');
                }.bind(this),
                evalScripts: true
            }).send();
        }.bind(this));
    }
});

var Debate = new Class({
    initialize: function (b) {
        this.ele = $(b);

        this.setUpColumns();
        this.setUpQuestions();
     },
     setUpColumns: function(){
         var cols = this.ele.getElements('.debate_columns');
         cols.each(function(col){
             this.setColumnSettings(col);
         }.bind(this));
     },
     setColumnSettings: function(col){
        var tallest = 0;
        var cols = col.getChildren('.debate_column');
        var numcols = cols.length;

        // set the width of each column
        var width = this.ele.getWidth();
        // subtract one to allow for border
        var colwidth = (width/numcols) - 10;

        cols.each(function (i) {
              i.setStyle('width',""+colwidth+"px");
        });

        // set the height of each column
        cols.each(function (i) {
             var height = i.getHeight();
              if(parseInt(height) > tallest){
                  tallest = parseInt(height);
              }
        });
        cols.each(function (i) {
              i.setStyle('height',""+tallest+"px");
        });
     },
     setUpQuestions: function(){
         this.questions = this.ele.getElements('.debate_question_toggler');
         this.questions.each(function(q){
             q.addEvent('click',this.toggleQuestion.bind(this));

             q.getChildren().each(function(c){
                 c.addEvent('click',this.toggleQuestion.bind(this));
             }.bind(this));
             var el = $(q.getProperty('rel'));
             var hash = window.location.hash.replace('#', '');
            
             if(el.getProperty('id') == hash || el.getElementById(hash))
                 el.setStyle('display','block');
             else
                el.setStyle('display','none');
         }.bind(this));
         this.rel = this.ele.getProperty('rel') || null;
     },
     toggleQuestion: function(e){
        e.stop();
        var ele = $(e.target);

        var rel = $(ele.getProperty('rel')) || null;
        if(rel){
            // toggle
            if(rel.getStyle('display') && rel.getStyle('display') == "block"){
                rel.setStyle('display','none');
            }else{
                rel.setStyle('display','block');
            }
        }
     }

});

var SettingsMenu = new Class({
    initialize: function (a) {
        this.a = $(a);
        this.a.addEvent('click', this.click.bind(this));
        this.showing = false;

        var img = new Image();
        img.src = '/images/icons/downarrow_active.png';
    },
    click: function (e) {
        e.stop();

        $('settings_block').toggle();
        this.showing = this.showing ? false : true;

        /* change colors */
        this.a.toggleClass('selected');
        /* blue arrow */
        if (this.showing)
            this.a.getElements('img')[0].set('src', '/images/icons/downarrow_active.png');
        else
            this.a.getElements('img')[0].set('src', '/images/icons/downarrow.png');
    }
});

var PlusLink = new Class({
    initialize: function (a) {
        this.a = $(a);
        this.a.addEvent('click', function (event) {
            event.stop();

            this.a.getNext('ul.subnav').toggleClass('active');
        }.bind(this));
    }
});

var ShowOnHover = new Class({
    initialize: function(ele){
        this.e = $(ele);
        this.e.addEvent('mouseover', this.show.bind(this));
        this.e.addEvent('mouseout', this.hide.bind(this));
        this.c = this.e.getElements('.hover');
        this.hide();
    },
    show: function(event){
        this.c.each(function(h){
            h.setStyle('display','block');
        });
    },
    hide: function(event){

        this.c.each(function(h){
            h.setStyle('display','none');
        });
    }
});
var AgendaItemUpdater = new Class({
    initialize: function (ele) {
        this.e = $(ele);
        this.refElement = $('agenda_item_list');
        this.ajaxRequest = this.e.getProperty('href') || null;
        this.confirmMsg = this.e.getProperty('confirmMsg') || null;
        this.e.addEvent('click', this.sendRequest.bind(this));
    },
    sendRequest: function(e){
        e.stop();

        var confirm = true;
        if(this.confirmMsg){
            confirm = window.confirm(this.confirmMsg);
        }
        if(!confirm)
            return;
        
        this.refElement.removeEvents();

        new Request({
            url: this.ajaxRequest,
            onSuccess: function (responseText) {
                this.refElement.setProperty('html',responseText);

                // set up handlers here
            
                var children = this.refElement.getElements('.agenda_item_update');
                children.each(function (i) {
                    new AgendaItemUpdater(i)
                    });
                // edit_modal
                children = this.refElement.getElements('.edit_modal');
                children.each(function (i) {
                    new EditModal(i)
                    });
                // ajax_checkbox
                children = this.refElement.getElements('.ajax_checkbox');
                children.each(function (i) {
                    new AjaxCheckbox(i)
                    });
            }.bind(this),
            onFailure: function (err) {
                console.debug(err);
            }
        }).send();
    }
});

var FormPreview = new Class({
    initialize: function(ele){
        this.e = $(ele);
        this.form = this.e.form;
        this.e.addEvent('click', this.showPreview.bind(this));
        this.url = this.e.getProperty('href');
    },
    showPreview: function(e){
        e.preventDefault();
        this.modal = new Modal({
                'parentEl': $$('body')[0],
                'title': 'Preview your comment',
                'content': '...loading...',
                'width': 400,
                'height': 200

            });
        new Request({
                url: this.url,
                method: 'post',
                data: this.form,
                onSuccess: function (responseText) {
                    this.modal.setContent(responseText);
                    this.success();
                }.bind(this),
                evalScripts: true
            }).send();
    },
    success: function(){
        
    }
            
});
var ShareButton = new Class({
    initialize: function(ele){
        this.e = $(ele);
        this.e.addEvent('click', this.share.bind(this));
        this.button = addthis.button('#'+this.e.getProperty('id'), {
            username: 'gr3gg0r',
            ui_click: 1,
            services_compact: 'facebook,twitter,mailto,gmail,hotmail,yahoomail,linkedin,myspace,googlebuzz,googlereader',
            services_expanded: ''
        }, {
            url: this.e.getProperty('href'),
            title: 'shared from icount.com',
            templates: {
                twitter: 'check out {{url}} on icount.com'
            }
        });
    },
    share: function(e){
       e.stop(); 
    }
});
var ConnectionFilter = new Class({
    initialize: function (ele) {
        this.ele = $(ele);
        this.ele.addEvent('click', this.filter.bind(this));       
    },
    filter: function () {
        var nm = this.ele.getProperty('name'); 
        var title = this.ele.getProperty('title') || "";
        $('filter_title').setProperty('html',title);
        $$(".connection_filter_item").each(function (c) {           
            if(c.hasClass(nm) || (nm == 'all' && !c.hasClass('constituent'))){
                c.setStyle('display','inline');
            }else{
                c.setStyle('display','none');
            }
            
        });
  
    }
});
var MenuFilter = new Class({
    initialize: function (ele) {
        this.ele = $(ele);
        this.ele.addEvent('click', this.filter.bind(this));       
    },
    filter: function () {
        var nm = this.ele.getProperty('name'); 
        var title = this.ele.getProperty('title') || "";
        $('filter_title').setProperty('html',title);
        $$(".menu_filter_item").each(function (c) {           
            if(c.hasClass(nm) || nm == 'all'){
                c.setStyle('display','inline');
            }else{
                c.setStyle('display','none');
            }
            
        });
  
    }
});
var RemoveFromNetworkLink = new Class({
    initialize: function(ele){
        this.e = $(ele);
        this.url = this.e.getProperty('href') || null;
        if(!this.url)
            return;
        this.relatedElement = $(this.e.getProperty('rel')) || this.e;
        this.networkId = this.e.getProperty('network_id');
        this.contactId = this.e.getProperty('contact_id');
        this.e.addEvent('click',this.removeContactFromNetwork.bind(this));
       
    },
    removeContactFromNetwork: function(evt){
        evt.stop();
        new Request({
            url: this.url,
            onSuccess: function (responseText) {
                if(responseText != 'failure'){
                    if($('contact_'+this.contactId).hasClass('network_'+this.networkId))
                        $('contact_'+this.contactId).removeClass('network_'+this.networkId);  
                    var str = "network_"+this.networkId+"_count";
                    $(str).setProperty('html',responseText);
                    this.updateNetworks();
                }
                 
            }.bind(this),
            evalScripts: true
        }).send();
    },
    updateNetworks: function(){
        new Request({
            url: '/network/networks',
            data: {
                "contact_id":this.contactId
                },
            onSuccess: function (responseText) {
                if(responseText != 'failure'){
                    $("networks_for_contact_"+this.contactId).setProperty('html',responseText);
                    var children = $("networks_for_contact_"+this.contactId).getElements('.remove_from_network_link');
                    children.each(function (i) {
                        new RemoveFromNetworkLink(i)
                        });
                }
                this.refreshConnectionList();   
            }.bind(this)
        }).send();
    },
    refreshConnectionList: function(){
        var ftitle = $('filter_title').getProperty('html');
        var currentFilter = $$('[title='+ftitle+']') || null;
        
        if(currentFilter)
            currentFilter.fireEvent('click');
    }
});

var DeleteContactLink = new Class({
    initialize: function(ele){
        this.e = $(ele);
        this.url = this.e.getProperty('href') || null;
        if(!this.url)
            return;
        this.relatedElement = $(this.e.getProperty('rel')) || this.e;
        this.e.addEvent('click',this.removeContact.bind(this));
       
    },
    removeContact: function(evt){
        evt.stop();
        if(window.confirm("Are you sure you would like to delete this connection?")){
            new Request({
                url: this.url,
                onSuccess: function (responseText) {
                    if(responseText != 'failure'){
                        this.relatedElement.destroy();
                        this.updateNetworkMenu();
                    }
                }.bind(this),
                evalScripts: true
            }).send();
        }
        
    },
    updateNetworkMenu: function(){
        new Request({
            url: 'network/networkMenu',
            onSuccess: function (responseText) {
                if(responseText != 'failure'){
                    $('network_menu').setProperty('html',responseText);
                    var children = $('network_menu').getElements('.connection_filter');
                    children.each(function(c){
                        new ConnectionFilter(c);
                    });
                    var children = $('network_menu').getElements('.new_modal');
                    children.each(function(c){
                        new NewModal(c);
                    });
                }
            }.bind(this),
            evalScripts: true
        }).send();
    }
});

var ShareForm = new Class({
    initialize: function(ele){
        this.e = $(ele);
        this.e.removeClass('share_form');
        this.keys = ["email","first_name","last_name"];  
        
        this.initAutoComplete();
    },
    getValueFromKeys: function(obj, text){
            var key, match=false;
            for (var i = 0; key = this.keys[i++];){
                if(obj[key]){
                    match = obj[key].test(new RegExp('^' + text.escapeRegExp(), 'i'));
                }
                if(match)
                    return true;
            } 
            return false;
    },
    getLabelForObject : function(obj){
                var lbl = "";
                if(obj['first_name'])
                    lbl += obj['first_name']+" ";
                if(obj['last_name'])
                    lbl += obj['last_name'] + " ";
                if(obj['email'])
                    lbl += obj['email'];
                return lbl;
                
    },
    addEmail : function(evt){          
       evt.stop(); 
       var value = this.autoCompleteInput.getProperty('value');
       if(value){
            var contact = new Element('input',{
                type:'hidden',
                name:'new_contact[]',
                value:value
            });
            var newId = 'contact_'+ new Date().getTime();
            var lbl = new Element('label',{html:value});
            var close = new Element('a',{href:"javascript:void(0);",html:'[x]'});
            close.addEvent('click',function(){$(newId).destroy()});
            close.addClass('right');
            var ele = new Element('li',{id:newId});
            ele.inject(this.list,'top');
            close.inject(ele);
            contact.inject(ele);
            lbl.inject(ele);

            this.autoCompleteInput.setProperty('value','');
        }        
    }, 
    initAutoComplete: function(){
        
        this.autoCompleteInput = this.e.getElements('.auto_complete')[0];
        this.autoCompleteInput.addEvent('keypress',function(evt){if(evt.key=="enter") evt.stop();});
        this.list = $(this.autoCompleteInput.getProperty('list'));
        this.add = $(this.autoCompleteInput.getProperty('add'));
        this.add.addEvent('click',this.addEmail.bind(this));
        var me = this;
        new Meio.Autocomplete(this.autoCompleteInput, '/network/getContacts', {
            selectOnTab: true,
            onNoItemToList: function(elements){
                   // elements.field.node.highlight('#ff0000');
            },
            filter: {
                    filter: function(text, data){
                        // this is for starts with

                        return text ? me.getValueFromKeys(data, text) : true;
                        // this is for contains
                      // return text ? getValueFromKeys(data, keys).test(new RegExp(text.escapeRegExp(), 'i')) : true;
                    },
                    formatMatch: function(text, data){
                        return me.getLabelForObject(data);
                    },
                    formatItem: function(text, data, i){
                        return text ? me.getLabelForObject(data).replace(new RegExp('(' + text.escapeRegExp() + ')', 'gi'), '<strong>$1</strong>') : me.getLabelForObject(data);
                    }
            },
            onSelect: function(elements,value){ 
                var contact = new Element('input',{
                    type:'hidden',
                    name:'contact[]',
                    value:value['id']

                });
                var lbl = new Element('label',{html:me.getLabelForObject(value)});
                var close = new Element('a',{href:"javascript:void(0);",html:'[x]'});
                close.addEvent('click',function(){$('contact_'+value['id']).destroy()});
                close.addClass('right');
                var ele = new Element('li',{id:'contact_'+value['id']});
                ele.inject(me.list,'top');
                close.inject(ele);
                contact.inject(ele);
                lbl.inject(ele);
                me.autoCompleteInput.setProperty('value','');
            }
        });              
     }         
});

var CallToActionForm = new Class({
    initialize: function(eleId){
        this.e = $(eleId);
        if(!this.e)
            return;
        this.initEditFields();
        this.e.addEvent('submit',this.submitForm.bind(this));
    },
    initEditFields: function(){
        this.editableFields = new Array();
        var editableArr = this.e.getElements('.editable');
        editableArr.each(function(e){
            this.editableFields.push(new EditableField(e));          
        }.bind(this));
    },
    submitForm: function(e){
        e.preventDefault();
        e.stop();  
        e.stopPropagation();
        var valid = true;
        this.editableFields.each(function(e){
            if(!e.isValid()){
                valid = false;
                window.alert('please enter all call to action values');
 
            } 
            
        });
        
        if(valid)
            this.e.submit();
    }
    
});
var EditableField = new Class({
    initialize: function(ele){
        this.e = $(ele);       
        this.editable_field = this.e.getElements('.editable_field')[0] || null;
        this.editable_value = this.e.getElements('.editable_value')[0] || null;
        this.editable_link = this.e.getElements('.editable_link')[0] || null;
        this.edit_complete = this.e.getElements('.edit_complete')[0] || null;
       
        if(!this.editable_field || !this.editable_value)
            return;
        this.e.addEvent('blur',this.editFieldComplete.bind(this));
        this.editable_value.addEvent('click',this.editField.bind(this));
        if(this.editable_link)
            this.editable_link.addEvent('click',this.editField.bind(this));
        this.editable_field.addEvent('blur',this.editFieldComplete.bind(this));
        this.editable_field.addEvent('change',this.editFieldComplete.bind(this));
        if(this.editable_field.getProperty('type') == 'text')
            this.editable_field.addEvent('keypress',this.ignoreEnter.bind(this));
        this.editFieldComplete();
        
    },
    ignoreEnter: function(evt){
        if(evt.key == "enter"){
            evt.preventDefault();
        }
    },
    editField: function(e){
        e.stop();     
        this.editable_value.setStyle('display','none');
        if(this.editable_link)
            this.editable_link.setStyle('display','none');
        this.editable_field.setStyle('display','inline');
        if(this.edit_complete)
            this.edit_complete.setStyle('display','inline');
        this.editable_field.focus();
        
    },
    editFieldComplete: function(){   
        var val = this.editable_field.getProperty('value');
        if(val){
            this.editable_value.setProperty('html',val.replace(/\n/g,'<br/>'));
            this.editable_field.setStyle('display','none');
            this.editable_value.setStyle('display','inline');
            if(this.editable_link)
                this.editable_link.setStyle('display','inline');
            if(this.edit_complete)
                this.edit_complete.setStyle('display','none');
        }else{
            if(this.editable_link)
                this.editable_link.setStyle('display','none');

        }
    },
    isValid: function(){
        var valid = true;
        if(this.editable_field.hasClass('required')){
            
            valid = this.editable_field.getProperty('value') ? true : false;
        }
        return valid;
    }
})
