/*gets all tags from the url*/
function getTags(tag, url, params, callback) {
    $.ajax({
        type:"GET",
        url: url,
        dataType:"json",
        success: function(response) {
            var tags = new Array();
            var count = 0;
            for (var r in response.result) {
                if ((typeof response.result[r]) == 'function') {
                    continue;
                }
                var temp_tags = response.result[r][tag].split(',');
                count++;
                for (var i = 0; i < temp_tags.length; ++i) {
                    if (tags[temp_tags[i]] == null && temp_tags[i] != '') {
                        tags.length++;
                        tags[temp_tags[i]] = 1;
                    } else {
                        tags[temp_tags[i]]++;
                    }
                }

            }
            callback(tags, count);
        }
    });
}
function checkredirect(object) {
    window.location = $(object).attr('value');
}
/* gets all tags sorted by the amount that were found
 * tag: the tag that will be used
 * metaHandler: the metaHandler that will be returned through the callback
 * returns an Array with ValueNumberPair
 * */
function getSortedTags(tag, currentNumber, searchHelper, callback) {
    getTags(tag, searchHelper.getGsaUrl(null, null, tag, 50, false), new Array(callback), function(tags, total) {
        var sortedTags = new Array();

        for (var tag in tags) {
            if (tag != '') {
                var valuePair = new ValueNumberPair(tag, Math.round((tags[tag] / total) * currentNumber));
                sortedTags.push(valuePair);
            }
        }

        sortedTags.sort(sortValueIntPairDesc);
        callback(searchHelper, sortedTags);
    });
}
/*gets the value of a single tag */
function getTagValue(url, callback) {
    $.ajax({
        url: url,
        dataType:"json",
        success: function(response) {
            var value = response.num;
            if (value == null || value == '')
                value = 0;
            callback(value);
        }
    });
}
function getGrades(searchHelper, start, tags, callback) {
    getTagValue(searchHelper.getGsaUrl('betyg', start, 'betyg', 1, false),
            function(value) {
                if (value != 0) {
                    var pair = new ValueNumberPair(start, value);
                    tags.push(pair);
                }
                if (start <= 1) {
                    tags.sort(sortStringIntPairDesc);
                    callback(searchHelper, tags);
                } else {
                    getGrades(searchHelper, start - 1, tags, callback);
                }
            });
}
function gradeToString(grade) {
    return '<img height="16" src="/template/ver2-0/gfx/' + SDS_namespace + '/' + grade + 'star.gif" style="padding:0;margin:0;" alt="' + grade + '" />';
}
function subCategoryToString(string) {
    return '&nbsp;-' + string;
}
function monthToString(month) {
    return subCategoryToString(Date.getMonthName(month));
}
function getYears(searchHelper, fromYear, toYear, tags, callback) {
    getTagValue(searchHelper.getGsaUrl('year', fromYear, null, 1, false),
            function(value) {
                if (value != 0) {
                    var pair = new ValueNumberPair(fromYear, value);
                    tags.push(pair);
                }
                if (tags.length < 6 && (value > 0 || fromYear > toYear) && fromYear > 2005) {
                    getYears(searchHelper, fromYear - 1, toYear, tags, callback);
                } else {
                    callback(tags, searchHelper);
                }
            });
}
function getMonths(searchHelper, year, month, tags, callback) {
    getTagValue(searchHelper.getGsaUrl('month', month, null, 1, false),
            function(value) {
                if (value != 0) {
                    var pair = new ValueNumberPair(month, value);
                    tags.push(pair);
                }
                if (month < 12) {
                    getMonths(searchHelper, year, month + 1, tags, callback);
                } else {
                    callback(tags, searchHelper);
                }
            });
}
function getDates(searchHelper, callback) {
    getAllDates(searchHelper, function(dates) {
        callback(searchHelper, dates);
    });
}
function getAllDates(searchHelper, callback) {
    $.ajax({
        type:"GET",
        url: searchHelper.getGsaUrl(null, null, null, 50, true),
        dataType:"json",
        success: function(response) {
            var tags = new Array();
            for (var r in response.result) {
                if ((typeof response.result[r]) == 'function') {
                    continue;
                }
                var value = response.result[r]["date"];
                if (value != '' && tags[value] == null) {
                    tags[value] = new ValueNumberPair(value, 1);
                    tags.length++;
                } else if (value != '') {
                    tags[value].number++;
                }
            }
            var dates = new Array();
            for (var date in tags) {
                dates.push(tags[date]);
            }
            dates.sort(sortStringIntPairDesc);
            callback(dates);
        }
    });
}
function getAllDateValues(searchHelper, fromDay, toDay, tags, callback) {
    var date = searchHelper.dateRange['year'] + '-' + searchHelper.dateRange['month'] + '-' + fromDay;
    getTagValue(searchHelper.getGsaUrl('date', date, null, 1, false),
            function(value) {
                if (value != 0) {
                    var pair = new ValueNumberPair(date, value);
                    tags.push(pair);
                }
                if (fromDay < toDay) {
                    getAllDateValues(searchHelper, fromDay + 1, toDay, tags, callback);
                } else {
                    callback(searchHelper, tags);
                }
            });
}
/* Metahandler fills all metaboxes with data
 * gsaUrl: the url that delivers the gsaresults
 * tags: an array with all tags that is to be used(artType,tags)*/
