function oc(a) {
    var o = {};
    for(var i=0; i < a.length; i++) {
        o[a[i]]='';
    }
    return o;
}

function truncate(text, words) {
    var strippedText = text.split(' ').slice(0, words);
    var textTrunc = strippedText.join(' ');
    if (textTrunc.length < text.length) {
        return textTrunc+'...';
    } else {
        return textTrunc;
    }
}

function truncate_chars(text, num_chars)
{
	if (text.length>num_chars)
		return text.slice(0,num_chars)+'...';
	return text
}

function formatFancyboxTitle(title, currentArray, currentIndex, currentOpts) {
    return '<div id="fancy-title"><span><a href="javascript:;" onclick="$.fancybox.close();"><img src="/site_media/images/fancybox/closelabel.gif" /></a></span>' + (title && title.length ? '<b>' + title + '</b>' : '' ) + '</div>';
}

function getUrlVars(url)
{
    var vars = [], hash, hashes;
	if(url.indexOf('?')!=-1){
		hashes = url.slice(url.indexOf('?') + 1).split('&');
	
		for(var i = 0; i < hashes.length; i++)
		{
			hash = hashes[i].split('=');
			vars.push(hash[0]);
			vars[hash[0]] = hash[1];
		}
	}
    return vars;
}

function urlQueryString(url, params){
	url += getUrlVars(url).length?'&':'?';
	if(params){
		url+=$.param(params)
	}
	return url
}

function shortPagination(el_id, current_page, paginator_num_pages){
	$(".pagination", $el).addClass("short-pagination");
	var next_page = current_page < paginator_num_pages?current_page+1:0;
	var prev_page = current_page > 1?current_page-1:0;
	var $el = $("#"+el_id);
	$(".pagination .next", $el).prevAll('a').filter(function(){
		var page = this.href.split('?')[1].split('&')[0];
		return page != 'page='+paginator_num_pages && page != 'page='+next_page && page != 'page='+prev_page && page != 'page=1';
	}).remove();	
	
	
	if(current_page + 9 > paginator_num_pages && current_page + 2 < paginator_num_pages){
		$(".pagination a:contains("+paginator_num_pages+")", $el).before('... ');
	}
	if(current_page < 11 && current_page - 2 > 1){
		$(".pagination .prev ", $el).next('a').after(' ... ');
	}
	$(".pagination", $el).htmlClean();
}

jQuery.fn.htmlClean = function() {
    this.contents().filter(function() {
        if (this.nodeType != 3) {
            $(this).htmlClean();
            return false;
        }
        else {
            return !/\S/.test(this.nodeValue);
        }
    }).remove();
}

function stripHTML(oldString) {
    return oldString.replace(/(<([^>]+)>)/ig,"");
}

function strip(text) {
    return text.replace(/^\s+|\s+$/g, '');
}

function copyObject(o) {
    var c = new Object();
    for (var e in o) {
        c[e] = o[e];
    }
    return c;
}

/* Returns array without duplicates */
function uniqueArray(a) {
    temp = new Array();
    for(i=0;i<a.length;i++){
        if(!contains(temp, a[i])){
            temp.length+=1;
            temp[temp.length-1]=a[i];
        }
    }
    return temp;
}

/* Will check for the Uniqueness */
function contains(a, e) {
    for(j=0;j<a.length;j++)if(a[j]==e)return true;
    return false;
}

function popupWindow(triggeringLink, width, height, link, top, left, href) {
	if(!top)
		top = 20;
	if(!left)
		left = 20;
    var name = triggeringLink.id.replace('-','_');
	if(!href)
		href = triggeringLink.href;
	if (link) href = link;
    if (href.indexOf('?') == -1) {
        href += '?_popup=1';
    } else {
        href  += '&_popup=1';
    }
    win = window.open(href,name,'height='+height+',width='+width+',top='+top+',left='+left+',resizable=yes,scrollbars=no');
    win.focus();
    return false;
}

/* Tiny MCE helpers - used for activating/deactivating editor in modals */
function deactivateTinyMCE(fieldId) {
    if (tinyMCE.getInstanceById(fieldId)) {
        tinyMCE.execCommand('mceFocus', false, fieldId);
        tinyMCE.execCommand('mceRemoveControl', false, fieldId);
    }
    tinyMCE.triggerSave();
}
function activateTinyMCE(fieldId) {
    tinyMCE.execCommand('mceAddControl', false, fieldId);
}

