﻿/// <reference path="jquery-1.4.1.min.js" />
/// <reference path="json2.js" />
/// <reference path="jquery.address-1.2rc.js" />


var findus = (function() {
    function init() {
        loadFlashes();

        if (findus.Page)
            findus.Page.Init();

        if (findus.Search)
            findus.Search.Init();

        if (findus.Cloud)
            findus.Cloud.Init();

        // Search for all inputs with switchable text
        findus.inputSwitch();

//        $('#openNewsletter').click(function(event) {
//            $('#newsletterContainer').load('http://su.pbl.nu/s/87/2/', function() {
//                //$('#newsletterContainer').html = $('#newsletterContainer').html().find('body').html();
//                //$('#newsletterContainer').html = $('#newsletterContainer').html().find('body').html();
//                $('#newsletterContainer').css('display', 'block');
//            });

//        });

    }

    function loadFlashes() {
        // Checking if we have additional content to show
        var so = null;
        if ($('#mostVisited').length > 0) {
            so = new SWFObject("/images/flash/most_visited.swf", "mymovie", "230", "345", "9", "#FFFFFF", false);
            so.addParam("wmode", "opaque");
            so.write("mostVisited");
        }
        if ($('#productNews').length > 0) {
            so = new SWFObject("/images/flash/product_news.swf", "mymovie", "230", "280", "9", "#FFFFFF", false);
            so.addParam("wmode", "opaque");
            so.write("productNews");
        }
        if ($('#askFindus').length > 0) {
            so = new SWFObject("/images/flash/ask_findus.swf", "mymovie", "230", "350", "9", "#FFFFFF", false);
            so.addParam("wmode", "opaque");
            so.write("askFindus");
        }
        if ($('#productNews').length > 0) {
            so = new SWFObject("/images/flash/product_news.swf", "mymovie", "230", "280", "9", "#FFFFFF", false);
            so.addParam("wmode", "opaque");
            so.write("productNews");
        }
        if ($('#campaigns').length > 0) {
            so = new SWFObject("/images/flash/campaigns.swf", "mymovie", "230", "370", "9", "#FFFFFF", false);
            so.addParam("wmode", "opaque");
            so.write("campaigns");
        }
        if ($('#findusTips').length > 0) {
            so = new SWFObject("/images/flash/findus_tips.swf", "mymovie", "230", "475", "9", "#FFFFFF", false);
            so.addParam("wmode", "opaque");
            so.write("findusTips");
        }
        //        if ($('#flashNewsletter').length > 0) {
        //            so = new SWFObject("/images/flash/newsletter_apply.swf", "mymovie", "206", "80", "9", "#FFFFFF", false);
        //            so.addParam("wmode", "opaque");
        //            so.write("flashNewsletter");
        //        }                

    }

    return {
        Init: function() {
            init();
            return this;
        },
        sendRequest: function(options) {
            /// <summary>
            /// Sends a Ajax request
            /// </summary>
            /// <param name="options">Options for sending ajaxrequests
            /// {
            ///    url: '',
            //      data: '',
            //      succes: function() {
            //
            //      },
            //      error: function() {
            //
            //      }
            //  };
            ///</param>

            var success = function(msg) {
                var response = JSON.parse(msg.d);
                options.success(response);
            };

            $.ajax({
                async: true,
                type: "POST",
                url: options.url,
                contentType: "application/json; charset=utf-8",
                dataType: "json",
                data: JSON.stringify(options.data),
                success: success,
                error: options.error
            });
        },
        inputSwitch: function() {
            $('.txtswitch').click(function(event) {
                var $sender = $(event.target);
                // Checking so we found the sender
                if ($sender.length > 0) {
                    // Checking if we removed the original text
                    if (!$sender.data('orig')) {
                        $sender.data('orig', $sender.val());
                        $sender.val('');
                    }
                }
            });
            $('.txtswitch').blur(function(event) {
                var $sender = $(event.target);
                // Checking so we found the sender
                if ($sender.length > 0) {
                    // Checking if the value is empty
                    if (!$sender.val()
                        && $sender.data('orig')) {
                        $sender.val($sender.data('orig'));
                        $sender.data('orig', null);
                    }
                }
            });
        }
    };
} ());