function MetaHandler(gsaUrl, currentNumber) {
    this.searchHelper = new SearchHelper(gsaUrl);

    printTag(this.searchHelper, 'tags', currentNumber, '', '');
    printTag(this.searchHelper, 'artType', currentNumber, '', '');
    printTag(this.searchHelper, 'saploTags', currentNumber, '', '');

    if (this.searchHelper.params['artType'].toLowerCase() == 'recension') {
        if (this.searchHelper.params['recType'].toLowerCase() != 'bok') {
            if (this.searchHelper.params['betyg'] == '') {
                getGrades(this.searchHelper, 5, new Array(), function(searchHelper, sortedTags) {
                    if (sortedTags.length > 0)
                        printTags(searchHelper, sortedTags, 5, 20, 'betyg', '#metabox_betyg', gradeToString);
                });
            } else {
                printSingleTag(this.searchHelper.searchHelper.getUrl('betyg', ''), this.searchHelper.params['betyg'], currentNumber, '#metabox_betyg');
            }
        }
        printTag(this.searchHelper, 'genre', currentNumber, '', '');
        printTag(this.searchHelper, 'recType', currentNumber, '', subCategoryToString);
        printTag(this.searchHelper, 'artist', currentNumber, '', '');
        printTag(this.searchHelper, 'recordLabel', currentNumber, '', '');
        printTag(this.searchHelper, 'actors', currentNumber, '', '');
        printTag(this.searchHelper, 'regi', currentNumber, '', '');
    }

    /*daterange search will not work without a query*/
    if (this.searchHelper.query != '') {
        if (this.searchHelper.dateRange['date'] == '') {
            var date = new Date();
            if (this.searchHelper.dateRange['month'] == '') {
                getDates(this.searchHelper, function(searchHelper, dates) {
                    if (dates.length > 0)
                        printTags(searchHelper, dates, 6, 20, 'date', '#metabox_dates', dateToString);
                });
            } else {
                date = new Date(this.searchHelper.dateRange['month'] + "/01/" + this.searchHelper.dateRange['year']);
                getAllDateValues(this.searchHelper, 1, date.getDaysInMonth(), new Array(), function(searchHelper, dates) {
                    if (dates.length > 0)
                        printTags(searchHelper, dates, 6, 31, 'date', '#metabox_dates', dateToString);
                });
            }

            if (this.searchHelper.dateRange['year'] == '') {
                getYears(this.searchHelper, date.getFullYear(), 2006, new Array(), function(years, searchHelper) {
                    if (years.length > 0)
                        printTags(searchHelper, years, 6, 20, 'year', '#metabox_years', '');
                });

            } else {
                printSingleTag(this.searchHelper.getUrl('year', ""), this.searchHelper.dateRange['year'], currentNumber, '#metabox_years');
                if (this.searchHelper.dateRange['month'] == '') {
                    getMonths(this.searchHelper, this.searchHelper.dateRange['year'], 1, new Array(), function(months, searchHelper) {
                        if (months.length > 0)
                            printTags(searchHelper, months, 12, 12, 'month', '#metabox_months', monthToString);

                    });
                } else {
                    printSingleTag(this.searchHelper.getUrl('month', ''), Date.monthNames[this.searchHelper.dateRange['month'] - 1], currentNumber, '#metabox_months');
                }
            }
        } else {
            printSingleTag(this.searchHelper.getUrl('date', ''), dateToString(this.searchHelper.dateRange['date']), currentNumber, '#metabox_dates');
        }
    }
}
function printTag(searchHelper, tag, currentNumber, alternativeGetFunction, alternativeFunction) {
    var getFunction = alternativeGetFunction == '' ? getSortedTags : alternativeGetFunction;

    if (searchHelper.params[tag] == '') {
        getFunction(tag, currentNumber, searchHelper, function(searchHelper, sortedTags) {
            if (sortedTags.length > 0)
                printTags(searchHelper, sortedTags, 5, 20, tag, '#metabox_' + tag, alternativeFunction);
        });
    } else {
        printSingleTag(searchHelper.getUrl(tag, ''), searchHelper.params[tag], currentNumber, '#metabox_' + tag);
    }
}
/*
 Prints a series of tags. If the max amount is reached then all tags above that amount will be hidden
 */
