/*	
 Copyright 2013 Adobe Systems Incorporated.  All rights reserved. 

Purpose- 
This file has the implementation of some functions used in FluidGrid.js and FluidGridBridger
*/

/*jslint browser: true*/

function getFGUtil() {
    "use strict";
    
    var lookForSelectorInCSSRules = function (cssRules, selector, styleRule, mediaRule, devices) {
        if (!cssRules) {
            return false;
        }
        var length = cssRules.length,
            i = 0,
            foundRuleDefinition = false,
            hasMediaRules = false,
            mediaRuleHasDefinition = true,
            mediaRuleList = [cssRules];
    
        for (i = 0; i < cssRules.length; i += 1) {
            if (cssRules[i].type === mediaRule) {
                mediaRuleList.push(cssRules[i].cssRules);
            }
        }
        mediaRuleList = mediaRuleList.filter(function (mediaRule, index) { return devices.indexOf(index) !== -1; });
        
        if (mediaRuleList.length !== devices.length) {
            return false;
        }
        return mediaRuleList.every(function (mediaRuleElement) {
            var found = false;
            for (i = 0; i < mediaRuleElement.length; i += 1) {
                if (mediaRuleElement[i].type === styleRule) {
                    if (mediaRuleElement[i].selectorText === selector) {
                        found = true;
                    }
                }
            }
            return found;
        });
    },
    
        getIDSelector = function (theElement) {
            if (!theElement) {
                return null;
            }
            var selector,
                id = theElement.getAttribute ? theElement.getAttribute('id') : null;
            if (id) {
                selector = '#' + id;
                return selector;
            }
            return null;
        },
    
        isValidFluidSelector = function (selector, styleElementSheet, styleRule, mediaRule) {
            // Call this function when you are sure we have the latest css.
            var ValidFluidElement = lookForSelectorInCSSRules(styleElementSheet, selector, styleRule, mediaRule, [0, 1, 2]);
            return ValidFluidElement;
        },
        
        getValidFluidGridIDSelector = function (theElement, styleElementSheet, styleRule, mediaRule) {
            if (!theElement) {
                return null;
            }
            var selector = getIDSelector(theElement);
            if (selector && isValidFluidSelector(selector, styleElementSheet, styleRule, mediaRule)) {
                return selector;
            }
            return null;
        },
        
        getValidFluidGridClassSelector = function (theElement, styleElementSheet, styleRule, mediaRule) {
            if (!theElement) {
                return null;
            }
            var classList = theElement.className.split(/\s+/),
                selector,
                index;
            for (index in classList) {
                if (classList.hasOwnProperty(index) && classList[index]) {
                    if (classList[index] !== 'gridContainer') {
                        selector = '.' + classList[index];
                        if (isValidFluidSelector(selector, styleElementSheet, styleRule, mediaRule)) {
                            return selector;
                        }
                    }
                }
            }
            return null;
        },
        
        getValidFluidGridSelector = function (theElement, styleElementSheet, styleRule, mediaRule) {
            if (!theElement) {
                return null;
            }
            var selector = getValidFluidGridIDSelector(theElement, styleElementSheet, styleRule, mediaRule);
            if (!selector) {
                selector = getValidFluidGridClassSelector(theElement, styleElementSheet, styleRule, mediaRule);
            }
            return selector;
        },
        
        childElementNodesToArray = function (nodeList) {
            var list = [],
                i;
            for (i = 0; i < nodeList.length; i += 1) {
                if (nodeList[i].nodeType === 1) {
                    list.push(nodeList[i]); // push in only valid HTML Elements
                }
            }
            return list;
        },
        
        validFluidElement = function (theElement, styleElementSheet, styleRule, mediaRule) {
            if (!theElement) {
                return false;
            }
    
            if (typeof theElement === "undefined") {
                return false;
            }
    
            var selector = this.getValidFluidGridSelector(theElement, styleElementSheet, styleRule, mediaRule);
            if (selector) {
                return true;
            }
    
            return false;
        },
        
        getActiveViewScale = function () {
            return 1;
        },
        
        getValidLayoutDivWidths = function (colRects) {
            if (colRects.length === 0) {
                return [];
            }
            var firstColLeft = colRects[0].left,
                widths = [],
                width,
                colRect,
                i;
            for (i = 0; i < colRects.length; i = i + 1) {
                colRect = colRects[i];
                width = colRect.right - firstColLeft;
                widths.push(width);
            }
            return widths;
        },
        
        getColSpanFromOffsetWidth = function (offsetWidth, colRects) {
            // Called for snapping to nearest valid col span and for converting valid width to valid col span.
            var smallestDiff = 100000,
                nearestWidthIndex = -1,
                validWidths = getValidLayoutDivWidths(colRects),
                len = validWidths.length,
                i,
                validWidth,
                diff;
            for (i = 0; i < len; i = i + 1) {
                validWidth = validWidths[i];
                diff = Math.abs(validWidth - offsetWidth);
                if (diff < smallestDiff) {
                    nearestWidthIndex = i;
                    smallestDiff = diff;
                }
            }
            return nearestWidthIndex + 1;
        },
        
        sprintf = function (theStr) {
            var retVal = [],
                argc = arguments.length,
                nextIndString,
                splits,
                i,
                j = 0;
            if (argc > 0) {
                nextIndString = 1; // first replacement argument
                splits = theStr.split(/%[s|d]/);
                
                for (i = 0; i < splits.length; i += 1) {
                    //write out the split itself.
                    if (splits[i].length > 0 && !isNaN(splits[i].charAt(0))) {
                        retVal.push(splits[i].substring(1));
                        retVal[j] = retVal[j].replace(/^\s\s*/, '').replace(/\s\s*$/, '');
                        j += 1;
                    } else {
                        retVal.push(splits[i]);
                        retVal[j] = retVal[j].replace(/^\s\s*/, '').replace(/\s\s*$/, '');
                        j += 1;
                    }
                    
                    //Now write out the next string in the list. 
                    if (i < splits.length - 1) {
                        //Pick the next string out of the array.
                        retVal.push(arguments[nextIndString]);
                        nextIndString += 1;
                    }
                }
            }
            
            return retVal.join(" ");
        };
    
    return { lookForSelectorInCSSRules: lookForSelectorInCSSRules,
            getIDSelector: getIDSelector,
            isValidFluidSelector: isValidFluidSelector,
            getValidFluidGridIDSelector: getValidFluidGridIDSelector,
            getValidFluidGridClassSelector: getValidFluidGridClassSelector,
            getValidFluidGridSelector: getValidFluidGridSelector,
            childElementNodesToArray: childElementNodesToArray,
            validFluidElement: validFluidElement,
            getActiveViewScale: getActiveViewScale,
            getValidLayoutDivWidths: getValidLayoutDivWidths,
            getColSpanFromOffsetWidth: getColSpanFromOffsetWidth,
            sprintf: sprintf};
}