/*
    Functions for the pages
*/
findus.Page = (function() {
    var pageId = null;

    function init() {
        // Setting the share by email onclick
        $('#shareEmail').attr('href', '#');
        $('#shareEmail').attr('onclick', 'return false;');
        $('#shareEmail').click(function(event) {           
            var so = null;
            if ($('#shareEmail_Open').length > 0) {
                so = new SWFObject("/images/flash/tips.swf", "mymovie", "193", "115", "9", "#FFFFFF", false);
                so.addParam("wmode", "opaque");
                so.addVariable("heading", $('#shareEmail').find('#shareEmail_heading:first').html());
                so.addVariable("url", $('#shareEmail').find('#shareEmail_url:first').html());
                so.write("shareEmail_Open");
            }
            $('#shareEmail_Open').slideDown('fast');
        });

        // Setting up the Like buttons        
        $('a.pageLike').attr('href', '#');
        $('a.pageLike').attr('onclick', 'return false;');
        $('a.pageLike').click(function(event) {
            if (pgid)
                pageId = pgid;
            var sender = event.target;
            if (sender)
                findus.Page.AddLike(pageId, $(sender).parents('a'));
            return false;
        });
    };

    function addLike(id, sender) {
        var callback = function(response) {
            var $sender = $(sender);
            if (response.Success) {
                $sender.find('span:first').html(response.Data);
                $sender.unbind('click');
                $sender.css('cursor', 'default');
                $sender.click(function() { return false; });
            }
        };

        var error = function(error) {

        };

        var options = {
            url: '/ws/pages.asmx/AddLike',
            data: { id: id },
            success: callback,
            error: error
        };

        findus.sendRequest(options);
    };

    return {
        Init: function() {
            init();
            return this;
        },
        AddLike: function(id, sender) {
            addLike(id, sender);
            return this;
        }
    };
} ());