function printTags(searchHelper, tags, visible, max, tag, resultBox, alternativeFunction) {
    var style = '';
    var html = '';
    if ($(resultBox + '_container').length > 0)
        $(resultBox + '_container').attr('style', ' ');
    html = '<table class="search_puff_table">';
    if ($(resultBox + '_container').length > 0) {
        html += '<tr><td colspan="2" class="top">&nbsp;</td></tr>';
    }
    for (var i = 0; i < tags.length && i < max; ++i) {
        if (i == visible)
            style = 'style="display:none"';
        var value = alternativeFunction == '' ? tags[i].value : alternativeFunction(tags[i].value);
        var url = searchHelper.getUrl(tag, tags[i].value);
        html += '<tr ' + style + '><td><a href="' + url + '">' + value + '</a></td>'
                + '<td align="right">' + (tags[i].number > 0 ? tags[i].number : '') + '</td></tr>' + '<tr ' + style + '><td class="divider" colspan="2"> <hr /></td></tr>';
    }
    if (tags.length > visible) {
        html += '<tr><td>&nbsp;</td><td align="right"><a href="#none" id="show' + tag + '">Fler &raquo;</a></td></tr>';
    }
    html += '</table>';
    $(resultBox).html(html);
    if (tags.length > visible) {
        $("#show" + tag).click(function(event) {
            $(resultBox + ' table tr').attr("style", ' ');
            $(event.target).hide();
        });
    }
}
/*
 Prints a selected tag and a link to remove the selected tag
 */
function printSingleTag(url, tag, value, resultBox) {
    $(resultBox + '_container').attr('style', ' ');
    var html = '<table class="search_puff_table">';
    html += '<tr><td><a href="' + url + '">&laquo; Fler</a></td><td align="right"></td></tr>';
    html += '<tr><td class="divider" colspan="2"> <hr /></td></tr>';
    html += '<tr><td><strong>' + decodeURIComponent(tag.replace(/\+/g, ' ')) + '</strong></td><td align="right"><strong>' + value.replace(/\+/g, ' ') + '</strong></td></tr>';
    html += '<tr><td class="divider" colspan="2"> <hr /></td></tr>';
    html += '</table>';
    $(resultBox).html(html);
}
/*
 The SearchHelper keeps track of the data used to build metaboxes
 */
function SearchHelper(gsaUrl) {
    this.params = new Array();
    this.query = encodeURIComponent(sds.global.getParam('q'));

    this.params['tags'] = sds.global.getParam('tags');
    this.params['artType'] = sds.global.getParam('artType');
    this.params['saploTags'] = sds.global.getParam('saploTags');
    this.params['betyg'] = '';
    this.params['recType'] = '';
    this.params['genre'] = '';
    this.params['artist'] = '';
    this.params['regi'] = '';
    this.params['actors'] = '';
    this.params['recordLabel'] = '';
    this.params['writer'] = sds.global.getParam('writer');

    if (this.params['artType'].toLowerCase() == 'recension') {
        this.params['betyg'] = sds.global.getParam('betyg');
        this.params['recType'] = sds.global.getParam('recType');
        this.params['genre'] = sds.global.getParam('genre');
        this.params['artist'] = sds.global.getParam('artist');
        this.params['regi'] = sds.global.getParam('regi');
        this.params['actors'] = sds.global.getParam('actors');
        this.params['recordLabel'] = sds.global.getParam('recordLabel');
    }
    this.dateRange = new Array();
    this.dateRange['date'] = '';
    this.dateRange['year'] = '';
    this.dateRange['month'] = '';
    if (this.query != '') {
        this.dateRange['date'] = sds.global.getParam('date');
        this.dateRange['year'] = sds.global.getParam('year');
        if (this.dateRange['year'] != '') {
            this.dateRange['month'] = sds.global.getParam('month');
        }
    }
    this.sort = sds.global.getParam('sort');
    if (this.sort == '') {
        this.sort = 'date';
    }

    this.gsa = gsaUrl;
    var regex = new RegExp('^([^?#]*)');
    this.baseUrl = regex.exec(window.location.href)[0];

    this.frontend = 'json_frontend';
    this.collection = 'default_' + SDS_namespace + '_collection2';

    return this;
}
/*generates and returns the metadata for gsa-urls or regular ones
 * */
