/*

	#################################################################

	AppName:		CBW Claims
	Authur:			Ian Sheridan
	
	Description:	This is the main Utility javascrip file that will
					be used for the CBW Claims Website to handle
					general functionality that will appear in every
					page.

	#################################################################
	
*/

/* jQuery should play nice with prototype */
jQuery.noConflict();

/* $j is for convenience */
window.$j = jQuery;

/* setting defaults for blockUI jQuery plugin */
// In the IE6 blockUI functionality doesn't work as expected
// because of that this functionality is called for all browsers except IE6
// the issue has affected the category selector on add_item_to_claim functionality
if(!(jQuery.browser.msie && (jQuery.browser.version.charAt(0) == '6')))
{
  jQuery.blockUI({
          css: { 
                  border: 'none', 
                  padding: '15px', 
                  backgroundColor: '#000', 
                  '-webkit-border-radius': '10px', 
                  '-moz-border-radius': '10px', 
                  opacity: '.5', 
                  color: '#fff' 
      }
  });
}

/* TODO: big todo!! we need to combine and reorganize our scripts into the same namespace. */

var CBWUI = {
	initItemActions: function(parentElementId) {
		var par = $j('#' + parentElementId);
	    par.find(".options-button").click(function() {
		    var trigger = $j(this);
		    var menu = $j(this.hash); /* important that this is "hash"!! if "href", IE will give fully qualified url on ajax */
		    var el = trigger.parent().parent().get(0);
		    $j('.itemmenu-dropdown').each(function() {
			    var container = $j(this);
			    if (container.index(el) === -1) {
				    container.css('position', 'static');
				    container.find('ul').hide();
				    /* only one should show */
			    }
			    else {
				    container.css('position', 'relative');
			    }
		    });
		    menu.toggle();
		    return false;
	    });
		par.find(".itemmenu-dropdown ul").bgiframe().hover(function() {
	    }, function() {
		    $j(this).hide();
	    });
		document.autoHide.register(function() {
			return $j('#' + parentElementId + " .itemmenu-dropdown ul").get();
		}, 'itemActionDropdowns_' + parentElementId);

	    par.find(".report-options-button").click(function() {
		    var trigger = $j(this);
		    var menu = $j(this.hash); /* important that this is "hash"!! if "href", IE will give fully qualified url on ajax */
		    var el = trigger.parent().parent().get(0);
		    $j('.report-itemmenu-dropdown').each(function() {
			    var container = $j(this);
			    if (container.index(el) === -1) {
				    container.css('position', 'static');
				    container.find('ul').hide();
				    /* only one should show */
			    }
			    else {
				    container.css('position', 'relative');
			    }
		    });
		    menu.toggle();
		    return false;
	    });
		par.find(".report-itemmenu-dropdown ul").bgiframe().hover(function() {
	    }, function() {
		    $j(this).hide();
	    });
		document.autoHide.register(function() {
			return $j('#' + parentElementId + " .report-itemmenu-dropdown ul").get();
		}, 'itemReportActionDropdowns_' + parentElementId);
    }
}

var DefaultValueExcludingFormObserver = Class.create();
DefaultValueExcludingFormObserver.prototype = Object.extend(new Abstract.TimedObserver(), {
	getValue: function() {
		/* Serialize non-default values only */
		return function(form) {
			var elements = Form.getElements($(form));
			var queryComponents = new Array();

			for (var i = 0; i < elements.length; i++) {
				var el = elements[i];
				/* note that this doesn't account for defaults for non-text inputs */
				if ((!!el.type && el.type.toLowerCase() === 'hidden') || (el.value !== el.defaultValue && el.value !== '')) {
					var queryComponent = Form.Element.serialize(el);
				}
				else {
					var queryComponent = el.name;
				}
				if (queryComponent) queryComponents.push(queryComponent);
			}
			return queryComponents.join('&');
		}(this.element);
	}
});

var ListFilter = {
	initialize: function() {
		$j('.inline-filter').each(function() {
			$j(this).attr("autocomplete", "off");
			this.reset();
		});
		$j('.inline-filter .advanced-filters').bgiframe();
		$j('.inline-filter input[type=text]').each(function() {
			var input = $j(this);
			input.addClass('default');
			input.focus(ListFilter.focusHandler).blur(ListFilter.blurHandler).keydown(ListFilter.keydownHandler);
            this.setValue = ListFilter.setValue;
		});
		$j('.inline-filter-set a').click(function() {
			$j(this.hash).toggle();
			$j(this).toggleClass('exp');
			return false;
		});
	},
	keydownHandler: function() {
		if (this.value === this.defaultValue) {
			$j(this).addClass('default');
		}
		else {
			$j(this).removeClass('default')
		}
	},
	focusHandler: function() {
		if (this.value === this.defaultValue) {
			this.value = '';
			$j(this).removeClass('default');
		}
	},
	blurHandler: function() {
		if (this.value === '' || this.value === this.defaultValue) {
			this.value = this.defaultValue;
			$j(this).addClass('default');
		}
		else {
			$j(this).removeClass('default');
		}
	},
    setValue: function(val) {
        if (val !== '' && val !== this.value) {
            this.value = val;
            $j(this).removeClass('default');
        }
    }
}

