document.observe('dom:loaded', function () {
    var root_url = location.href.replace(location.pathname + location.search + location.hash, '/');
    var cur_url = location.href.replace(location.search + location.hash, '');
    $$('a').each(function (link) {
        if (link.href == cur_url || (location.href.indexOf(link.href) == 0 && link.href != root_url)) {
            if(location.href.indexOf(root_url + 'news/dossier/') == 0 && link.href == root_url +'news/')
                return;
            link.addClassName('active');
        }
    });
    $$('a.popup').each(function (el) {
        el.observe('click', function (event) {
            var href = event.element().href;
            if (href.indexOf('?') == -1)
                href += '?_popup=1';
            else
                href += '&_popup=1';
            var win = window.open(href, href, 'height=500,width=800,resizable=yes,scrollbars=yes');
            win.focus();
            event.stop();
        });
    });
    document.fire('base:loaded');
});

var Dah = {
    articles: {},
    base: {},
    forms: {},
    stock: {},
    stockportfolio: {}
}

Dah.stock.StockChartGraph = Class.create({
    initialize: function(element, options) {
        this.element = $(element);
        this.options = $H({
            daterange: '1d',
            url: '',
            widget_pk: -1,
            max_indices: 5,
            chart_size: [640, 360]
        });
        this.stocks = new Array();
        this.options.update(options);

        this.img = this.element.down('img[class=chart]');
        this.select = this.element.down('select[name=stock]');
        this.close_buttons = this.element.down('div[class=close_buttons]');

        this.select.observe('change', function() {
            var stock = this.select.getValue();
            if (stock && stock != '')
                this.add_stock(stock).update_graph();
        }.bind(this));
        this.element.set_daterange = this.set_daterange.bind(this);
    },

    update_graph: function() {
        var query = Object.toQueryString({
            'widget_pk': this.options.get('widget_pk'),
            'stock': this.stocks,
            'daterange': this.options.get('daterange')
        });

        // BEGIN IE6 HACK
        //  problem: when IE6 calls this.element.set_daterange through an onclick method,
        //   the graph does not get updated properly. seems like it fails when called from
        //   a wrong thread of execution.
        //  solution: instead of calling this.img.src = url directly, we shove it into a
        //   different thread using setTimeout.
        var url = this.options.get('url') + '?' + query + '&' + Math.random();
        var img = this.img;
        setTimeout(function() { img.src = url; }, 0);
        // END IE6 HACK

        // Add pretty X's to "close" the indices
        this.close_buttons.update();
        this.close_buttons.style.left = ((this.close_buttons.parentNode.offsetWidth - this.options.get('chart_size')[0]) / 2) + 'px';

        if (this.stocks.length > 1) {
            function mkclosure(obj, stock) {
                return function() { obj.remove_stock(stock).update_graph(); }
            }
            for (i = 0; i < this.stocks.length; ++i) {
                var a = new Element('a').update('<span>X</span>');
                a.observe('click', mkclosure(this, this.stocks[i]));
                a.style.position = 'absolute';
                // FIXME we could use options.chart_size for calculation of the following two
                a.style.left = '22px';
                a.style.bottom = parseInt((13 + (this.stocks.length - i - 1) * 14.5)) + 'px';
                this.close_buttons.insert(a);
            }
        }
        return this;
    },

    set_daterange: function(daterange) {
        this.options.set('daterange', daterange);
        return this;
    },

    add_stock: function(stock) {
        if (this.stocks.length < this.options.get('max_indices'))
            this.stocks[this.stocks.length] = stock;
        this.stocks = this.stocks.uniq(); // Use every stock only once
        if (this.stocks.length >= this.options.get('max_indices'))
            this.select.disable();
        return this;
    },

    remove_stock: function(stock) {
        for (i = 0; i < this.stocks.length; ++i) {
            if (this.stocks[i] == stock) {
                this.stocks.splice(i, 1);
                break;
            }
        }
        if (this.stocks.length < this.options.get('max_indices'))
            this.select.enable();
        return this;
    }
});