$.maxZIndex = $.fn.maxZIndex = function(opt) {
    var def = { inc: 10, group: "*" };
    $.extend(def, opt);
    var zmax = 0;
    $(def.group).each(function() {
        var cur = parseInt($(this).css('z-index'));
        zmax = cur > zmax ? cur : zmax;
    });
    if (!this.jquery)
        return zmax;
    return this.each(function() {
        zmax += def.inc;
        $(this).css("z-index", zmax);
    });
};

/*
    Creates dynamically paginated list.

    Next & prev buttons have exist already in pagination container.
    By default function adds links to all pages (this can be disabled by
    allPagesLinks setting).
    Supports list with radio inputs. When one of them is already selected
    then initial page is set on one to which checked input belonges.
*/
$.fn.listSlicePaginator = function(options) {
    var defaultOptions = {
        pagination: '.pagination',
        pageLimit: 10,
        nextSliceButton: "#pagination-next-slide",
        prevSliceButton: "#pagination-prev-slide",
        allPagesLinks: true
    };
    var settings = $.extend(defaultOptions, options);

    $pagList = $(this);
    $pagination = $(settings.pagination);
    var lastPage = parseInt($pagList.length / settings.pageLimit);
    var totalPages = lastPage + 1;
    var currentPage;

    // render pageination buttons for each page
    if (settings.allPagesLinks) {
        function renderPagination(page) {
            $pagination.show();
            $(".auto-pagination", $pagination).remove();
            for (var i=0; i < totalPages; i++) {
                var n = i + 1;
                if (i == page) {
                    $(settings.nextSliceButton, $pagination).before('<span class="current auto-pagination"><a id="paginaton-page-'+i+'" href="">'+n+'</a></span>');
                } else {
                    $(settings.nextSliceButton, $pagination).before('<span class="auto-pagination"><a id="paginaton-page-'+i+'" href="">'+n+'</a></span>');
                }
            }
        }
    }

    // set current page according to given page index
    function setPage(page) {
        $pagList.hide().slice(page*10, (page+1)*10).show();
        renderPagination(page);
    }

    // initialization - sets page with checked input if exists or first page
    if ($pagList.length > settings.pageLimit) {
        var $checkedInput = $("input:checked", $pagList);
        if ($checkedInput.length) {
            var checkedInputIdx = $('input', $pagList).index($checkedInput);
            currentPage = parseInt(checkedInputIdx / settings.pageLimit);
        } else {
            currentPage = 0;
        }
        setPage(currentPage);
    }

    // handle button with page number
    $("[id^='paginaton-page-']").live("click", function() {
        var page = parseInt(this.id.split('-')[2]);
        setPage(page);
        currentPage = page;
        return false;
    });

    // handle prev page button
    $(settings.prevSliceButton).click(function() {
        if (currentPage > 0) {
            currentPage -= 1;
            setPage(currentPage);
        }
        return false;
    });

    // handle next page button
    $(settings.nextSliceButton).click(function() {
        if (currentPage < lastPage) {
            currentPage += 1;
            setPage(currentPage);
        }
        return false;
    });
    return this;
};

/* Handlers comments plugin
     Required in template: 
	- comments selector id in format: "comments-<plugin-name>-<plugin-id>",
	- add comment link class: ".comments-add",
	- count comment contener class: "comments-count"
	- list comments box id in format: "list-comments-<comments-selector-id>"
      See: templates/dreams/questions_advice_plugin.html	          
*/	

$.fn.pluginComments = function(options) {
	$(this).each(function(){
		var $plugin = $(this);
		var split = $plugin.attr('id').split('-');
		var object_id = split.pop();
		var content_type_id = split.pop();
		var $list = $("#list-"+$plugin.attr("id"));
		
		function reloadCounter(){
			$.manageAjax.add('defaultQueue', {
				success: function(response) {
					$(".comments-count", $plugin).html(response);
				},
				url: '/usercontent/comment_count/'+content_type_id+'/'+object_id+'/',
				type: 'GET',
				cacheResponse: false
			});
		}
		
		$(".comments-show", $plugin).live('click', function(e){
			if(!$list.hasClass('content-loaded')){
				$.manageAjax.add('defaultQueue', {
			        success: function(response) {
			            $list.html(response);
					},
			        url: this.href + '?scope=plugin',
			        type: 'GET',
					cacheResponse: false
			    });
				$list.show();
			} else {
				$list.toggle();
			}
			$list.addClass('content-loaded');
			e.preventDefault(); 			
		});
		
		$(".comments-add", $plugin).popup({
			width: 600,
			onSuccessClose: function(res, status, xhr, $form) {
				reloadCounter();
				$list.removeClass("content-loaded");
				$(".comments-show", $plugin).trigger('click');
			}
		})
		
		reloadCounter();
	})

	return this;
}

