HEARST.app = HEARST.app || {};

HEARST.app.indeed = {
    getJobs: function() {

        var TMPL = {
                pagination: '\
                    <div class="pagination">\n\
                        <div class="previous">\n\
                            <a class="angle_quote">&laquo;</a>\n\
                            <a class="button"><span>Back</span></a>\n\
                        </div>\n\
                        <div class="pages short">\n\
                            <span class="current">{{ page_current }}</span> of <a class="last">{{ page_last }}</a>\n\
                        </div>\n\
                        <div class="pages long">{{ page_offset }}</div>\n\
                        <div class="next">\n\
                            <a class="button"><span>Next</span></a>\n\
                            <a class="angle_quote">&raquo;</a>\n\
                        </div>\n\
                        </a>\n\
                    </div>\n',
    
                result: '\
                    <li class="result">\n\
                        <h5><a href="{{ url }}" onmousedown="{{ onmousedown }}" target="_blank">{{ jobtitle }}</a></h5>\n\
                        <h6>{{ company }} &ndash; {{ city }}, {{ state }}</h6>\n\
                        <p>{{ snippet }}</p>\n\
                        <span class="source">From {{ source }}</span>\n\
                        <span class="date">{{ date }}</span>\n\
                        <br />\n\
                    </li>\n',
    
                jobs: '\
                    <div class="short">{{ pagination }}</div>\n\
                    <h4>{{ query }} jobs {{ location }}</h4>\n\
                    <div class="count">results {{ start }} - {{ end }} jobs found: {{ totalresults }}</div>\n\
                    <ul class="results">{{ results }}</ul>\n\
                    <div class="long">{{ pagination }}</div>\n'
            },
        HTML = {},
        $form = $('#job_search_form');

        function listJobs(xml) {
            var $xml = $(xml),
                response = {
                    query: $xml.find('query').text() || 'no query',
                    location: $xml.find('location').text() && 'near ' + $xml.find('location').text(),
                    totalresults: $xml.find('totalresults').text(),
                    start: $xml.find('start').text(),
                    end: $xml.find('end').text(),
                    results: []
                },
                page = {},
                i, j, k;
                
            function offsetDate(str) {
                var then = new Date(str),
                    now = new Date(),
                    offset = (now - then),
                    maxOffset = 6.048e8, // maxOffset is a week in milliseconds
                    date = [],
                    display = '',
                    denom = [
                        {name: 'second', value: 1000},
                        {name: 'minute', value: 60},
                        {name: 'hour', value: 60},
                        {name: 'day', value: 24}
                    ],
                    i, int;
                    
                function s(n) {
                    return (n !== 1 && 's') || '';
                }

                if (offset > maxOffset) {
                    return then.toLocaleDateString();
                }

                for (i=0; i<denom.length; i++) {
                    offset /= denom[i].value;
                    maxOffset *= denom[i].value;
                }

                for (--i; i>-1; i--) {
                    int = parseInt(offset);
                    if (int > 0) {
                        date.push(int + ' ' + denom[i].name + s(int));
                    }
                    if (date.length > 1) {
                        break;
                    }
                    offset = (offset - int) * denom[i].value;
                }

                return date.join(' and ');
            }
            
            function offsetPages() {
                var pages = [],
                    offset = 2,
                    length = offset * 2 + 1,
                    i, j, thisPage;

                function markup(n) {
                    var tag = (n === page.current) ? 'span' : 'a' ;
                    return ['<',tag,'>',n,'</',tag,'>'].join('');
                }

                for (i=0, j=0; i<length; i++) {
                    thisPage = i + page.current - offset;
                    if (thisPage > 0) {
                        if (thisPage <= page.last) {
                            pages[j] = thisPage;
                            j++;
                        } else if (pages[0] > 1) {
                            pages.unshift(pages[0] - 1);
                        }
                    } else {
                        length++;
                    }
                }

                return $.map(pages, markup).join('');
            }

            page.limit = response.end - response.start + 1;
            page.current = Math.ceil(response.start / page.limit);
            page.first = 1;
            page.last = Math.ceil(response.totalresults / page.limit);

            $xml.find('result').each(function(i) {
                response.results[i] = {};
                $(this).find('*').each(function(j) {
                    var property = this.nodeName.toLowerCase();
                    response.results[i][property] = (property === 'date') ? offsetDate($(this).text()) : $(this).text() ;
                });
            });

            HTML.results = '';
            for (k=0; k<response.results.length; k++) {
                HTML.results += TMPL.result.templateReplace(response.results[k]);
            }

            HTML.pagination = TMPL.pagination.templateReplace({
                page_current: page.current,
                page_last: page.last,
                page_offset: offsetPages()
            });

            // Convert to jQuery object
            HTML.pagination = $(HTML.pagination);

            // Remove paging buttons if current page is at a page boundary
            if (page.current == 1) {
                HTML.pagination.find('.previous').remove();
            }

            if (page.current == page.last) {
                HTML.pagination.find('.next').remove();
            }
            
            // Convert back to plain text
            HTML.pagination = HTML.pagination.parent().html();

            HTML.jobs = TMPL.jobs.templateReplace(response, HTML);

            HTML = (response.results.length)
                ? HTML.jobs
                : 'Sorry, no ' + response.query + ' jobs could be found ' + response.location;
            
            // Attach events
            $('#job_search_results')
                .html(HTML)
                .find('.pagination .previous')
                    .bind(
                        'click.indeed',
                        function() {
                            $form[0].start.value = Number($form[0].start.value) - Number($form[0].limit.value);
                            HEARST.app.indeed.getJobs();
                        }
                    )
                    .end()
                .find('.pagination .next')
                    .bind(
                        'click.indeed',
                        function() {
                            $form[0].start.value = Number($form[0].start.value) + Number($form[0].limit.value);
                            HEARST.app.indeed.getJobs();
                        }
                    )
                    .end()
                .find('.pages a')
                    .bind(
                        'click.indeed',
                        function() {
                            $form[0].start.value = Number($form[0].limit.value) * Number($(this).text()) - 1;
                            HEARST.app.indeed.getJobs();
                        }
                    );
        }
// update dataType to text instead of xml to fix mac FF2 parse error
        $.ajax({
            type: 'GET',
            url: $form[0].action,
                    dataType: (jQuery.browser.mozilla && (parseFloat(jQuery.browser.version) < 1.9)) ? 'text': 'xml',
            data: $form.serialize(),
            success: listJobs
        });
    }
};