jQuery(document).ready(function($j) {
	// FOR ALL pages
	// ----------------------------------------------------
	$j("#topnav>ul>li").hover(function(){
		$j(this).addClass("hover");
	},function(){
		$j(this).removeClass("hover");
	});
	
	// FOR _results.rhtml
	// ----------------------------------------------------
	$j("#itemsfound a.toggledesc").click(function(e) {
		if (!!e) e.preventDefault(); /* prevent url from showing */
		$j(this.hash).toggle("fast");
	});
	$j("#itemsfound a.closebtn").click(function(e) {
		if (!!e) e.preventDefault(); /* prevent url from showing */
		$j(this.hash).hide();
	})
	$j("#sort_anchor").click(function(){
		$j(this).siblings("ul").toggle();
	});

	$j(".item-list td.item-actions a").click(function(e) {
		if (!!e) e.preventDefault(); /* prevent url from showing */
		var form = $j('#' + $j(this).attr("rel"));
		if (!form.length === 1 || form.get(0).tagName.toLowerCase() !== 'form') return;
		form.submit();
	});
	var els = $j("a[@name='new_window']");
	/* in jQuery, els will never be null. instead we check for length of object collection. */
	if (els.length > 0) {els.attr("target","_blank");}

	// FOR _categories_menu.rhtml
	// ----------------------------------------------------

	/* initCatDropdown
	 * add the functions to the new element in the dropdown box.
	 * 
	 * @param {Object} element -- name of the ID of the node to be affected.
	 */

    var DrillDown = Class.create();
    DrillDown.prototype = {
        initialize: function() {
            var cbox = $j("#category_box");
            this.category_changed = null;
            $j("#category_anchor").click(function() {
                cbox.toggle();
                return false;
            });
            if (!!cbox.length) cbox.bgiframe();
            document.autoHide.register(function() {
                return $j("#category_box").get()
            }, "category");

            if ($j.browser.mozilla) $j("#category_anchor").css({overflow: 'hidden'})
            this.heading = $j('#category_anchor span');
            this.sld = $j('#slider');
            this.breadcrumbs = $j('#breadcrumbs');
            if ($j('#searchform').length) {
                this.currentCategory = $j('#category_id'); // We're probably on the search page
            }
            else {
                this.currentCategory = $j('#claim_item_category_id');
            }
            this.container = $j("#category_box").hover(function() {}, function() {
                $j(this).hide();
            });
        },
        setCategory: function(catID, name) {
            this.currentCategory.val(catID);
            this.heading.html(name);
            if (this.category_changed)
            {
                this.category_changed(catID, name);
            }
        },
        setBreadcrumbs: function(catID, doSubmit) {
            if (!this.breadcrumbs.length) return;
            if (doSubmit) $j('#searchform').submit();
            this.breadcrumbs.load("/breadcrumbs/create_breadcrumbs/", {category_id: catID});
        },
        prevSub: function(el, e) {
            if (e.stopPropagation) {
                e.stopPropagation();
                e.preventDefault();
            }
            else {
                e.cancelBubble = true;
                e.returnValue = false;
            }
            var current = $j(el.hash);
            var callback = function() {
                current.prev().css({overflow: 'auto'});
                current.remove();
            };
            this.sld.animate({left: '+=196px'}, 250, callback);
        },
        nextSub: function (el, e) {
            /* This function selects next category and if there are children, drills down.
             * There is nearly no distinction between links with children and links without. */
            if (e.stopPropagation) {
                e.stopPropagation();
                e.preventDefault();
            }
            else {
                e.cancelBubble = true;
                e.returnValue = false;
            }
            var relation = el.rel.split('::'); // Sort of like a path. relates CurrentCategory::NextCategory
            var nextID = relation[1];
            var catID = el.search.split('=')[1] || ""; // When child categories exists, this is the same as nextID
            this.setCategory(catID, el.innerHTML);
            if (!!nextID) {
                // This means there are child categories
                var current = $j('#cat' + relation[0]);
                var newList = $j('<ul id="' + 'cat' + nextID + '"><li>Loading...<li></ul>');
                current.css({'overflow': 'hidden'});
                newList.appendTo(this.sld).load(el.href);
                this.sld.animate({left: '-=196px'}, 250);
                this.setBreadcrumbs(nextID, false);
            }
            else {
                // When no children exist, it means you selected. hide the menu.
                this.container.hide();
                this.setBreadcrumbs(catID, true);
            }
            return false;
        },
        add_on_change: function (event_handler)
        {
            this.category_changed = event_handler;
        }
    }
    window.catmenu = new DrillDown();
    

	// FOR _depreciation_options_menu.rhtml
	// ----------------------------------------------------

	/* initCatDropdown
	 * add the functions to the new element in the dropdown box.
	 * 
	 * @param {Object} element -- name of the ID of the node to be affected.
	 */

    var DepreciationDrillDown = Class.create();
    DepreciationDrillDown.prototype = {
        initialize: function() {
            var cbox = $j("#depreciation_box");
            $j("#depreciation_anchor").click(function() {
                cbox.toggle();
                return false;
            });
            if (!!cbox.length) cbox.bgiframe();
            document.autoHide.register(function() {
                return $j("#depreciation_box").get()
            }, "depreciation_options_dropdown");

            if ($j.browser.mozilla) $j("#depreciation_anchor").css({overflow: 'hidden'})
            this.heading = $j('#depreciation_anchor span');
            this.sld = $j('#depreciation_slider');
            this.currentDepreciation = $j('#claim_item_depreciation_entry_id');
            this.container = $j("#depreciation_box").hover(function() {}, function() {
                $j(this).hide();
            });
        },
        setDepreciationOption: function(catID, name) {
            this.currentDepreciation.val(catID);
            this.heading.html(name);
        },
        chooseDepreciation: function (el, e) {
            if (e.stopPropagation) {
                e.stopPropagation();
                e.preventDefault();
            }
            else {
                e.cancelBubble = true;
                e.returnValue = false;
            }
            
            var catID = $j(el).attr("id");
            if (!!catID) {
                this.setDepreciationOption(catID, $j(el).children("#catName")[0].innerHTML);
            }
            else {
                this.setDepreciationOption("", "Please Select");                
            }
            
            this.container.hide();            
            return false;
        }
    }
    window.depOptmenu = new DepreciationDrillDown();
        
    /* TODO: consider reimplemnting defaultValue handlers for inputs */

    /* shows the associated panel on click. this way we don't need to specify an id but rely on
     * the existence of the panel in the same source order. Note that this implementation
     * enforces a 1-to-1 relationship between tabs and panels
     */
    var tabbedPanels = jQuery('.tabbed-panel').not(".exclude").hide(); // hide these initially
    var tabbedPanelTabs = jQuery('.tabbed-panel-tabs li').not(".exclude");
    tabbedPanelTabs.each(function(idx) {
        this.assocPanel = tabbedPanels.get(idx);
        jQuery(this).click(function(e) {
			if (!!e) e.preventDefault(); //really shouldn't matter, but for good measure
            tabbedPanelTabs.removeClass('selected'); //blindly remove them all
            jQuery(this).addClass('selected'); //set current
            tabbedPanels.hide();
            if (!!this.assocPanel) jQuery(this.assocPanel).show(); // panel should exist. if not, die silently
        });
    });
	var sel = jQuery('.tabbed-panel-tabs .selected');
	if (sel.length === 1) sel.click();

    initClaimDetailsToggler();
	document.autoHide.refresh();
});
// FOR /claim_items/_item_form_elements.rhtml
// ----------------------------------------------------
function initItemFormElements(form_id) {
	jQuery("button.source-submit").click(function() {
        if (!this.name || !jQuery("#source").length) return;
        var v = jQuery(this).attr("name");
        jQuery("#source").val(v);
		jQuery("#"+form_id).submit();
	});
}
/* this implementation makes a tradeoff between speed in initializing versus toggle speed.
 * Inline handlers exec more slowly, but initialization is *ridiculously* faster than before.
 * (in a few cases, firebug profiler reported 10x or better) Also avoids circular reference
 * memory leaks, and overall consumes less memory. */