/* Functions for Search */
findus.Search = (function() {
    var $searchArea = null;
    var searchItem = {
        id: 0,
        origId: 0,
        text: '',
        searchInArticles: true,
        searchInProducts: true,
        searchInRecipes: true,
        searchInPassionForFood: false,
        searchResult: [],
        sortOrder: 1,
        maxItems: 0,
        excludeSubCategories: []
    };
    var viewType = 'grid';
    var pageItems = 20;
    var currentPage = 0;
    var lastAddedItems = 0;

    var types = [];
    types[1] = {
        img: '/images/13x13_artikel.png',
        name: 'Artikel'
    };
    types[2] = {
        img: '/images/13x13_produkt.png',
        name: 'Produkt'
    };
    types[3] = {
        img: '/images/13x13_recept.png',
        name: 'Recept'
    };
    types[7] = {
        img: '/images/13x13_microartikel.png',
        name: 'MikroArtikel'
    };

    // Setting up javaenabled search
    function init() {
        //        $.address.init(function(event) {
        //            $.address.autoUpdate(true);
        //        });

        $searchArea = $('#searchArea');
        if ($searchArea.length) {
            // We know we have a searchArea on the page. Now going to define all buttons
            $searchArea.find('#searchProducts'
                           + ',#searchRecipes'
                           + ',#searchArticles'
                           + ',#viewList'
                           + ',#viewGrid'
                           + ',#viewSummit'
                           + ',#sortOptions'
                           + ',#itemsPerPage'
                           + ',#searchPaging a'
                           + ',.btnSubCat')
                           .attr('href', '#')
                           .live('click', function(event) {
                               var itemId = '';
                               if (this.tagName.toLowerCase() == 'a') {
                                   itemId = $(this).attr('id');
                               }
                               else if ($(this).hasClass('btnSubCat')) {
                                   //itemId = $(event.srcElement.parentNode.outerHTML).attr('id');
                                   itemId = 'btnSubCat';
                               }

                               // Determining the type of event, and fires it
                               switch (itemId) {
                                   case 'viewList':
                                       switchView('list');
                                       break;
                                   case 'viewGrid':
                                       switchView('grid');
                                       break;
                                   case 'viewSummit':
                                       switchView('summit');
                                       break;
                                   case 'sortOptions':
                                       var order = 1;
                                       if ($(this).find('img').attr('src').indexOf('senaste') > 0)
                                           order = 2;
                                       toggleSorting(order);
                                       break;
                                   case 'itemsPerPage':
                                       togglePageItems();
                                       break;
                                   case 'searchProducts':
                                       toggleResultType('products');
                                       break;
                                   case 'searchRecipes':
                                       toggleResultType('recipes');
                                       break;
                                   case 'searchArticles':
                                       toggleResultType('articles');
                                       break;
                                   case 'pagingPrev':
                                   case 'pagingNext':
                                       switchPage(itemId);
                                       break;
                                   case 'btnSubCat':
                                       toggleSubCategory(this);
                                       break;
                               };
                               // Gets the settings for the search and sets them to the addressbar
                               stringifySettings();

                               return false;
                           });

            // Called when request from external page is done
            $.address.externalChange(function(event) {
                var val = event.value;
                if (val != '/') {       // No settings are set.
                    parseSettings(val); // Parses and setts all values
                    var newSearch = updateButtonsWithSettings();   // Updates all buttons and stuff visually
                    refreshList(newSearch);
                }
            });

            $searchArea.find('#searchProducts').hover(
                function(event) {
                    if ($searchArea.find('#searchProducts').find('img').attr('src') == "/images/sortButtons_products_false.png") {
                        $('#search').find('#productsBubble:first').removeClass('removeProducts');
                        $('#search').find('#productsBubble:first').addClass('addProducts');
                    }
                    else {
                        $('#search').find('#productsBubble:first').addClass('removeProducts');
                        $('#search').find('#productsBubble:first').removeClass('addProducts');
                    }
                    $('#search').find('#productsBubble:first').css('display', 'block');
                },
                function(event) {
                    $('#search').find('#productsBubble:first').css('display', 'none');
                    //$('#search').find('#productsBubble:first').fadeOut(500);
                }
            );

            $searchArea.find('#searchRecipes').hover(
                function(event) {
                    if ($searchArea.find('#searchRecipes').find('img').attr('src') == "/images/sortButtons_recipes_false.png") {
                        $('#search').find('#recipesBubble:first').removeClass('removeRecipes');
                        $('#search').find('#recipesBubble:first').addClass('addRecipes');
                    }
                    else {
                        $('#search').find('#recipesBubble:first').addClass('removeRecipes');
                        $('#search').find('#recipesBubble:first').removeClass('addRecipes');
                    }
                    $('#search').find('#recipesBubble:first').css('display', 'block');
                },
                function(event) {
                    $('#search').find('#recipesBubble:first').css('display', 'none');
                }
            );

            $searchArea.find('#searchArticles').hover(
                function(event) {
                    if ($searchArea.find('#searchArticles').find('img').attr('src') == "/images/sortButtons_articles_false.png") {
                        $('#search').find('#articlesBubble:first').removeClass('removeArticles');
                        $('#search').find('#articlesBubble:first').addClass('addArticles');
                    }
                    else {
                        $('#search').find('#articlesBubble:first').addClass('removeArticles');
                        $('#search').find('#articlesBubble:first').removeClass('addArticles');
                    }
                    $('#search').find('#articlesBubble:first').css('display', 'block');
                },
                function(event) {
                    $('#search').find('#articlesBubble:first').css('display', 'none');
                }
            );


            var $searchBox = $searchArea.find('#theSearchBox');
            searchItem.text = $searchBox.find('input[type=text]').val();    // Gets the default search text

            if ($searchBox.length > 0) {
                var $searchTxt = $searchBox.find('input[type=text]');
                $searchTxt.keydown(function(event) {
                    if (event.keyCode == 13) {
                        searchItem.text = $searchTxt.val();
                        stringifySettings();
                        refreshList();
                        return false;
                    }
                });

                var $searchBtn = $searchBox.find('input[type=image]');
                $searchBtn.click(function(event) {
                    searchItem.text = $searchTxt.val();
                    stringifySettings();
                    refreshList();
                    return false;
                });
            }


            // Detecting if we have a original searchid and current viewtype, adds it to the object in that case
            var $hiddenId = $searchArea.find('#currentSearchId');
            var $hiddenListType = $searchArea.find('#currentView');
            if ($hiddenId.length > 0) {
                searchItem.origId = $hiddenId.val();
            }

            if ($hiddenListType.length > 0) {
                var view = $hiddenListType.val();
                switch (view) {
                    case 'List':
                        viewType = 'list';
                        break;
                    case 'Grid':
                        viewType = 'grid';
                        break;
                    case 'Sumit':
                        viewType = 'summit';
                        break;
                }
            }

            fixPagingButtons();
        };


        /* *******************
        Functions for managing visual setup buttons and so on..
        *********************/

        // Toggles the sortingbuttons so they show the correct images depending on searchItem.sortOrder
        function setupSortingButtons() {
            var $img = $searchArea.find('#sortOptions img');
            switch (searchItem.sortOrder) {
                case 1:
                    $img.attr('src', '/images/senaste_active.png');
                    $img.attr('title', 'Sorterar senaste först');
                    break;
                case 2:
                    $img.attr('src', '/images/a-z_active.png');
                    $img.attr('title', 'Sorterar i bokstavsordning');
                    break;

                // Saknas för case 3 (order by hits!!)                                                                                        
            }
        }

        // Toggles the different types of items shown in the resultlist if type is undefined, we only fix the visuals
        function setupResultTypes(type) {
            // If a specified type is set then the variable is toggled, otherwise only the visuals are changed
            if (type) {
                if (type == 'products') searchItem.searchInProducts = !searchItem.searchInProducts;
                else if (type == 'recipes') searchItem.searchInRecipes = !searchItem.searchInRecipes;
                else if (type == 'articles') searchItem.searchInArticles = !searchItem.searchInArticles;
            }
            // Updating the buttons
            $('#searchProducts, #searchRecipes, #searchArticles').each(function() {
                var $img = $(this).find('img');
                if ($img) {
                    switch (this.id) {
                        case 'searchProducts':
                            if (searchItem.searchInProducts)
                                $img.attr('src', '/images/sortButtons_products_true.png');
                            else
                                $img.attr('src', '/images/sortButtons_products_false.png');
                            break;
                        case 'searchRecipes':
                            if (searchItem.searchInRecipes)
                                $img.attr('src', '/images/sortButtons_recipes_true.png');
                            else
                                $img.attr('src', '/images/sortButtons_recipes_false.png');
                            break;
                        case 'searchArticles':
                            if (searchItem.searchInArticles)
                                $img.attr('src', '/images/sortButtons_articles_true.png');
                            else
                                $img.attr('src', '/images/sortButtons_articles_false.png');
                            break;
                    }
                }
            });
        }

        // Setup the buttons for how many items per page we want to show
        function setupPageItemsButtons() {
            var $img = $searchArea.find('#itemsPerPage img');
            switch (pageItems) {
                case 20:
                    $img.attr('src', '/images/20_active.png');
                    $img.attr('title', 'Visar 20 per sida');
                    break;
                default:
                    $img.attr('src', '/images/alla_active.png');
                    $img.attr('title', 'Visar alla på samma sida');
                    break;
            }
        }

        /* *******************
        Ending functions for managing visual setup buttons and so on..
        *********************/

        function toggleResultType(type) {
            /// <summary>
            /// Updates the searchsettings, does a new search in the database if required
            /// Else uses the existing data to filter the results
            /// </summary>
            /// <param name="type">The type to toggle</param>

            setupResultTypes(type);
            // Updates the list with the current settings
            refreshList();
        };


        // Excludes or includes the selected subCategorys in the results        
        function toggleSubCategory(sender) {
            // If a sender is provided, it's status will be toggled
            if (sender) {
                // Turns of all other subCategories if they all are selected
                if (!$('#searchInCategorysContainer .btnSubCat.on').length)
                    $('#searchInCategorysContainer .btnSubCat').addClass('on');

                var $item = $(sender);
                $item.toggleClass('on');

                if (!$('#searchInCategorysContainer .btnSubCat:not(.on)').length)
                    $('#searchInCategorysContainer .btnSubCat').removeClass('on');
            }
            setupSubCategories();
            refreshList(true);
        }

        // Collects all info about which subCategories that are selected, adds the unselected to searchItem.excludeSubCategories
        function setupSubCategories() {
            searchItem.excludeSubCategories = [];
            $('#searchInCategorysContainer .btnSubCat.on').each(function() {
                var id = getSubCategoryId(this);
                if (id)
                    searchItem.excludeSubCategories.push(id);
            });
        }

        // Parses a id from a categoryItem
        function getSubCategoryId(cat) {
            var id = cat.id;
            if (id) {
                id = id.replace('subCat_', '');
                id = parseInt(id);
            }
            return id;
        }


        // Reorders the items in the list
        function toggleSorting(order) {
            if (order) {
                searchItem.sortOrder = order;
            }
            else {
                if (searchItem.sortOrder === 1)
                    searchItem.sortOrder = 2;
                else
                    searchItem.sortOrder = 1;
            }

            setupSortingButtons();

            reorderResult();

            // Updates the list with the current settings
            refreshList(true);
        }

        function reorderResult() {
            var sortFunct = null;
            switch (searchItem.sortOrder) {
                case 1: // Order by date
                    sortFunct = function(a, b) {
                        if (a.Item.date > b.Item.date) {
                            return -1;
                        }
                        if (a.Item.date < b.Item.date) {
                            return 1;
                        }
                        if (a.Item.date == b.Item.date) {
                            return 0;
                        }
                    };
                    break;
                case 2: // Order by heading
                    sortFunct = function(a, b) {
                        if (a.Item.heading < b.Item.heading) {
                            return -1;
                        }
                        if (a.Item.heading > b.Item.heading) {
                            return 1;
                        }
                        if (a.Item.heading == b.Item.heading) {
                            return 0;
                        }
                    };
                    break;
                case 3: // Order by hits
                    sortFunct = function(a, b) {
                        if (a.Item.heading < b.Item.heading) {
                            return -1;
                        }
                        if (a.Item.heading > b.Item.heading) {
                            return 1;
                        }
                        if (a.Item.heading == b.Item.heading) {
                            return 0;
                        }
                    }
                    break;
            }

            if (searchItem.searchResult.length > 0
                && sortFunct) {
                searchItem.searchResult = searchItem.searchResult.sort(sortFunct);
            }
        }

        // Changes between 20 or all items
        function togglePageItems() {
            if (pageItems === 0)
                pageItems = 20;
            else
                pageItems = 0;

            setupPageItemsButtons();

            // Updates the list with the current settings
            refreshList(true);
        }

        function switchPage(btnId) {
            switch (btnId) {
                case 'pagingPrev':
                    currentPage--;
                    break;
                case 'pagingNext':
                    currentPage++;
                    break;
            }
            // Updates the list with the current settings
            refreshList(true);
        }

        // switches the view
        function switchView(view) {
            viewType = view;
            // Updates the list with the current settings
            refreshList(true);
        };

        /* ******************************
        Functions for managing forward and back clicks
        ******************************/

        // Creates a string containing all current settings for the search, should be placed in the adressrow to support back and forward
        function stringifySettings() {
            var settings = 0;
            // Setting up listtype
            if (viewType == 'list') settings += 1;
            else if (viewType == 'grid') settings += 2;
            else if (viewType == 'summit') settings += 4;
            // Setup list order. (Sortorder is 1 when ascending, increase when show all)
            if (searchItem.sortOrder == 2) settings += 8;
            else if (searchItem.sortOrder == 3) settings += 16;
            // Setup ltems per page (20 or all, pageItems is set to 0 if all should be shown, in that case, increase value)
            if (pageItems) settings += 32;
            // Setup producttypes to search in
            if (searchItem.searchInProducts) settings += 64;
            if (searchItem.searchInRecipes) settings += 128;
            if (searchItem.searchInArticles) settings += 256;

            // Adding values for the subcategories
            settings += stringifySubCategories(512);

            $.address.parameter('settings', settings);
            $.address.parameter('text', searchItem.text);
            $.address.parameter('page', currentPage);
        }

        // Figures out which subcategories are selected and creates a value from that
        function stringifySubCategories(bitVal) {
            if (!$.fn.reverse) // Adds reverse to jQuery if it doesn't exist
                $.fn.reverse = [].reverse;

            var value = 0;
            $('#searchInCategorysContainer .btnSubCat').reverse().each(function() {
                if (!$(this).hasClass('on')) // I would think it would be more logic to have it the other way (on when on, not off)
                    value += bitVal;
                // Increases the bitVal for next loop
                bitVal *= 2;
            });
            return value;
        }

        // Parses the settingsstring
        function parseSettings(settings) {
            var isNewSearch = false;
            // Parsing settings
            var value = $.address.parameter('settings');
            var text = $.address.parameter('text');
            var page = $.address.parameter('page');

            // Adding values, if there is anything to set
            if (value
                || text
                || page) {
                $(window).scrollTo($('#searchArea')); // Would be nice to find the last selected item to return to, but thats a later thing to fix.

                if (value)
                    value = parseSubCategories(value);
                setupSubCategories();
                parseBaseValues(value);
                if (text) {
                    isNewSearch = (searchItem.text != text);
                    searchItem.text = text;
                    if (isNewSearch)
                        $searchArea.find('#theSearchBox input[type=text]').val(searchItem.text);
                }
                if (page)
                    currentPage = page;
            }
            return isNewSearch;
        }

        // Parses the subCategoryvalues and sets the values to the serachitem
        // Must be run before parsing the baseValues !!
        function parseSubCategories(value) {
            var categories = $('#searchInCategorysContainer .btnSubCat').length;
            var bitVal = Math.pow(2, (8 + categories));
            $('#searchInCategorysContainer .btnSubCat').each(function() {
                value >= bitVal ?
                    (value -= bitVal) && $(this).removeClass('on') :
                    $(this).addClass('on');
                bitVal = bitVal / 2;
            });
            return value;
        }

        // Parses the basevalues and sets the values to the serachitem
        function parseBaseValues(value) {
            var bitVal = 256;
            searchItem.searchInArticles = (value >= bitVal) ? (value -= bitVal) && true : false;    // 256
            bitVal = bitVal / 2;
            searchItem.searchInRecipes = (value >= bitVal) ? (value -= bitVal) && true : false;     // 128
            bitVal = bitVal / 2;
            searchItem.searchInProducts = (value >= bitVal) ? (value -= bitVal) && true : false;    // 64
            bitVal = bitVal / 2;
            pageItems = (value >= bitVal) ? (value -= bitVal) && 20 : 0;                            // 32
            bitVal = bitVal / 2;
            searchItem.sortOrder = (value >= bitVal) ? (value -= bitVal) && 3 : 1;                  // 16
            bitVal = bitVal / 2;
            if (searchItem.sortOrder != 3)
                searchItem.sortOrder = (value >= bitVal) ? (value -= bitVal) && 2 : 1;              // 8
            bitVal = bitVal / 2;
            if (value == 4) viewType = 'summit';                                                    // 4
            else if (value == 2) viewType = 'grid';                                                 // 2
            else if (value == 1) viewType = 'list';                                                 // 1
        }

        function updateButtonsWithSettings() {
            setupSortingButtons();
            setupPageItemsButtons();
            setupResultTypes();

            //   toggleSubCategory(event);

        }

        /* ******************************
        Ended managing forward and back clicks
        ******************************/

        function refreshList(noPost) {
            // Send a ajaxrequest
            if (searchItem.searchResult.length >= 0
                && (!noPost
                    || searchItem.searchResult.length === 0)) {
                // Visa en loading symbol..


                var callback = function(response) {
                    if (response.Success) {
                        searchItem = response.Data;
                        reorderResult();    // Should be done on the server instead
                        buildList(searchItem, viewType);
                        // Updates the pageingbuttons att the bottom of the page..
                        fixPagingButtons();
                    }
                    else
                        alert('Ett fel har uppstått. Försök igen.');
                };

                var error = function(error) {
                    alert('Ett fel har uppstått. Försök igen.\n\rMeddelande: ' + error.responseText);
                };

                requestNewSearch(callback, error);
            }
            // Rebuild the list with existing data
            else {
                buildList(searchItem, viewType);
                // Updates the pageingbuttons att the bottom of the page..
                fixPagingButtons();
            }
        };

        // Updates the pageingbuttons att the bottom of the page..
        function fixPagingButtons() {
            var $pagediv = $searchArea.find('#searchPaging');
            if (pageItems === 0) {
                $pagediv.css('display', 'none');
            }
            else {
                $pagediv.css('display', 'block');
                if (currentPage == 0)
                    $pagediv.find('div:first').css('display', 'none');
                else
                    $pagediv.find('div:first').css('display', 'block');

                if ((countMaxPages() - 1) <= currentPage)
                    $pagediv.find('div:eq(1)').css('display', 'none');
                else
                    $pagediv.find('div:eq(1)').css('display', 'block');
            }
        }

        // builds a searchlist
        function buildList(searchItm, listType) {
            var $list = $searchArea.find('#searchResult');
            switch (listType) {
                case 'list':
                    $list.html(buildViewList(searchItm));
                    break;
                case 'grid':
                    $list.html(buildViewGrid(searchItm));
                    break;
                case 'summit':
                    $list.html(buildViewSummit(searchItm));
                    break;
            }
        };

        // Building Listview
        function buildViewList(searchItm) {
            var html = [];
            var itmCount = searchItm.searchResult.length;
            var result = searchItm.searchResult;
            var addedItms = 0;
            html.push('<table id="listTable" cellspacing="0" cellpadding="0" border="0">');
            for (var i = 0; itmCount > i; i++) {
                var itm = result[i];
                if (filterTypes(itm, searchItm)) {
                    if (filterPagingPages(addedItms))
                        html.push(buildViewListItem(itm));
                    addedItms++;
                }
            }
            html.push('</table>');
            updateSearchHits(addedItms);

            return html.join('');
        };

        function buildViewListItem(itm) {
            // Variables that I can't get directly from itm
            var vars = getVariableVarsFromItem(itm);

            // Creates the html for the item
            var html = '<tr>'
                        + '<td class="typeSymbol"><img src="' + vars.typeImg + '" title="' + vars.typeName + '" alt="' + vars.typeName + '"/></td>'
                        + '<td class="name"><a href="' + vars.link + '">' + itm.Item.heading + '</a></td>'
                        + '<td class="arrow"><a href="' + vars.link + '"><img src="/images/list_arrow.png" title="Gå till" alt="Gå till" /></a></td>'
                        + '<td class="tagLinks">' + vars.tags + '</td>'
                        + '<td class="date">' + itm.Item.date.substr(0, 10) + '</td>'
                      + '</tr>';
            return html;
        };

        /// Building Gridview
        function buildViewGrid(searchItm) {
            var html = [];
            var itmCount = searchItm.searchResult.length;
            var result = searchItm.searchResult;
            var addedItms = 0;
            var newRow = true;
            html.push('<table id="listTable" cellspacing="0" cellpadding="0" border="0">');
            for (var i = 0; itmCount > i; i++) {
                var itm = result[i];
                if (filterTypes(itm, searchItm)) {
                    newRow = addedItms % 4 == 0;

                    if (filterPagingPages(addedItms)) {
                        if (newRow) {
                            if (addedItms > 0)
                                html.push('</tr>');
                            html.push('<tr>');
                        }
                        if (addedItms % 4 == 3)
                            itm.setRight = false;
                        else
                            itm.setRight = true;

                        html.push(buildViewGridItem(itm));
                    }
                    addedItms++;
                }
            }
            if (!newRow)
                html.push('</tr>');
            html.push('</table>');
            updateSearchHits(addedItms);

            return html.join('');
        };

        function buildViewGridItem(itm) {
            // Variables that I can't get directly from itm
            var vars = getVariableVarsFromItem(itm);

            // Creates the html for the item
            var html = '<td class="grid' + ((itm.setRight && ' right')
                                                || '') + '">'
                        + '<div class="gridItemImage">'
                            + '<div class="gridItemTypeImg"><img src="' + vars.typeImg + '" title="' + vars.typeName + '" alt="' + vars.typeName + '"/></div>'
                            + '<a href="' + vars.link + '"><img src="' + itm.Item.gridImageUrl.url + '" '
                                + (itm.Item.gridImageUrl.largest === 0
                                    || (itm.Item.gridImageUrl.largest === 1 && 'width="107" ')
                                    || (itm.Item.gridImageUrl.largest === 2 && 'height="107" '))
                                + ' title="' + itm.Item.heading + '" alt="' + itm.Item.heading + '"/></a>'
                        + '</div>'
                        + '<div class="gridItemText"><a href="' + vars.link + '">' + itm.Item.heading + '</a></div>'
                      + '</td>';
            return html;
        };

        /// Building Summitview
        function buildViewSummit(searchItm) {
            var html = [];
            var itmCount = searchItm.searchResult.length;
            var result = searchItm.searchResult;
            var addedItms = 0;
            html.push('<table id="listTable" cellspacing="0" cellpadding="0" border="0">');
            for (var i = 0; itmCount > i; i++) {
                var itm = result[i];
                if (filterTypes(itm, searchItm)) {
                    if (filterPagingPages(addedItms))
                        html.push(buildViewSummitItem(itm));
                    addedItms++;
                }
            }
            html.push('</table>');
            updateSearchHits(addedItms);

            return html.join('');
        };

        function buildViewSummitItem(itm) {
            // Variables that I can't get directly from itm
            var vars = getVariableVarsFromItem(itm);

            // Creates the html for the item
            var html = '<tr>'
                        + '<td style="width:166px; padding:10px 0px 10px 0px; vertical-align:top;">'
                            + '<a href="' + vars.link + '"><img src="' + itm.Item.sumitImageUrl.url + '" '
                                + (itm.Item.sumitImageUrl.largest === 0
                                    || (itm.Item.sumitImageUrl.largest === 1 && 'width="166" '))
                            + 'title="' + itm.Item.heading + '" alt="' + itm.Item.heading + '"/></a>'
                        + '</td>'
                        + '<td class="summit">'
                            + '<h2><a href="' + vars.link + '">' + itm.Item.heading + '</a></h2>'
                            + '<img src="' + vars.typeImg + '" title="' + vars.typeName + '" alt="' + vars.typeName + '">'
                            + itm.Item.ingress
                            + '<a href="' + vars.link + '"><img src="/images/arrow-white-bg.jpg" title="Gå till" alt="Gå till" align="middle" /></a>'
                            + ((vars.tags.length > 0 && '<div class="tagDiv">Etiketter: <span class="tags">' + vars.tags + '</span></div>')
                                || '')
                        + '</td>'
                    + '</tr>';
            return html;
        };

        function updateSearchHits(hits) {
            $searchArea.find('#searchHits').html(hits);
            lastAddedItems = hits;
        }

        // Extracts variable properties from a searchResult
        function getVariableVarsFromItem(item) {
            var vars = {
                typeImg: types[item.Item.type].img,
                typeName: types[item.Item.type].name,
                link: '',
                tags: buildTagList(item.Item.tags)
            };

            if (item.Item.permalinks.length > 0)
                vars.link = item.Item.permalinks[0].Link;
            else
                vars.link = '/page.aspx?id=' + item.Item.id;
            //vars.link = item.Item.heading.replace(/ /g, '-');

            return vars;
        }

        // Checks so the current searchitem goes through the filter
        function filterTypes(item, settings) {
            var typeOk = false;
            switch (item.Item.type) {
                case 1:
                    typeOk = settings.searchInArticles;
                    break;
                case 2:
                    typeOk = settings.searchInProducts;
                    break;
                case 3:
                    typeOk = settings.searchInRecipes;
                    break;
            }
            if (typeOk && settings.excludeSubCategories.length > 0) {
                // check if item category is in exclude list

                if (settings.excludeSubCategories.indexOf(item.Item.categoryId) >= 0) {
                    typeOk = false;
                }
                else {
                    typeOk = true;
                }
            }
            return typeOk;
        }

        function filterPagingPages(itemNo) {
            var min = pageItems * currentPage;
            var max = min + pageItems;
            if ((itemNo >= min
                 && itemNo < max)
                || max === 0)
                return true;
            return false;
        }

        function countMaxPages() {
            var pages = 1;
            var results = lastAddedItems;  //searchItem.searchResult.length;
            if (!results) {
                results = $searchArea.find('#searchHits').text();
                if (!results)
                    results = 0;
            }

            if (pageItems > 0)
                pages = Math.ceil(results / pageItems);
            return pages;
        }

        /// Builds the taglist
        function buildTagList(tags) {
            var html = '';
            var tagNo = tags.length;
            for (var i = 0; i < tagNo; i++) {
                var tagName = tags[i].TagName;
                var tag = {
                    name: tagName,
                    search: tagName.replace(/ /g, '-')
                };
                if (html.length > 0)
                    html += ', ';
                html += '<a href="/search.aspx?s=' + tag.search + '">' + tag.name + '</a>';
            }

            return html;
        }

        function requestNewSearch(callback, error) {
            /// <summary>
            /// Requests a new search from the server, fires callback if succeded else error
            /// </summary>
            /// <param name="callback">Function to call when request is completed</param>
            /// <param name="error">Function to call if something fails</param>
            searchItem.searchResult = [];
            var options = {
                url: '/ws/pages.asmx/GetSearch',
                data: { search: searchItem },
                success: callback,
                error: error
            };

            findus.sendRequest(options);
        };

    }

    return {
        Init: function() {
            init();
            return this;
        },
        ToggleResultType: function(type) {
            toggleResultType(type);
            return this;
        },
        SwitchView: function(view) {
            switchView(view);
            return this;
        }
    };
} ());

