/**
    This function is trying to find a checked checkbox of a class 'box_class'
    whithin a form of id 'form_id'
    
    Returns true if empty (nothing is selected)
    false - otherwise
*/
function isCheckboxFormEmpty(form_id, box_class){
    els = $$('#'+form_id + ' input.' + box_class);
    //alert('els: ' + els.length);
    var len = els.length;
    for(var i = 0; i < len; i++){
        if(els[i].checked){
            return false;
        }
    }
    
    return true;
}

/**
    This function is trying to find a non-empty input field of a class 'el_class'
    whithin a form of id 'form_id'
    
    Returns true if everything is empty
    false - otherwise
*/
function isFormEmpty(form_id, el_class){
    els = $$('#'+form_id + ' input.' + el_class);
    alert('els: ' + els.length);
    var len = els.length;
    for(var i = 0; i < len; i++){
        if(!els[i].value.empty()){
            alert('Found!');
            return false;
        }
    }
    
    return true;
}

/**
* Toggles the display attribute of an item, given by ID.
* Shows the item if it is hidden and vice versa.

* If an image id is present, try to switch it to the appropriate arrow
*/
function toggleDisplay(id, img_id){

    el = $(id);
    if(!el || !el.style)
        return;
    
    if(el.style.display && el.style.display == 'none'){
        el.show();
        if(img_id)
            toggleImg(img_id, 'down');
    }else{
        el.hide();
        if(img_id)
            toggleImg(img_id, 'right');
    }
}

/**
* Toggles the image src
*/
function toggleImg(id, direction){

    el = $(id);
    if(!el || !el.src)
        return;

    var nameRight = 'section_bg_right_collapsed.gif';
    var nameDown = 'section_bg_right_expanded.gif';
    
    if(direction == 'down'){
        el.src = el.src.replace(nameRight, nameDown);
    }else{
        el.src = el.src.replace(nameDown, nameRight);
    }
}

/**
* This code takes care of the expanding/hiding of the <li> items
* on the Help page
*/

function toggleList(e){
  if( e.className == 'expand' )
    e.className = 'hide';
  else
    e.className = 'expand';
}

// Prevent a click on a child list element from reaching the parent.  
function cancelBubbling( evt ){
  // stop event from bubbling
  if( window.event )
    // IE
    window.event.cancelBubble = true;
  else if (evt.stopPropagation)
    // Firefox
    evt.stopPropagation();
}

Ajax.Responders.register({
  onException: function(transport, e) {
  	var message = e.message;
  	if (!window.uniAjaxErrors) {
  		window.uniAjaxErrors = [];
  	}
  	window.uniAjaxErrors.push(e);
  },
  onFailure: function(transport) {
    alert('Catastrophic failure: ' + transport.status + ' ' + transport.statusText);
  }
}
);

Unisource = Class.create();

Unisource.formatters = {
    en : function(value) {
        var number = new Number(value);
        var prefix;
        
        if (number < 0) {
        	prefix = '-$';
        } else {
        	prefix = '$';
        }
        return prefix + Math.abs(number).toFixed(2);
    }, 
    fr : function(value) {
        var number = new Number(value);
        return number.toFixed(2) + ' $';
    }
};
Unisource.formatCurrency = function(value) {
    var language = (Paths) ? Paths.lang : 'en';
    return Unisource.formatters[language](value);
}

Unisource.hasPrivilege = function(name) {
    return Unisource.Privileges && Unisource.Privileges[name];
}

Unisource.applyMaxScreenSize = function() {
    var max_screen_width = 1000;
    var max_screen_height = 768;
    if(screen.width < max_screen_width){
        max_screen_width = screen.width - 20;
    }
    if(screen.height < max_screen_height){
        max_screen_height = screen.height - 20;
    }
}

Unisource.makeURL = function(base, parameters) {
    var url = base;
    
    if ($H(parameters).any()) {
        url += $H(parameters)
        .map(
            function(parameter) {
                return parameter.key + '=' + encodeURIComponent(parameter.value);
            }
        )
        .inject(
            '',
            function(accumulator, item) {
               var result;
               
               if (accumulator == '') {
                   result = '?' + item;
               } else {
                   result = accumulator + '&' + item; 
               }
               
               return result;
            }
        );
    }
    
    return url;
}


function getSubCategoriesByLetter(letter) {
    new Ajax.Updater('subcategoriesListing', Paths.www + '/UniProducts/getSubCategoriesByLetter/'+letter, {method:'get'});
    return false;
}

function getManufacturersByLetter(letter) {
    new Ajax.Updater('manufacturersListing', Paths.www + '/UniProducts/getVendorsByLetter/'+letter, {method:'get'});
    return false;
}  

/***************************************************************
 *
 * Folders
 *
 ***************************************************************/
 
var FolderStack = {};