/* 
using jquery.expander
If element has class = 'expander', slicePoint takes default value 250.
If has class = 'expander-200', slicePoint = 200
*/
function expandText(parent){
	var slicePoint = 250;
	$(".expander", parent).expander({slicePoint: slicePoint, expandText: "Show more", userCollapseText: "Hide"});

	$("[class*='expander-']", parent).each(function(){
		classList = $(this).attr('class').split(/\s+/);
		for (i=0; i<classList.length; i++){
			if((/^expander-/.test(classList[i]))){
				v = parseInt(classList[i].split('-')[1]);
				if(v) {
					slicePoint = v;
				}
			break;
			}
		}
		$(this).expander({slicePoint: slicePoint, expandText: "Show more", userCollapseText: "Hide"});
	})
}
    
function dayValidation(yearField, monthField, dayField)
{
    function validation()
    {
        var year = $('option:selected', yearField)[0].value;
        var month = $('option:selected', monthField)[0].value;

        var max_days = new Date(year, month, 0).getDate();
        if ($('option:selected:first', dayField).val() > max_days)
            $('option:selected:first', dayField).removeAttr("selected");
        $('option', dayField).slice(28+1, max_days+1).show();
        $('option', dayField).slice(max_days+1).hide();
    }
    yearField.change(validation);
    monthField.change(validation);
    dayField.change(validation);
}

/*
drop down list options
*/

function dropdownList(){
	$('.show-opt').live('click', function(){
		$('.show-opt').not(this).removeClass('extended').next('ul.options').hide();
		$(this).toggleClass('extended');
		$(this).next('ul.options').toggle();
		return false;
	});
	$('body').live('click', function(){ 
		$('.show-opt').removeClass('extended').next('ul.options').hide();
	});
}

function privacySettings(){
	$('.show-all-options').popup({
		width: 430,
		onSuccessResponse: function(res, status, xhr, $form) {
			var obj_id = res.extra_data.attribute_id?res.extra_data.attribute_id:res.extra_data.userplugin_id;
			var obj = $("#set-quick-status-"+obj_id);
			responseUserPluginControls(res, obj);
		},
		onLoad: function(){$("body").trigger('click');}
	});
			
	$('.set-quick-status').live('click', function(){
		var obj = $(this);
		$.manageAjax.add('defaultQueue', {
			success: function(response){responseUserPluginControls(response, obj)},
			url: $(this).attr('href'),
			type: 'POST',
			cacheResponse: false,
			data: {'quick-status': true, 'csrfmiddlewaretoken': $("input[name='csrfmiddlewaretoken']").val()}
		});
		return false;
	});
}

/*
using jquery.jqEasyCharCounter
*/

$.fn.charCounter = function(options) {
    var defaultOptions = {
        maxChars: 100,
		msgFontSize: '11px', 
        msgFontColor: '#cdcbcb'
    };
    var settings = $.extend(defaultOptions, options);
	if(!settings['maxCharsWarning']){
		settings['maxCharsWarning'] = settings['maxChars'] - 20;
	}
	$(this).jqEasyCounter(settings);
	return this;
}


function dateAddDays(myDate,days,tostring) {
	var monthname=new Array("January","February","March","April","May","June","July","August", "September","October","November","December")
	var d = new Date(myDate.getTime() + days*24*60*60*1000);
	if(tostring){
		return new Array(monthname[d.getMonth()], d.getDate(), d.getFullYear());
	} else {
		return d;
	}
}

// Generate 32 char random uuid 
function gen_uuid() {
    var uuid = ""
    for (var i=0; i < 32; i++) {
        uuid += Math.floor(Math.random() * 16).toString(16); 
    }
    return uuid
}

function initProgressBar(target, media_url) {
	target.progressBar({boxImage: media_url + 'images/progressbar.gif',
						barImage: {
								0:	media_url + 'images/progressbg_red.gif',
								30: media_url + 'images/progressbg_orange.gif',
								70: media_url + 'images/progressbg_green.gif'
							}});
}