/* Functions for Search */
findus.Cloud = (function() {
    function init() {

        $('#cloudToday'
            + ',#cloudWeek'
            + ',#cloudMonth').click(function(event) {
                var itemId = $(event.target).attr('id');
                var $target = $('#tagContent');
                // Determining the type of event, and fires it
                switch (itemId) {
                    case 'cloudToday':
                        getCloud(1, 20, $target);
                        break;
                    case 'cloudWeek':
                        getCloud(7, 20, $target);
                        break;
                    case 'cloudMonth':
                        getCloud(30, 20, $target);
                        break;
                };
                return false;
            });
    }

    function getCloud(days, items, target) {
        var callback = function(response) {
            var html = [];
            var tc = response.Data;
            var noTags = tc.Items.length;
            for (var i = 0; i < noTags; i++) {
                var tag = tc.Items[i];
                var size = (tag.HitRate + 1) * 5;
                if (size < 13)
                    size = 12;
                if (size > 30)
                    size = 25;
                html.push('<span class="tagitem" style="font-size:' + size
                    + 'px;"><a href="/Search.aspx?s=' + tag.Tag.TagName + '">'
                    + tag.Tag.TagName + "</a></span> ");
            }

            $(target).html(html.join(''));
        };

        var error = function(error) {
            // Add a errormessage
        };

        var options = {
            url: '/ws/pages.asmx/GetCloud',
            data: {
                days: days,
                items: items
            },
            success: callback,
            error: error
        };

        findus.sendRequest(options);
    }

    return {
        Init: function() {
            init();
            return this;
        },
        GetCloud: function(days, target) {
            getCloud(days, target);
            return this;
        }
    }
} ());





//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.indexOf) {
    Array.prototype.indexOf = function(elt /*, from*/) {
        var len = this.length;

        var from = Number(arguments[1]) || 0;
        from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
        if (from < 0)
            from += len;

        for (; from < len; from++) {
            if (from in this &&
          this[from] === elt)
                return from;
        }
        return -1;
    };
}

//This prototype is provided by the Mozilla foundation and
//is distributed under the MIT license.
//http://www.ibiblio.org/pub/Linux/LICENSES/mit.license

if (!Array.prototype.forEach) {
    Array.prototype.forEach = function(fun /*, thisp*/) {
        var len = this.length;
        if (typeof fun != "function")
            throw new TypeError();

        var thisp = arguments[1];
        for (var i = 0; i < len; i++) {
            if (i in this)
                fun.call(thisp, this[i], i, this);
        }
    };
}