Dah.stock.StockList = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({
            object_id: null,
            refresh: 0,
            url: ''
        });
        this.options.update(options);

        this.container = this.element.down('.stocklist');
        this.select_index = this.element.down('select[name=index]');
        this.select_sector = this.element.down('select[name=sector]');

        if (this.options.get('refresh') > 0)
            this.timer = setInterval(this.update.bind(this), this.options.get('refresh'))
        if (!Object.isUndefined(this.select_index))
            this.select_index.observe('change', this.on_change.bind(this));
        if (!Object.isUndefined(this.select_sector))
            this.select_sector.observe('change', this.on_change.bind(this));
        document.observe('widget:watchlist', this.update.bind(this));
    },

    update: function () {
        var object_id = '', index_id = '', sector_id = '';
        object_id = this.options.get('object_id');
        if (!Object.isUndefined(this.select_index))
            index_id = this.select_index.getValue();
        if (!Object.isUndefined(this.select_sector))
            sector_id = this.select_sector.getValue();

        new Ajax.Request(this.options.get('url'), {
            method: 'get',
            parameters: {
                'object': object_id,
                'index': index_id,
                'sector': sector_id
            },
            onSuccess: function (response) {
                this.container.update(response.responseText);
            }.bind(this)
        });
    },
    
    on_change: function (event) {
        if (this.timer) {
            clearTimeout(this.timer);
            this.timer = setInterval(this.update.bind(this), this.options.get('refresh'));
        }
        this.update();
    }
});

Dah.stock.TurboSpeederList = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({
            url: '',
            page: 1,
            widget_pk: -1
        });
        this.options.update(options);

        this.container = this.element.down('.turbospeederlist');
        this.select = this.element.down('select[name=index]');

        if (!Object.isUndefined(this.select))
            this.select.observe('change', this.update_index.bind(this));

        this.element.set_page = this.set_page.bind(this);
    },

    update: function () {
        if (!Object.isUndefined(this.select))
        {
            new Ajax.Request(this.options.get('url'), {
                method: 'get',
                parameters: {
                    'index': this.select.getValue(),
                    'page': this.options.get('page'),
                    'widget_pk': this.options.get('widget_pk')
                },
                onSuccess: function (response) {
                    this.container.update(response.responseText);
                }.bind(this)
            });
        }
        return this;
    },

    update_index: function () {
        return this.set_page(1).update();
    },

    set_page: function(page) {
        this.options.set('page', page);
        return this;
    }

});

Dah.stock.MutualFundList = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({
            url: '',
            page: 1,
            widget_pk: -1
        });
        this.options.update(options);

        this.container = this.element.down('.mutualfundlist');
        this.select = this.element.down('select[name=index]');
        this.select_provider = this.element.down('select[name=provider]');

        if (!Object.isUndefined(this.select))
            this.select.observe('change', this.update_index.bind(this));
        
        if (!Object.isUndefined(this.select_provider))
            this.select_provider.observe('change', this.update_index.bind(this));
        
        this.element.set_page = this.set_page.bind(this);
    },

    update: function () {
        if (!Object.isUndefined(this.select) && !Object.isUndefined(this.select_provider)) {
            new Ajax.Request(this.options.get('url'), {
                method: 'get',
                parameters: {
                    'index': this.select.getValue(),
                    'provider': this.select_provider.getValue(),
                    'page': this.options.get('page'),
                    'widget_pk': this.options.get('widget_pk')
                },
                onSuccess: function (response) {
                    this.container.update(response.responseText);
                }.bind(this)
            });
        }
        return this;
    },

    update_index: function () {
        return this.set_page(1).update();
    },

    set_page: function(page) {
        this.options.set('page', page);
        return this;
    }

});

Dah.stock.OptionList = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({
            url: '',
            stock: -1,
            page: 1,
            widget_pk: -1
        });
        this.options.update(options);

        this.container = this.element.down('.optionlist');
        this.select = this.element.down('select[name=optiontype]');

        if (!Object.isUndefined(this.select))
            this.select.observe('change', this.update_type.bind(this));

        this.element.set_page = this.set_page.bind(this);
    },

    update: function () {
        if (!Object.isUndefined(this.select)) {
            new Ajax.Request(this.options.get('url'), {
                method: 'get',
                parameters: {
                    'type': this.select.getValue(), 
                    'stock': this.options.get('stock'),
                    'page': this.options.get('page'),
                    'widget_pk': this.options.get('widget_pk')
                },
                onSuccess: function (response) {
                    this.container.update(response.responseText);
                }.bind(this)
            });
        }
        return this;
    },

    update_type: function () {
        return this.set_page(1).update();
    },

    set_page: function(page) {
        this.options.set('page', page);
        return this;
    }
});