function startProgressBarUpdate(target, url) {
  target.fadeIn();
  target.progressBar(0);
  //if(g_progress_intv != 0)
  //  clearInterval(g_progress_intv);
  g_progress_intv = setInterval(function() {
    $.getJSON(url, function(data) {
      if (data == null) {
      	target.progressBar(100);
        clearInterval(g_progress_intv);
        g_progress_intv = 0;
        return;
      }
      var percentage = Math.floor(100 * parseInt(data.uploaded) / parseInt(data.length));
      target.progressBar(percentage);
    });
  }, 1500);
}

function addVote(dir, url, vote_plugin) {
	$.manageAjax.add('defaultQueue', {
        success: function(response) {
        	if(response.success==1) {
	        	$.jGrowl(response.message, {header:'Success'});
	        	vote_plugin.replaceWith(response.extra_data.voting_plugin_content);
        	} else if(response.extra_data && response.extra_data.user_not_auth) {
				var login_modal = $('<a href="/accounts/signin/?next=."></a>').popup();
				login_modal.trigger('click');
        	} else $.jGrowl(response.message, {header:'ERROR'});
        },
        url: url + '?dir=' + dir,
        type: 'GET',
        cacheResponse: false
    });
}

// SimpleGeo related utilities
function selectSgeoLocation(features, $location_target, $dialog, callback)
{
    var available_locations = getAvailableLocations(features);

    if (available_locations.length == 0) {
        $location_target.val('');
        if (callback) {
            callback();
        }
    } else if (available_locations.length == 1) {
        $location_target.val(available_locations[0].data.locationId);
        if (callback) {
            callback();
        }
    } else {
        displaySgeoFilter(features, $location_target, $dialog, callback, true)
    }
}

function getAvailableLocations(features)
{
    var available_locations = new Array();
    for (var i = 0 ; i < features.length ; i++)
    {
        if (features[i].data.sgeoLookup && features[i].data.locationId) {
            available_locations.push(features[i]);
        }
    }
    return available_locations;
}

function getFeaturesCategories(features)
{
    categories = {};
    for (var i = 0 ; i < features.length ; i++)
    {
        if (!features[i].data.sgeoCategory)
            continue;
        var category = features[i].data.sgeoCategory;
        var subcategory = features[i].data.sgeoSubcategory;
        if (!(category in categories))
            categories[category] = Array();
        if ($.inArray(subcategory, categories[category]) == -1)
            categories[category].push(subcategory);
    }
    return categories;
}

function getAllowedSubcategories($categories_list)
{
    var subcategories = Array();
    $categories_list.find('li.cat2 > input:visible:checked').each(function() {
        subcategories.push($(this).siblings().filter('span.cat_name').text());
    });
    return subcategories;
}

function filterFeatures(features, allowed_subcategories)
{
    for (var i = 0 ; i < features.length ; i++) {
        if (features[i].data.sgeoSubcategory && $.inArray(features[i].data.sgeoSubcategory, allowed_subcategories) == -1) {
            features[i].style = new OpenLayers.Style();
        } else {
            features[i].style = null;
        }
    }
}