SearchHelper.prototype.getGsaMeta = function(forcedTag) {
    var meta = '';
    this.params['writer'] = this.params['writer'].replace('.', '%252E');

    if (forcedTag != null)
        meta += forcedTag + '.';
    for (var param in this.params) {

        if (this.params[param] == '' || (typeof this.params[param]) == 'function') {
            continue;
        }
        var tmp = this.params[param];
        if (isNaN(tmp)) {
            this.params[param] = this.params[param].replace(/\./g, '');
            this.params[param] = this.params[param].replace('&', '.' + param + ':');
        }
        meta += param + ':' + encodeURIComponent(this.params[param]) + '.';
        this.params[param] = tmp;
    }

    this.params['writer'] = this.params['writer'].replace('%252E', '.');
    return '&partialfields=' + meta.substr(0, meta.length - 1);
};
SearchHelper.prototype.getRegularMeta = function() {
    var meta = '';
    for (var param in this.params) {
        if (this.params[param] == '')
            continue;
        meta += '&amp;' + param + '=' + encodeURIComponent(this.params[param]);
    }
    for (param in this.dateRange) {
        if (this.dateRange[param] == '')
            continue;
        meta += '&amp;' + param + '=' + this.dateRange[param];
    }
    return meta;
};
/*gets the date for a gsa url*/
SearchHelper.prototype.getGsaDate = function() {

    if (this.dateRange['date'] != '') {
        return '&as_q=daterange:' + this.dateRange['date'] + '..' + this.dateRange['date'];
    } else if (this.dateRange['month'] != '') {
        var date = new Date(this.dateRange['month'] + "/01/" + this.dateRange['year']);
        return '&as_q=daterange:' + this.dateRange['year'] + '-' + this.dateRange['month'] + '-01..' + this.dateRange['year'] + '-' + this.dateRange['month'] + '-' + date.getDaysInMonth();
    } else if (this.dateRange['year'] != '') {
        return '&as_q=daterange:' + this.dateRange['year'] + '-01-01..' + this.dateRange['year'] + '-12-31';
    }
    return '';
};
/*builds the url to a gsa resultpage
 * tag: the tag that is used
 * value: the value of the tag
 * max: the maximum number of results
 * bydate: set to true if the result should be sorted by date and false for relevance*/
SearchHelper.prototype.getGsaUrl = function(tag, value, forcedTag, max, byDate) {
    var meta = '';
    var date = '';
    var sort = '';
    if (tag != null) {
        var tmp = this.params[tag];
        if (tmp != null)
            this.params[tag] = value;
        meta = this.getGsaMeta(forcedTag);
        if (tmp != null)
            this.params[tag] = tmp;


        tmp = this.dateRange[tag];
        if (tmp != null)
            this.dateRange[tag] = value;
        date = this.getGsaDate();
        if (tmp != null)
            this.dateRange[tag] = tmp;

    } else {
        meta = this.getGsaMeta(forcedTag);
        date = this.getGsaDate();
    }
    if (byDate) {
        sort = '&sort=date:D:S:d1';
    }
    return this.gsa + "?q=" + this.query + '' + date + '' + meta
            + "&proxystylesheet=" + this.frontend + "&client=" + this.frontend + "&site=" + this.collection + "&num=" + max + '' + sort +
           "&oe=UTF8&ie=UTF8&output=xml_no_dtd&getfields=" + forcedTag;

};
/*
 Gets an url to the current site, the sent tag will be used
 */
SearchHelper.prototype.getUrl = function(tag, value) {
    var meta = '';
    if (tag != null) {
        var tmp = this.params[tag];
        var tmpDate = this.dateRange[tag];
        if (tmp != null)
            this.params[tag] = value;
        if (tmpDate != null)
            this.dateRange[tag] = value;


        meta = this.getRegularMeta();

        if (tmp != null)
            this.params[tag] = tmp;
        if (tmpDate != null)
            this.dateRange[tag] = tmpDate;
    } else {
        meta = this.getRegularMeta();
    }

    return (this.baseUrl + '?q=' + this.query + meta + '&amp;sort=' + this.sort).replace(/"/g, '%22');

};
/*
 A valuepair where the last one need to be a number to make the pair sortable
 */
function ValueNumberPair(value, number) {
    this.value = value;
    this.number = number;
    return this;
}
/*
 Used for sorting arrays with ValueIntPairs
 */
function sortValueIntPairDesc(a, b) {
    return b.number - a.number;
}
function sortStringIntPairDesc(a, b) {
    return b.value > a.value;
}
function dateToString(date) {
    date = date.split('-');
    var d = new Date();
    d.setFullYear(date[0], date[1] - 1, date[2]);
    return d.toLocaleDateString();
}