Dah.stock.WatchList = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({
            refresh: 0,
            url: ''
        });
        this.options.update(options);

        this.container = this.element.down('.watchlist');

        if (this.options.get('refresh') > 0)
            this.timer = setInterval(this.update.bind(this), this.options.get('refresh'))
        document.observe('widget:watchlist', this.update.bind(this));
    },

    update: function () {
        new Ajax.Request(this.options.get('url'), {
            method: 'get',
            onSuccess: function (response) {
                this.container.update(response.responseText);
            }.bind(this)
        });
    }
});

Dah.stock.watchlist_url = '/stock/watchlist/';
Dah.stock.watchlist = function (mode, id) {
    url = Dah.stock.watchlist_url + mode + '/?stock=' + id;
    if (mode == 'delete' && !confirm('Weet u zeker dat u dit aandeel uit uw watchlist wil verwijderen?'))
        return
    new Ajax.Request(url, {
        method: 'get',
        onSuccess: function (response) {
            document.fire('widget:message', {message: response.responseText, clear: true});
            document.fire('widget:watchlist');
        }
    });
}

Dah.base.BaseAlerts = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({
            url: '',
            errors: {
                notifications_missing: 'Please select a notification method.'
            }
        }).update(options);
        this.element.add_alert = this.add_alert.bind(this);
        this.element.remove_alert = this.remove_alert.bind(this);
        document.observe('widget:alerts', this.update.bind(this));
    },

    update: function () {
    },

    add_alert: function (type) {
        var p = this.element.down('.' + type);
        var notification_through_email = p.down('input[name=notification_through_email]');
        var notification_through_sms = p.down('input[name=notification_through_sms]');
        if (!(notification_through_email && notification_through_email.checked)
                && !(notification_through_sms && notification_through_sms.checked)) {
            alert(this.options.get('errors').notifications_missing);
            return false;
        }
        var parameters = {
            type: type,
            notification_through_email: notification_through_email.checked == false ? '' : 'on',
            notification_through_sms: notification_through_sms.checked == false ? '' : 'on'
        };
        if (this.add_alert_parameters)
            parameters = Object.extend(parameters, this.add_alert_parameters(type));
        url = this.options.get('url') + 'add/';
        new Ajax.Request(url, {
            method: 'post',
            parameters: parameters,
            onSuccess: function (response) {
                this.on_add_alert(response, type).bind(this);
            }.bind(this)
        });
        return true;
    },

    remove_alert: function(type, id) {
        var parameters = {type: type, subscription: id};
        if (this.remove_alert_parameters)
            parameters = Object.extend(parameters, this.remove_alert_parameters(type, id));
        url = this.options.get('url') + 'remove/';
        new Ajax.Request(url, {
            method: 'post',
            parameters: parameters,
            onSuccess: function (response) {
                this.on_remove_alert(response, type, id).bind(this);
            }.bind(this)
        });
        return true;
    },

    on_add_alert: function(response, type) {
        document.fire('widget:message', {message: response.responseText, clear: true});
        document.fire('widget:alerts');
    },

    on_remove_alert: function(response, type, id) {
        document.fire('widget:message', {message: response.responseText, clear: true});
        document.fire('widget:alerts');
    }
});

Dah.articles.DossierAlerts = Class.create(Dah.base.BaseAlerts, {
    add_alert_parameters: function (type) {
        var p = this.element.down('.' + type);
        return {
            type: p.down('select[name=type]').value
        }
    }
});

Dah.stockportfolio.StockAlerts = Class.create(Dah.base.BaseAlerts, {
    initialize: function ($super, element, options) {
        options = $H({widget_pk: -1}).update(options);
        $super(element, options);
        this.container = this.element.down('.stockalerts');
    },

    update: function () {
        new Ajax.Request(this.options.get('url'), {
            method: 'get',
            parameters: {
                'widget_pk': this.options.get('widget_pk')
            },
            onSuccess: function (response) {
                this.container.update(response.responseText);
            }.bind(this)
        });
    },

    add_alert_parameters: function(type) {
        var p = this.element.down('.' + type);
        var parameters = {}
        switch (type) {
        case 'bounds':
            parameters['lower_bound'] = p.down('input[name=lower_bound]').value.replace(/^\s*|\s*$/, '');
            parameters['upper_bound'] = p.down('input[name=upper_bound]').value.replace(/^\s*|\s*$/, '');
            if (parameters['lower_bound'] == '' && parameters['upper_bound'] == '') {
                alert(this.options.get('errors').bounds_missing);
                return false;
            }
            break;
        case 'periodic':
            var tmp = [];
            p.select('input[name=time_predef]').each(function(el) { if (el.checked) tmp.push(el.value); });
            if (p.down('input[name=time_custom]').value.match(/^\s*([0-1]?[0-9]|2[0-3])[:.][0-5][0-9]\s*$/))
                tmp.push(p.down('input[name=time_custom]').value.replace(/\./, ':').replace(/^\s*|\s*$/g, ''));
            if (tmp.length == 0) {
                alert(this.options.get('errors').times_missing);
                return false;
            }
            parameters['comma_delimited_times'] = tmp.join(',');
            break;
        }
        return parameters;
    },

    on_add_alert: function ($super, response, type) {
        var p = this.element.down('.' + type);
        switch (type) {
        case 'bounds':
            p.down('input[name=lower_bound]').value = '';
            p.down('input[name=upper_bound]').value = '';
            break;
        case 'periodic':
            p.select('input[name=time_predef]').each(function(el) { el.checked = false; });
            p.down('input[name=time_custom]').value = 'hh:mm';
            break;
        case 'news':
            break;
        }
        $super(response, type);
    }
});