function truncateItemDesc(idx, el) {
	var content = $j(el); // cache this, (el.id must be set!)
	var words = $j.trim(content.html().replace(/<[^>]+>/g, " ")).split(/[\s]+/); // collect all the words
	var numWords = words.length; // word count
	var truncateThreshold = 8; // length at which to truncate
	if (numWords > truncateThreshold) { // don't waste time for every element.
		// here's where the fun begins
		var firstPart = [];
		var theRest = [];
		/* for the numerous concat's performed for words, [].join() will be MUCH faster. Not so for few concats
		 * (e.g. constructing mousedown handlers). */
		for (var j = 0; j < numWords; j++) {
			if (j <= truncateThreshold) firstPart.push(words[j]);
			else theRest.push(words[j]);
		}
		var newContent = firstPart.join(" ") + '<span>&hellip;</span>\n<span style="display: none;">' + theRest.join(" ") + '</span>\n<a href="#' +
		                 el.id + '" onclick="return false;" onmousedown="$j(this.hash + \' span\').toggle();' +
		                 ' $j(this).text({more: \'less\', less: \'more\'}[$j(this).text()]); return false;">more</a>';
		content.html(newContent);
	}
}

function initClaimDetailsToggler() {
    var links = $j(".toggle-details a");
    var container = $j("#claiminfo");
    if (!container.length || links.length !== 2) return;
    links.click(function(e) {
        if (!!e) e.preventDefault(); // prevent url from showing
        if (this.hash === "#show") {
            container.addClass("expanded");
            container.removeClass("collapsed");
        }
        else {
            container.addClass("collapsed");
            container.removeClass("expanded");
        }
    });
}