/** 
 * Push an element onto the folder stack
 * 
 * @param string folderName The name of the folder
 * @param integer position The position of the folder, starting at 1.
 * @param function onClick The function to call when the link is clicked
 */
FolderStack.set = function (folderName, position, onclick) {
    this.currentPosition = 0;
    this.container       = $('folderBreadcrumb');
    
    if (this.container) {
        this.prefix = this.container.innerHTML;
        this.set = function (folderName, position, onclick) {
            if (typeof(onclick) == 'function') {
                onclick = onclick.getBody().replace(/\n/, ' ');
            }
            this.stack[position] = {label: folderName, 'onclick': onclick};
            this.currentPosition = position;
            this.render();
        }
        this.render = function () {
            var html = new Array();
            
            // Builds the container and the content
            html[html.length] = '<div class="links">';
            html[html.length] = '<div class="link">' + this.prefix + '</div>';
            
            for (var i = 1; i <= this.currentPosition; i++) {
                html[html.length] = '<div class="link">';
                if (i == this.currentPosition) {
                    html[html.length] = this.stack[i].label;
                } else {
                    var link = '<a href="#" ';
                    if (this.stack[i].onclick) {
                        var script = 
                            this.stack[i].onclick
                                .replace(/\n/g, ' ')
                                .replace(/^\s+/, '')
                                .replace(/\"/g,"'");
                        link += 'onclick="'+script+'"';
                    } else {
                        link += 'onclick="return false"';
                    }
                    link += '>' + this.stack[i].label + '</a>';
                    html[html.length] = link;
                }
                html[html.length] = '</div>';
            }
            html[html.length] = '</div>';
                
            this.container.innerHTML = html.join(' ');
            this.container.style.display = 'block';
        }
        this.set(folderName, position, onclick);
    }
}

FolderStack.stack = new Array();

/**
 * Draws the current folder list.
 *
 * First initialized by the first call to FolderStack.set()
 */
FolderStack.render = function () {
    return false;
}
 
var folderId = 0;
function createFolder(folder, openFolderId, alternatives) {
    var containerDiv = $('foldersFoldersContainer');
    var foldersContainerDiv = $('foldersContainer');

    folderId += 1;
    var newDiv = 'div'+folderId;
    if ($(newDiv)) {
        // target div already exists!
        return false;
    }

    // these three lines cause the div to scroll to top onclick
    // var html = foldersContainerDiv.innerHTML;
    // html += '<div id="' + newDiv + '" class="folder"></div>';
    // foldersContainerDiv.innerHTML = html;
    var elNewDiv = document.createElement('div');
    elNewDiv.id = newDiv;
    elNewDiv.className = "folder";
    foldersContainerDiv.appendChild(elNewDiv);
    

    // adjust width of folder container to prevent horizontal scrollbar
    // if there aren't enough folders visible to justify one
    var nDivs = foldersContainerDiv.getElementsByTagName('div').length;
    //foldersContainerDiv.style.width = (Math.min(nDivs * 350, 645)) + 'px';

    // allow horizontal scrollbar to appear if necessary
    //foldersContainerDiv.style.overflowX = 'auto';

    new Ajax.Updater(
        newDiv, 
        Paths.www + '/mycatalogue/getFolders', 
        {
            method: 'get', 
            evalScripts: true, 
            parameters: {
                depth: folderId, 
                folder_id: folder, 
                open_folder_id: openFolderId,
                alternatives: alternatives
            },
            onSuccess: function() {
                if (!MyUnisource.Catalogue.foldersLoaded) {
                    MyUnisource.Catalogue.fire(MyUnisource.Catalogue.Event.FOLDERS_LOADED);
                    MyUnisource.Catalogue.foldersLoaded = true;
                }
            }
        }
    );
    return false;
}

/**
 * Function called whenever a folder is clicked.
 *
 * @param integer afterDiv The numeric position in the tree of the current div
 * @param string folder The id of the folder
 * @param string folderOpen The id of the folder being opened
 * @param string folderColor The color of the folder
 * @param void anchor ???
 */
function updateFolderList(afterDiv, folder, folderOpen, folderColor, anchor) {
    var divName = 'div'+afterDiv;
    if ($(divName) == null) {
    	location.href = Paths.www + '/my_unisource/catalogue?depth=0&folder_id='+folder+'&dom_id=myCatFolder'+folder+'&color='+escape(folderColor);
    } else {                        
        clearDivs(afterDiv);        
        createFolder(folder, false);
        openFolder(afterDiv, folder, folderOpen, folderColor);                           
        if (anchor && $(anchor)) {
            $(anchor).scrollTo();
        }

        return false;
    }
}

/**
 * Displays products for a given folder id.
 *
 * @access public
 * @param string folder The folder id
 * @param string alternatives Show alternatives? 'true' or 'false'
 * @param boolean showAll Indicates whether to show all products instead of pages
 */
function updateProductList(folder, alternatives, showAll) {
   

    MyUnisource.Catalogue.fire(MyUnisource.Catalogue.Event.PRODUCTS_LOADING);    

    Products.Listing.retainAll();
    if ($('product-listing-container')) {
        $('product-listing-container').update('');
    }
    productInquiry.fire(ProductInquiry.Event.PRODUCT_LISTING_REMOVED);
    
    showAll = showAll || false;
    
    var topLink = $("go-to-top-link");
    // The function responsible for displaing / hiding the view button
    Products.Listing.onLoad = function (listing) {

        // Remove back-to-top link if we have 10 or less products
        if (topLink) {
            if (listing.productIds.length > 9) {
                topLink.show();
            } else {
                topLink.hide();
            } 
        }
        
        // Resets the function
        Products.Listing.onLoad = function (listing) { 
                return false; 
            }
    }
    
    var completeFn = function () {        
        window.setTimeout( Products.Listing.restoreAll, 10 );
        window.location.hash = 'folder-listing-top';
        if (topLink) {
            topLink.hide();
        }
    }   
    var updateURL = productInquiry.getUrl('/mycatalogue/getFolderProducts/' + (showAll ? '-1' : '1'));
    
    var parameters    = {}
    if (folder)       parameters.folder_id = folder;
    if (alternatives) parameters.alternatives = alternatives;
    
    new Ajax.Updater('productListing', updateURL, {
        method: 'get', 
        evalScripts: true, 
        parameters: parameters,
        onSuccess : function() {
            MyUnisource.Catalogue.fire(MyUnisource.Catalogue.Event.PRODUCTS_LOADED);          },
        onComplete: completeFn
    });
}

/**
 * Action called by the 'view all' button
 *
 * @access public
 */
function showAllProducts() {
    updateProductList(false, false, true);
}

function getAlternatives(product_id){
    if(product_id){
        showAlternatives(
            Paths.www + '/UniProducts/getAlternativesContacts/', 
            product_id, 
            'folders-product-alternatives-container'
        );
    }
}

/**
 * Opens a folder
 *
 * @param integer depth The numeric depth of the folder, starting at 1
 * @param string The id of the folder
 * ...
 */
function openFolder(depth, folder, folderOpen, color, alternatives) {
    var folderColor;
    var a;
    var row;
    var col;

    depth = Number(depth);
    
    var foldersContainer = $('foldersContainer');
    if (!foldersContainer.maxDepth || foldersContainer.maxDepth < depth) {
        foldersContainer.maxDepth = depth;
    }
    var width = ((foldersContainer.maxDepth + 1) * 350)
    $('foldersContainer').style.width = ((width < 740) ? 740 : width) + 'px';;
    // close all folders at this depth
    var divName = 'div'+depth;
    var folders = $(divName).getElementsByTagName('li');    
    for (var i=0; i<folders.length; i++) {
        var folderItem = $(folders[i]);
        if (folderItem.hasClassName('open')) {
            folderItem.removeClassName('open');
            folderItem.addClassName('closed')
            
            var image = $(folderItem.id + '-image');
            image.src = image.src.replace('opened', 'closed');        
            break;
        }
    }
    
    
    // now open the selected folder
    var folderOpenElement = $(folderOpen)
    if(folderOpenElement) {
        $('foldersFoldersContainer').scrollToElement(folderOpenElement, [true, false]);
        folderOpenElement.removeClassName('closed');
        folderOpenElement.addClassName('open');
        
        var image = $(folderOpen + '-image');
        image.src = image.src.replace('closed', 'opened');   

        // Retrieves the label of the folder and pushes it onto the stack
        var label = $(folderOpen + '-label');
        FolderStack.set(label.innerHTML, depth, folderOpenElement.onclick.getBody());
    
        updateProductList(folder, alternatives);
    }
    
    return false;
}

function clearDivs(afterDiv) {
    if (afterDiv < 1) {
        return false;
    }
    var divName;
    var divRef;
    var folderCount = $('foldersContainer').getElementsByTagName('div').length;
    for (var i=afterDiv+1; i<=folderCount; i++) {
        divName = 'div'+i;
        divRef = $(divName);
        if (divRef != undefined) {
            divRef.parentNode.removeChild(divRef);
        }
    }
    folderId = afterDiv;
    if (folderId < 0) {
        folderId = 0;
    }
    return false;
}



/**
*   Products Lookup scripts
*/



var currentVendorId;

/**
*   Update Root Container block
*/
function updateRootContainer(containerId, url, selected_id) {
    //alert('updateRootContainer('+containerId+', '+url+')');
    // Find the target container
    var container = $(containerId);
    // If not found, don't even bother
    if(!container){
        //alert('no container!')
        return;
    }
    // Do not refill it again if not empty
    if(container.length > 0){
        //alert('not empty');
        return;
    }
        
    var result = new Ajax.Request(url,
                    {
                        method: 'get',
                        evalScripts: true,
                        onSuccess: function (transport) {
                            var response = transport.responseText;
                            //alert('response: ' + response);
                            eval(response);

                            var html='';
                            // Clean it up
                            container.length = 0;
                            
                            var option = null;
                            //alert('ids.length: ' + ids.length);
                            
                            //alert('ids[0]: ' + ids[0] + '; desc[0]: ' + desc[0]);
                            var selectedIndex = -1;
                            for (var i = 0; i < ids.length; i++) {
                                option = new Option(desc[i], ids[i], 'TRUE');
                                container.options[container.options.length] = option;
                                
                                if(selected_id == ids[i]){
                                    selectedIndex = i;
                                }
                            }
                            // This is a workaround for FF which is selecting the last item by default
                            container.selectedIndex = selectedIndex;
                        }
                    }
    );
    return false;
} 


/**
*  Initialize the tabs - make them 'eliminate' the listing when clicked
*/
function setCleaners(){

    var tabs = $$('ul.tabs li');
    for(var i = 0, len = tabs.length; i < len; i++){
        tabs[i].observe('click', cleanSelects);
    }
}

/**
*   Find the listing containers and clean them
*/
function cleanContainers(){
    var productListingContainer = $('product-listing-container');
    var productAlternativesContainer = $('product-alternatives-container');
    
    if(!productListingContainer || !productAlternativesContainer)
        return;
        
    productListingContainer.innerHTML = '';
    productAlternativesContainer.innerHTML = '';
    productInquiry.fire(ProductInquiry.Event.PRODUCT_LISTING_REMOVED);
}
/**
*   Unselect all the SELECT elements of the class 'search-by-category';
*   clean containers
*/
function cleanSelects(){
    var els = $$('select.search-by-sub-category');
    var len = els.length;
    for(var i = 0; i < len; i++){
        els[i].selectedIndex = -1;
    }
    
    cleanContainers();
}

ProductInquiry = Class.create();

ProductInquiry.DEFAULT_SOURCE = 'UniProducts';
ProductInquiry.Event = {
    LOADING : 'loading',
    LOADED : 'loaded',
    PRODUCT_LISTING_REMOVED : 'product-listing-removed'
};

ProductInquiry.prototype = {
    source: null,
    webroot: null,
    listingContainer : $('product-listing-container'),
    listingContainerId : 'product-listing-container',
    
    initialize : function() {
        this.source = ProductInquiry.DEFAULT_SOURCE;
        this.webroot = Paths.www;
        new EventHandler(this);
    },
    
    setWebroot : function(webroot) {
        this.webroot = webroot;
    },

    setSource : function(source) {
        this.source = source;
    },
    
    getUrl: function(partialUrl) {
        return this.webroot + partialUrl + '?source=' + this.source;
    },
    
    setListingContainer : function(listingContainer) {
        this.listingContainer = $(listingContainer);
        this.listingContainerId = this.listingContainer.id;
    },
    
    /**
    *   Update the listing
    */
    findProducts: function(categoryId, status, vendorId) {
        categoryId = categoryId || 'null';
        status     = status     || 'null';
        vendorId   = vendorId   || 'null';
        
        Products.Listing.retainAll(); 
        
        this.listingContainer = $(this.listingContainerId);
        
        this.fire(ProductInquiry.Event.LOADING);
        // TODO: Remove this band-aid
        if ($('productListing')) {
            $('productListing').update('');
        }
        
        new Ajax.Updater(
                    this.listingContainer,
                    this.getUrl('UniProducts/findProductsByCategory/' + categoryId + '/' + status + '/' + vendorId),
                    {
                        method: 'get',
                        evalScripts: true,
                        onComplete : function() {
                            this.fire(ProductInquiry.Event.LOADED);
                            window.setTimeout(
                                Products.Listing.restoreAll,
                                10
                            );
                        }.bind(this)
                    }
        );
        return false;
    }
}

window.productInquiry = new ProductInquiry(); 
 
/**
 * Product Lookup class creates the navigation necessary
 * to lookup products based on the category or vendor
 *
 * @param String container1
 * @param String container2
 * @param String container3
 * @param String webroot The root of the site
 */
var ProductLookup = Class.create();
ProductLookup.prototype = {
    /**
     * The webroot
     */
    webroot: '',
    /**
     * Default constructor
     */ 
    initialize: function (webroot) {
        this.webroot = webroot || window.Paths.www + '/';
    },
    /**
     * Retrieves all categories
     *                                                                 
     * @param Node into The container to recieve the list
     * @param Function onClick Function called when a category was clicked
     * @param Function onLoad Function called when the list is done loading
     */
    findAllCategories: function (into, onClick, onLoad) {
        var firstLetter = firstLetter || 'null';
        var url         = this.webroot + 'UniCategories/listAllForProducts/top';
        ProductLookup.buildList(url, into, 'category', onClick, onLoad);
        return false;
    },
    /**
     * Retrieves all new categories                    
     *     
     * @param Node into The container to recieve the list
     * @param Function onClick Function called when a category was clicked
     * @param Function onLoad Function called when the list is done loading
     */ 
    findAllNewCategories: function (into, onClick, onLoad) {
        var url = this.webroot + 'UniCategories/listAllForProducts/top/new';
        ProductLookup.buildList(url, into, 'category', onClick, onLoad);
        return false;
    },
    /**
     * Retrieves all clearance categories                    
     *     
     * @param Node into The container to recieve the list
     * @param Function onClick Function called when a category was clicked
     * @param Function onLoad Function called when the list is done loading
     */ 
    findAllClearanceCategories: function (into, onClick, onLoad) {
        var url = this.webroot + 'UniCategories/listAllForProducts/top/clearance';
        ProductLookup.buildList(url, into, 'category', onClick, onLoad);
        return false;
    },
    /**
     * Retrieves all categories for a manufacturer                    
     *     
     * @param Number manId The manufacturers id
     * @param Node into The container to recieve the list
     * @param Function onClick Function called when a category was clicked
     * @param Function onLoad Function called when the list is done loading
     */ 
    findAllCategoriesForManufacturer: function (manId, into, onClick, onLoad) {
        var url = this.webroot + 'UniCategories/listAllForProducts/top/null/' + manId;
        ProductLookup.buildList(url, into, 'category', onClick, onLoad);
        return false;
    },
    /**
     * Retrieves a list of sub-categories
     *
     * @param Number parentId The id of the parent category
     * @param String status The status of the products
     * @param Number manId The id of the manufacturer                
     * @param Node into The container to recieve the list
     * @param Function onClick Function called when a category was clicked
     * @param Function onLoad Function called when the list is done loading 
     */
    findAllSubCategories: function(parentId, status, vendor, into, onClick, onLoad) { 
        // var parentId = parentId || 'null';
        var status   = status   || 'null';
        var vendor   = vendor   || 'null';
        
        var url = this.webroot + 'UniCategories/listAllForProducts/' + parentId + '/' + status + '/' + vendor;
        ProductLookup.buildList(url, into, 'category', onClick, onLoad);
        return false;
    },
    /**
     * Returns a list of subcategories for products
     * available to the user starting with the passed first
     * letter. If the letter is the number one (1), then
     * only categories not starting with a letter are returned.
     *
     * @param String $firstLetter The first letter
     * @param Function onClick Function called when a category was clicked
     * @param Function onLoad Function called when the list is done loading  
     */
    findSubCategories: function(firstLetter, into, onClick, onLoad) {
        var firstLetter = firstLetter || 'a';
        var url         = this.webroot + 'UniCategories/listSubCategoriesForProducts/' + firstLetter;            
        ProductLookup.buildList(url, into, 'category', onClick, onLoad);
        return false;
    }, 
    /**
     * Retrieves all manufacturers
     *
     * @param String firstLetter The first letter of the vendors
     * @param Node into The container to receive the list
     * @param Function onClick Called when a vendor is clicked
     * @param Function onLoad Called when the list has loaded
     */
    findAllManufacturers: function (firstLetter, into, onClick, onLoad) {
        var firstLetter = firstLetter == '#' ? '1' : firstLetter;
        var url         = this.webroot + 'UniVendors/listAllForProducts/' + firstLetter;
        ProductLookup.buildList(url, into, 'vendor', onClick, onLoad, true);
        return false;
    }
}                                  
/**
 * Selects an item within a container.
 *
 * @param String|Node container The container
 * @param String id The id of the item
 * @return Node Returns the node found
 */
ProductLookup.selectItem = function (container, id) {               
    var found = null;
    var lis = $(container).getElementsByTagName('li');
    // do not use getElementById because of possible duplication
    for (var i = 0; i < lis.length; i++) {                          
        if (lis[i].id == id) { 
            found = lis[i];
            ProductLookup.onClickList(found);
            break;
        }
    }
    return found;
}
/** 
 * Triggers the clicking of a list item
 *
 * @param Node item The item clicked
 * @param Event e The event that triggered the clicking
 */
ProductLookup.onClickList = function (li, e) { 
    if (typeof li.tagName == 'undefined') {
        // this is an event
        e  = li;
        li = Event.findElement(e, 'li');
    }                   
    if (!li) return;
    ul = li.parentNode;                                        
    
    if (!ul) return;
    var lis   = ul.getElementsByTagName('li');
    var index = 0;
    for (var i = 0; i < lis.length; i++) {
        if (lis[i].tagName && lis[i].className) {
            $(lis[i]).removeClassName('selected');
        }
        if (typeof lis[i].id != 'undefined' && lis[i].id == li.id) {
            index = i;
        }
    }                
    $(li).addClassName('selected');
    
    // scrolls the ul container. only used when called directly, i.e. no e
    if (!e && index > 0) {
        var liHeight = Element.getHeight(li);
        var liBottom = li.offsetTop - li.parentNode.offsetTop + liHeight;
        if (liBottom > Element.getHeight(ul)) {
            ul.scrollTop = liBottom - liHeight;
        }
    }    
    if (e && ul.onItemClick) {
        var id = li.id.split('_').pop();
        if (id) {
            ul.onItemClick(id, e);
        }    
    }                 
    if (e) {
        Event.stop(e);
    }
}  
/**
 * Makes a list a selectable list
 *
 * @param Node list The list to make selectable
 * @param Function onClick The function to call when an element is clicked
 */
ProductLookup.makeSelectable = function (list, onClick) {
    list.onItemClick = onClick;            
    Event.observe(list, 'click', ProductLookup.onClickList); 
}
/**
 * Builds a list.
 * 
 * The list is then inserted into the intoContainer with each 
 * element having the id of the type plus their numeric id.
 *
 * The callback function is called when a list item is selected
 * and it is passed the id of that item.
 *
 * @param String fromURL 
 * @param String|Node intoContainer
 * @param String type
 * @param Function callback
 */     
ProductLookup.buildList = function(fromURL, intoContainer, type, callback, onLoad, multiId) {
    var success = function (request) {  
        var response = {};
        if (multiId) {
            response = eval('(' + request.responseText + ')');
         
            if (!response) {
                response = {
                    ids:  [],
                    desc: []
                }
            }     
        } else {
            eval(request.responseText);  
            response.ids = ids;
            response.desc = desc;
        }   
        var container = $(intoContainer); 

        // builds the list   
        var listItems = new Array(response.ids.length);
        for (var i = 0;i<response.ids.length;i++) {
            listItems[i] = '<li id="' + type + '_' + ProductLookup.convertIdToString(response.ids[i]) + '"><a href="#">' + response.desc[i] + '</a></li>';
        }                  
        container.innerHTML = '<ul>' + listItems.join('\n') + '</ul>';
        var list = container.firstChild;  
        
        ProductLookup.makeSelectable(list, callback);  
        
        if (onLoad && typeof(onLoad) == 'function') {
            onLoad();
        }                             
    };
    var params = {method: 'get', evalScripts: true, onSuccess: success, onException: function(t,e) {throw e;}};
    var result = new Ajax.Request(fromURL + '?json', params);
}; 

ProductLookup.convertIdToString = function(id) {
    var result = '';
    if (id instanceof Array) {
        result = id.join(',');
    } else {
        result = id;
    }
    return result;
};

/**
*   [END] Products Lookup scripts
*/

/**
*   Click Submit button onEnter
*/
function submitOnEnter(button_id, event){
    if(event && event.keyCode == 13){
        var b = $(button_id);
        if(b){
            b.click();
        }
    }
}                              

UniException = Class.create();
UniException.PREFIX = "Unisource Runtime JS Exception: ";


UniException.prototype = {
    initialize : function(message) {        
        this.message = UniException.PREFIX + message;
    }
}

EmptyElementException = Class.create();
EmptyElementException.PREFIX = "Empty element: ";

EmptyElementException.prototype = Object.extend(new UniException(),
    {
        initialize : function(element) {
            this.element = element;
            UniException.prototype.initialize.apply(
                this, 
                [EmptyElementException.PREFIX + element]
            );
        }
    }
);

UniDebug = Class.create();
UniDebug.output = function(object) {
    var objectString;
    $H(object).each(
        function(entry) {
            objectString += entry.key + ' = ' + entry.value + ";\n"
        }
    );
    return objectString
}

UniDebug.write = function(text) {
	var textNode = document.createTextNode(text);
	var lineBreak = document.createElement('br');
	var console = $('script-debug');
	console.appendChild(textNode);
	console.appendChild(lineBreak);
}

/**
    Update the main menu if needed - 'turn on' the item, specified by the page
*/
function updateMainMenu(page) {
    // First try to find the new item
    var flag_found = false;
    for(var i = 1; $('dynamic-submenu-' + i + '-div'); i++) {
        var tmp_item  = $('dynamic-submenu-' + i + '-div');
        //alert('getAttribute: ' + tmp_item.getAttribute('page'));
        if(tmp_item.getAttribute('page') == page){
            flag_found = true;
            break;
        }
    }
    // if not found, do nothing
    if(!flag_found)
        return;
    
    // Turn off all the items, except the current one
    for(var i = 1; $('dynamic-submenu-' + i + '-div'); i++) {
        
        var tmp_item  = $('dynamic-submenu-' + i + '-div');
        if(tmp_item.getAttribute('page') == page){
            // Turn on the current one
            tmp_item.className = 'dynamic-submenu-current-link-off';
        }else{
            tmp_item.className = 'dynamic-submenu-link-off';
        }
    }
    
}

/*******************************************************
 * Form and usability functions
 *******************************************************/
 
var UniForm = {};
/**
 * Test for the Safari Web Brower
 */
UniForm.safari = navigator.appVersion.match(/WebKit/i);
/**
 * Function initializes the UniForm component.
 */
UniForm.initialize = function () {
    if (UniForm.safari) {
        UniForm.ajaxReponders.onComplete();
        Ajax.Responders.register(UniForm.ajaxReponders);
    } else {
        Event.observe(window, 'load', function () {
            UniForm.ajaxReponders.onComplete();
            Ajax.Responders.register(UniForm.ajaxReponders);
        });
    }
}
/**
 * Ajax Event responders
 */
UniForm.ajaxReponders = {
    onComplete: function () {
        UniForm.makeSelectInput();    
        UniForm.organizeTabbing();
    }   
}
/**
 * Function applies to all text inputs a "select all
 * on focus" model. If the container is passed, only
 * the inputs from the container are given the event
 * handler.
 *
 * @access public
 * @param Node container Optional container in which
 *                       to look for the input elements
 * @return void
 */
UniForm.makeSelectInput = function(container) {  
    if (!UniForm.safai) {
        UniForm.makeSelectInput = function (container) {
            var inputs = (container || document).getElementsByTagName('input');
            for (var i = 0; i < inputs.length; i++) {
                var input = inputs[i];
                if (input.inputTagged)
                    continue;
                var type = (input.type || 'text').toLowerCase();
                if (type == 'text' || type == 'password') {
                    Event.observe(input, 'focus', UniForm.onInputFocus);
                    input.inputTagged = true;
                }
            }
        }
        UniForm.makeSelectInput(container);
    } else {
        return false;
    }
}      
/**
 * Private function responsible for handling the 
 * onFocus of an input field.
 *
 * @access public
 * @return void
 */          
UniForm.onInputFocus = function(e) {
    var target = Event.element(e);
    target.select();
}
/**
 * Function organizes the tabbing between HTML elements
 * in an appropriate order within a form.
 *
 * @access public
 * @return void
 */
UniForm.organizeTabbing = function() {
    if (!UniForm.safari) {
        UniForm.organizeTabbing = function () {
            var forms    = document.getElementsByTagName('form');
            var tabindex = 100;
            for (var i = 0; i < forms.length; i++) {
                var form      = forms[i];      
                var els       = UniForm.getInputs(form);
                var usedRadio = {};
                for (var ii = 0; ii < els.length; ii++, tabindex++) {
                    if (   els[ii].type
                        && els[ii].type == 'radio'
                        && (!els[ii].getAttribute('name') || !usedRadio[els[ii].getAttribute('name')])) {
                        els[ii].setAttribute('tabIndex', tabindex);
                        usedRadio[els[ii].getAttribute('name')] = true;
                    } else if (!els[ii].type || els[ii].type != 'hidden') {
                        els[ii].setAttribute('tabIndex', tabindex); 
                    }          
                }
                form.tabsOrganized = true;
            }
        }
        UniForm.organizeTabbing();
    } else {
        return false;
    }
}
/**
 * Public function that returns all input fields
 * for a given for node in their appearing order.
 *
 * @access public
 * @param Node form The form node
 * @return void
 */
UniForm.getInputs = function (form) {
    var elements = $A(form.elements);
    var inputs   = form.getElementsByTagName('input');
    for (var i = 0; i < inputs.length; i++) {
        if (inputs[i].type && inputs[i].type == 'image') {
            elements.push(inputs[i]);
        }
    }    
    var imgs = form.getElementsByTagName('img');
    for (var i = 0; i < imgs.length; i++) {
        if (imgs[i].className && imgs[i].className == 'button') {
            elements.push(imgs[i]);
        }
    }                                                                               
    return elements;
}

/**
* Sets the time to midnight without changing the date
*
*/
Date.prototype.setToMidnight = function() {
    this.setHours(0);
    this.setMinutes(0);
    this.setSeconds(0);
    this.setMilliseconds(0);
}


/**
* Adds the specified number of days to this date without
* changing the time
*
* @param Number days the number of days to add
*/
Date.prototype.addDays = function(days) {
    this.setDate(this.getDate() + days); 
}

/**
* Determines whether thius date occurs before the specified date
*
* @param Date date the date to which this date will be compared
* @return Boolean
*/
Date.prototype.isBefore = function(date) {
    return this.getTime() < date.getTime();
}

/**
* Determines if this date occurs AT OR AFTER the specified date
*
* @param Date date the date to which this date will be compared
* @return Boolean
*/
Date.prototype.isAfter = function(date) {
    return this.getTime() >= date.getTime();
}

/**
* Determines if this date occurs at or after [today] + [days] days
*
* @param Number days the number of days to add
* @return Boolean
*/
Date.prototype.isAfterDayCount = function(days) {
    var date = new Date();
    date.addDays(days);
    date.setToMidnight();
    return this.isAfter(date);
}

/**
* Determines if this date occurs tomorrow at midnight or later
*
* @return Boolean
*/
Date.prototype.isAfterTomorrow = function() {
    return this.isAfterDayCount(1);
}

/**
* Returns the next date following the current date that
* satisfies the specified predicate.
*
* @param Function predicate the predicate to check
*/
Date.prototype.getNextDate = function(predicate) {
    var date = new Date(this);
    while(!predicate(date)){
        date.addDays(1);
    }
}

Date.padLeft = function(string, length, character) {
    var result = string;
    while(result.length < length) {
        result = character + result;
    } 
    
    return result;
}

Date.prototype.toISODate = function() {
    var isoDate = 
        this.getFullYear() + '-' +
        Date.padLeft((this.getMonth() + 1).toString(), 2, '0') + '-' +
        Date.padLeft(this.getDate().toString(), 2, '0');
    return isoDate;
}

UniAjax = Class.create();


UniAjax.hidePopups = function(transport) {
	UniAjax.nextPopupHidden = true;
}

window.defaultAjaxResponder = { 
    timeout: null,
    onCreate: function(event) {
    	if (UniAjax.nextPopupHidden) {
    		UniAjax.nextPopupHidden = false;
		} else {
        	window.defaultAjaxResponder.showPopup(event);
		}
    },
    onComplete: function(requester, transport) {
        window.defaultAjaxResponder.hidePopup(requester, transport);
    },
    onException: function(event,exception) {
        window.defaultAjaxResponder.hidePopup(event);
        throw(exception);                                           
    },
    
    showPopup: function (event) {
        if (this.timeout != null) {
            clearTimeout(this.timeout);
            this.timeout = null;
        }   
        if ($('ajax-indicator').unipopup.hidden()) {   
            $('ajax-indicator').unipopup.show(event);
        }  
    },
    
    hidePopup: function (requester, transport) { 
        if (transport && transport.responseText == 'Login Required') {
            window.location.href = Paths.www;
        } else if ($('ajax-indicator').unipopup.visible()) {
            if (Ajax.activeRequestCount == 0) {
                $('ajax-indicator').unipopup.hide(requester);
            } else {
                if (this.timeout != null) {
                    clearTimeout(this.timeout);
                    this.timeout = null;
                }   
                this.timeout = setTimeout(function () { window.defaultAjaxResponder.hidePopup(requester, transport) }, 750);
            }
        }
    }
}
Ajax.Responders.register(defaultAjaxResponder);

function MM_preloadImages() { //v3.0
    var d = document;
    if(d.images){
        if(!d.MM_p)
            d.MM_p = new Array();
    var i, j = d.MM_p.length, a = MM_preloadImages.arguments;
    for(i=0; i<a.length; i++)
        if (a[i].indexOf("#") != 0){
            d.MM_p[j] = new Image;
            d.MM_p[j++].src=a[i];
        }
    }
}


Toggle = Class.create(
    {
        initialize : function(id, texts) {
            this.id = id;            
            this.texts = texts;
            this.expanded = false;                        
            if ($(id)) {
                this.setup();
            } else {
                Event.observe(
                    window,
                    'load',
                    this.setup.bind(this)
                );
            }            
        },
        
        setup : function() {
            this.target = $(this.id);
            this.link = $(this.id + '-toggle');
            this.image = $(this.id + '-arrow');
            
            this.target.hide();
            this.attachEvents();
        },
        
        attachEvents : function() {
            Event.observe(
                this.link,
                'click',
                function(e) {
                    Event.stop(e);
                    this.toggle();
                }.bind(this)
            );                
        },
        
        toggle : function() {
            if (this.expanded) {
                this.collapse();
            } else {
                this.expand();
            }
        },
        
        expand : function() {
            this.target.expand();
            this.link.update(this.texts.collapse);
            this.expanded = true;
            this.image.src = Paths['img-base'] + 'arrow_down.gif';
        },
        
        collapse : function() {
            this.target.collapse();
            this.link.update(this.texts.expand);
            this.expanded = false;
            this.image.src = Paths['img-base'] + 'arrow_right.gif';
        }
    }
);

if (window.jQuery) {
    (function($) {
        $(
            function() {           
                $('ul.dynamic-menu li > div')
                    .click(
                        function(e) {                
                            $(this).find('> a').click();
                        }
                    )
                    .find('> a')
                        .click(
                            function(e) {                            
                                if ($(document).data('preview_mode')) {
                                    alert(window.iw_preview_mode_message);
                                    return false;
                                }
                                location.href = $(this).attr('href');                        
                                e.stopPropagation();
                            }
                        )                    
                    .end();
            }
        );
    })(jQuery);
}