Dah.stockportfolio.StockPortfolioAdd = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({
            url: ''
        });
        this.options.update(options);

        this.select = this.element.down('select[name=stock]');
        this.select.observe('change', this.on_change.bind(this));
        this.price = this.element.down('input[name=purchase_price]');
    },

    on_change: function () {
        var value = this.select.getValue();
        if (value == '') {
            this.price.value = '';
        } else {
            new Ajax.Request(this.options.get('url'), {
                method: 'get',
                parameters: {
                    'stock': value
                },
                onSuccess: function (response) {
                    this.price.value = response.responseText;
                }.bind(this),
                onFailure: function () {
                    this.price.value = '';
                }.bind(this)
            });
        }
    }
});

Dah.base.PaginateList = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({
            url: '',
            object_id: null,
            page: 1
        });
        this.options.update(options);

        this.container = this.element.down('.list');

        this.element.set_page = this.set_page.bind(this);
    },

    update: function () {
        new Ajax.Request(this.options.get('url'), {
            method: 'get',
            parameters: {
                'object_id': this.options.get('object_id'),
                'page': this.options.get('page')
            },
            onSuccess: function (response) {
                this.container.update(response.responseText);
            }.bind(this)
        });
        return this;
    },

    set_page: function(page) {
        this.options.set('page', page);
        return this;
    }
});

Dah.base.ArticleList = Class.create(Dah.base.PaginateList, {
    initialize: function ($super, element, options) {
        my_options = $H({refresh: 0});
        my_options.update(options);
        $super(element, my_options);

        this.container = this.element.down('.articlelist');

        if (this.options.get('refresh') > 0)
            this.timer = setInterval(this.update.bind(this), this.options.get('refresh'));
    },

    set_page: function($super, page) {
        $super(page);
        if (this.timer) {
            clearTimeout(this.timer);
            this.timer = setInterval(this.update.bind(this), this.options.get('refresh'));
        }
        return this;
    }
});

Dah.base.CommentList = Class.create(Dah.base.ArticleList, {
    initialize: function ($super, element, options) {
        $super(element, options);
        this.container = this.element.down('.commentlist');
    }
});

Dah.base.MessageList = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({});
        this.options.update(options);
        this.list = this.element.down('ul');
        if (!this.list) {
            this.list = new Element('ul');
            this.element.insert(this.list);
        }
        document.observe('widget:message', this.onMessage.bind(this));
    },

    onMessage: function (event) {
        if (event.memo.clear)
            this.clear();
        this.add(event.memo.message);
        window.location.href = '#site-alert';
    },

    add: function (message) {
        var li = new Element('li');
        li.update(message);
        this.list.insert(li);
        this.element.show();
        return this;
    },

    clear: function () {
        this.list.update();
        this.element.hide();
        return this;
    }
});

Dah.base.Menu = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({});
        this.options.update(options);
        this.list = this.element.down('.settings-menu');
        this.list.select('li').each(function (li) {
            if (li.down('ul')) {
                li.down('a').observe('click', this.fold_onclick.bind(this));
                if (!li.down('a').hasClassName('active')) {
                    li.down('ul').hide();
                    li.addClassName('fold');
                }
                else {
                    li.addClassName('unfold');
                }
            }
            if (li.down('a').hasClassName('active')) {
                this.unfold(li.down('a'));
            }
        }.bind(this));
    },

    fold_onclick: function (event) {
        var link = event.element();
        var li = link.up('li');
        var list = link.next('ul');
        list.toggle();
        if (list.visible()) {
            li.removeClassName('fold');
            li.addClassName('unfold');
        }
        else {
            li.removeClassName('unfold');
            li.addClassName('fold');
        }
        event.stop();
    },

    unfold: function (element) {
        while (element != this.element)
        {
            element.show();
            element = element.up();
        }
    }
});