$('#job_search_form')
    .submit(
        function() {
            var error = false,
                $button = $(this).find('button, .button input'),
                disable = function(elem) {
                    elem.disabled = true;
                },
                enable = function(elem) {
                    elem.disbaled = false;
                };
                
            disable($button);
    
            $(this)
                .find('.required')
                .each(function(i){
                    var thisField = document.getElementById(this.htmlFor);
                    if (thisField.value === '') {
                        // I think there's an error with jQuery's .add() or .addClass() method.
                        // It seems we have to make an excepation for select elements.
                        if ($(thisField).is('select')) {
                            $(this).addClass('error');
                            $(thisField).addClass('error');
                        } else {
                            $(this).add(thisField).addClass('error');
                        }
                        error = true;
                    }
                });
    
            if (error) {
                enable($button);
                alert('You forgot one or more required fields');
            } else {
                HEARST.app.indeed.getJobs();
                enable($button);
            }
            
            return false;
        }
    )
    .find('input, select, textarea')
        .blur(function() {
            var $thisLabel = $('label[for=' + this.id + ']'),
                $pair = $(this).add($thisLabel);
    
            if (this.value !== '' && $(this).hasClass('error')) {
                $pair.removeClass('error');
            };
        })
        .end()
        
    .find('[name=useragent]')
        .val(navigator.userAgent)
        .end()
        
    .find(':submit')
        .bind(
            'mousedown.indeed',
            function() {
                this.form.start.value = 0;
                this.form.limit.value = 10;
            }
        );


// Check to see if job search parameters are passed in URL
(function() {
    var what = HEARST.utils.getQueryVariable('job_what'),
        where = HEARST.utils.getQueryVariable('job_where'),
        $form = $('#job_search_form');

    $form.find('[name=q]').val(what);
    $form.find('[name=l]').val(where);

    if (what) {
        $form.submit();
    }
})();