function displaySgeoFilter(features, $location_target, $original_dialog, callback, loc_select_only)
{
    var loc_select_only = typeof(loc_select_only) != 'undefined' ? loc_select_only : false;

    var $dialog = $($original_dialog.parent().html());
    $dialog.dialog({modal: true,
        resizable: false,
        width: 800,
        height: 'auto',
        autoopen: false,
        position: 'center',
        title: "Nearby places filter"});

    var $locations_list = $('#sgeo_location_select ul', $dialog);
    var $categories_list = $('#sgeo_categories_select ul', $dialog);
    var previous_location = $location_target.val();

    if ($locations_list.children().filter('li').length == 0 && $location_target.val()) {
        var single_location = true;
        $('#sgeo_location_select', $dialog).hide();
    } else {
        var single_location = false;
        $('#sgeo_location_select', $dialog).show();
    }

    if (!single_location && $locations_list.children().length == 0)
    {
        var available_locations = getAvailableLocations(features);
        for (var i = 0 ; i < available_locations.length ; i++)
        {
            $locations_list.append('<li><input type="radio" name="sgeo_location_select" value="'+available_locations[i].data.locationId+'" /><span class="loc_name">'+available_locations[i].data.listName+'</span></li>');
        }
    }
    
    if (!loc_select_only && $categories_list.children().length == 0)
    {
        $('#sgeo_categories_select', $dialog).show();
        var categories = getFeaturesCategories(features);
        for (var category in categories)
        {
            var $category_entry = $('<li class="cat1"></li>');
            $category_entry.append('<input type="checkbox" checked />');
            $category_entry.append('<span class="cat_name">'+category+'</span>');
            var $subcategories_list = $('<ul></ul>');
            for (var i = 0 ; i < categories[category].length ; i++)
            {
                var $subcategory_entry = $('<li class="cat2"></li>');
                $subcategory_entry.append('<input type="checkbox" checked />');
                $subcategory_entry.append('<span class="cat_name">'+categories[category][i]+'</span>');
                $subcategories_list.append($subcategory_entry);
            }
            $category_entry.append($subcategories_list);
            $categories_list.append($category_entry);
        }
    }
    else if (loc_select_only) {
        $categories_list.html('');
    }
    if(!loc_select_only)
    {
        $('#sgeo_categories_select', $dialog).show();
    } else {
        $('#sgeo_categories_select', $dialog).hide();
    }

    if ($location_target.val())
        $locations_list.find('input[value=' + $location_target.val() + ']').attr('checked', true);
    $categories_list.find('input[value=1]').attr('checked', true);
    $categories_list.find('input[value=0]').attr('checked', false);

    $categories_list.find('li.cat1 > input').click(function() {
        if ($(this).is(':checked'))
            $(this).siblings().filter('ul').show();
        else
            $(this).siblings().filter('ul').hide();
    });

    $('#apply-button', $dialog).click(function() {
        if (!single_location)
        {
            var location_id = $('input[type=radio]:checked', $locations_list).val();
            if (previous_location != location_id) {
                $categories_list.html('');
                $location_target.val(location_id);
            }
        }

        $categories_list.find('input').filter(':checked').val('1');
        $categories_list.find('input').not(':checked').val('0');
        $original_dialog.html($dialog.html());
        if (!loc_select_only) {
            var allowed_subcategories = getAllowedSubcategories($categories_list);
            filterFeatures(features, allowed_subcategories);
        }
        $dialog.dialog('close');
        callback();
        return false;
    });
    $dialog.dialog('open');
}

function refreshDreamsList(page) {
	var dream_list = $('#dreams-list')
    if (dream_list.length == 0) {
    	dream_list = $('#t2d_list');
    	if (dream_list.length == 0) {
        	return false;
        }
    }
    if (typeof(page) == 'undefined') {
        var page = $('.pagination:eq(0) .page.current').text();
    }
    var url = window.location.toString();
    if (url.lastIndexOf('?') != -1) {
        url = url.substr(url.lastIndexOf('?'));
        url += '&';
    } else {
        url = '?';
    }
    url += 'page=' + page;
    console.log("URL: " + url);
    $.manageAjax.add('paginationRefresh', {
        abortOld: true,
        success: function(response) {
            dream_list.html(response);
        },
        url: url
    });
    return true;
}

function restoreDreamsListModal() {
    actionCookie = $.cookie('actionCookie');
    if (actionCookie)
    {
        var dreamID = $.cookie('dreamlist_last_dreamid');
        if (dreamID && (actionCookie == 'dreams-add-to-my-list' ||
                actionCookie == 'dreams-check-off'))
        {
        var page = $.cookie('dreamlist_last_page');
            dreamID = parseInt(dreamID);

            if (actionCookie == 'dreams-add-to-my-list') {
                var popup_url = '/dreams/add_to_my_list/' + dreamID + '/';
                var popup_width = 680;
            } else {
                var popup_url = '/dreams/check_off/' + dreamID + '/';
                var popup_width = 750;
            }
            popup_url += "?redir=False"

            action_popup = $('<a id="action_popup" href=""></a>');
            action_popup.attr('href', popup_url);
            action_popup.popup({ 
                width: popup_width,
                onSuccessResponse: function() {
                    if (page) {
                        refreshDreamsList(page);
                    }
                }
            });
            action_popup.trigger('click');
        }
        $.cookie('dreamlist_last_dreamid', null, options={path: '/'});
        $.cookie('dreamlist_last_page', null, options={path: '/'});
        $.cookie('actionCookie', null, options={path: '/'});
    }
}