Dah.base.Tabular = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({});
        this.options.update(options);
        this.element.down('.tab-menu').select('li').each(function (li) {
            var a = li.down('a');
            if (!a)
                return;
            var label = a.innerHTML;
            this.element.select('.tab-title').each(function (el) {
                if (label == el.innerHTML) {
                    var content = el.next('.tab-content');
                    a.observe('click', this.activate.bind(this, content));
                    if (label == this.options.get('defaulttab')) {
                        content.show();
                        a.up('li').addClassName('active');
                    }
                }
            }.bind(this));
        }.bind(this));
    },

    activate: function (tab, event) {
        var element = event.element();
        this.element.down('.tab-menu').select('li').invoke('removeClassName', 'active');
        this.element.select('.tab-content').invoke('hide');
        element.up('li').addClassName('active');
        tab.show();
    }
});

Dah.base.WidgetForm = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({});
        this.options.update(options);
        this.content_container = this.element.down('.widget_content');
        this.form_container = this.element.down('.widget_form');
        this.form_container.hide();
    },
    load_form: function (form) {
        this.form_container.update(form);
        this.form_container.down('input[name=cancel]').observe('click', this.hide.bind(this));
        this.form_container.down('input[name=save]').observe('click', this.save.bind(this));
    },
    hide: function () {
        new Effect.SlideUp(this.form_container);
    },
    reload: function () {
        new Ajax.Request(this.options.get('view_url'), {
            method: 'get',
            onSuccess: function (response) {
                this.content_container.update(response.responseText);
            }.bind(this)
        });
    },
    show: function () {
        if (this.form_container.visible())
            return;
        new Ajax.Request(this.options.get('edit_url'), {
            method: 'get',
            onSuccess: function (response) {
                this.load_form(response.responseText);
                new Effect.SlideDown(this.form_container);
            }.bind(this)
        });
    },
    save: function (event) {
        var form = event.element().up('form');
        new Ajax.Request(this.options.get('edit_url'), {
            method: 'post',
            parameters: form.serialize(),
            onSuccess: function (response) {
                if (response.responseText == 'OK') {
                    this.hide();
                    this.reload();
                } else {
                    this.load_form(response.responseText);
                }
            }.bind(this)
        });
        return false;
    }
});

Dah.forms.PasswordField = Class.create({
    initialize: function (element, options) {
        this.element = $(element);
        this.options = $H({
            lower: 1,
            upper: 1,
            numeric: 1,
            aplha: 2,
            special: 0,
            length: [8, Infinity],
            custom: [],
            bad_words: [],
            no_sequential: true,
            bad_sequence_length: 4,
            allow_submit: true
        });
        this.options.update(options);

        this.element.observe('keyup', this.keyup.bind(this));
        this.element.form.observe('submit', this.submit.bind(this));
        this.rules = {
            lower: /[a-z]/g,
            upper: /[A-Z]/g,
            aplha: /[a-z]/gi,
            numeric: /[0-9]/g,
            special: /[\W_]/g
        }
    },

    validate: function (pw) {
        if (pw.length < this.options.get('length')[0] || pw.length > this.options.get('length')[1])
            return false;
        for (var rule in this.rules) {
            if ((pw.match(this.rules[rule]) || []).length < this.options.get(rule))
                return false;
        }
        if (this.options.get('no_sequential') && /(.)\1\1\1/.test(pw))
            return false;
        return true;
    },

    get_errorlist: function () {
        var ul = this.element.previous('ul.errorlist');
        if (!ul) {
            ul = new Element('ul', {className: 'errorlist'});
            this.element.up().insert({top: ul});
        }
        return ul;
    },

    keyup: function (event) {
        var ul = this.get_errorlist().update();
        if (!this.validate(this.element.value)) {
            var li = new Element('li');
            li.update('Dit wachtwoord is zwak, probeer een combinatie van cijfers, letters en hoofdletters');
            ul.insert(li);
        }
    },

    submit: function (event) {
        if (!this.validate(this.element.value) && !this.options.get('allow_submit'))
            event.stop();
    }
});

