/* 
 This file was generated by Dashcode and is covered by the 
 license.txt included in the project.  You may edit this file, 
 however it is recommended to first turn off the Dashcode 
 code generator otherwise the changes will be lost.
 */

if (!window.dashcode) {
    dashcode = new Object();
}

//
// setupParts(string)
// Uses the dashcodePartsSpec dictionary, declared in the automatically generated file setup.js to instantiate 
// all the parts in the project.
//
dashcode.setupParts = function () {
    if (dashcode.setupParts.called) return;
    dashcode.setupParts.called = true;
    var partsToGetFinishLoading = [];

    // Set up data sources
    if (window.dashcodeDataSources && !dashcode.inDesign) {
        for (var id in dashcodeDataSources) {
            var specDict = dashcodeDataSources[id];
            var dataSource = dashcode.setupDataSource(id,specDict);
            
            if (dataSource)
                dataSource.registerWithName(id);
        }        
    }
    
    // Optimize the bindings for quick lookup
    // We do them all beforehand to ensure initing a container view
    // doesn't init without this done
    for (var id in dashcodePartSpecs) {
        dashcode.preProcessBindings(dashcodePartSpecs[id]);
    }
    
    // fallback for border-image in shapes
    if (!DC.Support.BorderImage) {
        var allShapes = dashcodePartSupport['imageBgParts'];
        for(var name in allShapes) {
            var info = allShapes[name];
            Element.set3PiecesBorderImage(document.getElementById(name), info[0], info[1], info[2]);
        }
    }
    
    for (var id in dashcodePartSpecs) {        
        var specDict = dashcodePartSpecs[id];
        var object = dashcode.setupPart(id,specDict.creationFunction,specDict.view,specDict);
        
        if (object && object.finishLoading) {
            partsToGetFinishLoading[partsToGetFinishLoading.length] = object;
        }

    }
    // Call finishedLoading callbacks.
    for (var i=0; i<partsToGetFinishLoading.length; i++) {
        partsToGetFinishLoading[i].finishLoading();
    }    
}


dashcode.setupPart = function(elementOrId,creationFunction,viewClass,specDict,relativeController){
    var object = null;
    var createFunc = window[creationFunction];
    var node = elementOrId;
    
    if (elementOrId.nodeType != 1/*Node.ELEMENT_NODE*/) {
        node = document.getElementById(elementOrId);
	}
    
    if (!node) {
        return null;
    }
    
    if (createFunc) {
        object = createFunc(node, specDict);
    } else {
        var viewClass = null;
        
        object = DC.View.fromNode(node);
        
        // Skip objects already initialized
        if (object)
            return object;
        
        if (specDict.view) {
            viewClass = eval(specDict.view)
        }
        
        if (dashcode.inDesign)
            dashcode.preProcessBindings(specDict);
                
        if (!viewClass)
            viewClass = DC.View.viewClassForNode(node, specDict.hasBindings) || DC.View;

        object = new (viewClass)(node, relativeController , specDict.propertyValues, specDict)
            
        node.object = object;
    }

    return object;
}

dashcode.setupDataSource = function(identifier,specDict)
{
    var dsClass = null;
    var dataSource = null;
    
    try{
        dsClass = specDict["Class"]?eval(specDict["Class"]):null;
    } catch (e){
    }
    
    if (!dsClass) {
        console.error("Couldn't create data source " + identifier + ". Invalid class specified.");

        return null;
    }
    
    var propertyValues = specDict["propertyValues"];
    
    // Instantiate the data source class. 
    dataSource = new dsClass(propertyValues);
    
    return dataSource;
}

dashcode.getDataSource = function(dataSourceName)
{
    return DC.dataModel.valueForKey(dataSourceName);
}

dashcode.preProcessBindings = function(partSpec)
{
    if (partSpec && partSpec.propertyValues && !partSpec.hasBindings) {
        for (p in partSpec.propertyValues)
        {
            if (-1!==p.search(/Binding$/)){
                partSpec.hasBindings = true;
                // in design mode, delete binding
                if (dashcode.inDesign) {
                    delete partSpec.propertyValues[p];
                } else {
                    break;
                }
            }
        }
    }
}

if (window.addEventListener)
    window.addEventListener('load', dashcode.setupParts, false);
else if (window.attachEvent)
    window.attachEvent('load', dashcode.setupParts);

//
// getLocalizedString(string)
// Pulls a string out an array named localizedStrings.  Each language project directory in this widget
// contains a file named "localizedStrings.js", which, in turn, contains an array called localizedStrings.
// This method queries the array of the file of whichever language has highest precedence, according to
// your preference set in the language toolbar item
//
// string: the key to the array
//
dashcode.getLocalizedString = function (string) {
    try { string = localizedStrings[string] || string; } catch (e) {}
    return string;
}

//
// createInstancePreferenceKey(key)
// Returns a unique preference key that is based on a instance of an opened widget.
// The returned value can then be used in widget.setPreferenceForKey()
// and widget.preferenceForKey() so that the value that is set or retrieved is
// only for a particular opened widget.
//
// key: preference key
//
dashcode.createInstancePreferenceKey = function (key) {
    return widget.identifier + "-" + key;
}

//
// getElementHeight(mainElement)
// Get the height of a part even if it's hidden (by 'display: none').
//
// mainElement: Part element
//
dashcode.getElementHeight = function (mainElement) {
    var height = mainElement.offsetHeight;
    
    if (!height || height == 0) {
        height = dashcode.getElementSize(mainElement).height;
    }
    
    return height;
}

//
// getElementWidth(mainElement)
// Get the width of a part even if it's hidden (by 'display: none').
//
// mainElement: Part element
//
dashcode.getElementWidth = function (mainElement) {
    var width = mainElement.offsetWidth;
    
    if (!width || width == 0) {
        width = dashcode.getElementSize(mainElement).width;
    }
    
    return width;
}

//
// getElementSize(mainElement)
// Get the size of a DOM element even if it's hidden (by 'display: none').
//
// mainElement: DOM element
//
dashcode.getElementSize = function (mainElement) {
    var sizes = dashcode.getElementSizesWithAncestor([mainElement], mainElement);
    return sizes[0];
}

//
// getElementSizesWithAncestor(elements, ancestor)
// Get the size of an array of DOM elements under a common ancestor even if they're hidden (by 'display: none').
//
// elements: Array of DOM element
// ancestor: Common DOM ancestor. 'display' will temporarily be flipped to 'block' for all hidden ancestors of this element.
//
dashcode.getElementSizesWithAncestor = function (elements, ancestor) {
    if (elements.length < 1) return [];

    var displayNoneElements = new Array();
    var width = elements[0].offsetWidth;
    
    if (!width || width == 0) {        
        var parentNode = ancestor;
        while (parentNode && (parentNode != document)) {
            var computedDisplay = Element.getStyles(parentNode, "display");
            var displayValue = (computedDisplay) ? computedDisplay : parentNode.style.display;        
            if ((computedDisplay && displayValue == "none") || (!computedDisplay && displayValue != "block")) {
                displayNoneElements.push({node:parentNode, display:parentNode.style.display});
                parentNode.style.display = "block";
            }
            parentNode = parentNode.parentNode;
        }
    }

    var sizes = new Array();    
    for (var i=0; i<elements.length; i++) {
        sizes.push({width: elements[i].offsetWidth, height: elements[i].offsetHeight});
    }

    for (var i=0; i<displayNoneElements.length; i++) {
        var element = displayNoneElements[i].node;
        element.style.display = displayNoneElements[i].display;
        // clean up
        if (element.getAttribute("style") == "") {
            element.removeAttribute("style");
        }
    }
    
    return sizes;
}

dashcode.getElementDocumentOffset = function(element)
{   
    var parent = element.offsetParent;
    var offset = {x:element.offsetLeft,y:element.offsetTop};
    
    if( parent ){
        var parentOffset = dashcode.getElementDocumentOffset(parent);
        
        offset.x += parentOffset.x;
        offset.y += parentOffset.y;
    }
    
    return offset;
}

dashcode.pointInElement = function (x,y,element)
{
    var size = dashcode.getElementSize(element);
    var origin = dashcode.getElementDocumentOffset(element);
    
    // Check horizontally
    if( x >= origin.x ){
        if( x > origin.x + size.width )
            return false;
        
        if( y >= origin.y ){
            if( y > origin.y + size.height )
                return false;
        }else
            return false;
    }else
        return false;
    
    return true;
}

//
// cloneTemplateElement(element, isTemplate)
// Clone an element and initialize the parts it contains. The new element is simply returned and not added to the DOM.
//
// element: element to clone
// isTemplate: true if this is the template element
//
dashcode.cloneTemplateElement = function (element, isTemplate, relativeController) {
    return DC.View.cloneViewsForTreeNode(element,relativeController,null);
}

//
// This Method is Deprecated
// processClonedTemplateElement(element, templateElements, isTemplate, preserveIds)
// Recursively process a newly cloned template element to remove IDs and initialize parts.
//
// element: element to process
// templateElements: list of references to template objects to populate
// isTemplate: true if this is the template element
// preserveIds: true to preserve the original id in a tempId attribute
//
dashcode.processClonedTemplateElement = function (element, templateElements, isTemplate, preserveIds, relativeController, bindController) {
    console.error("dashcode.processClonedTemplateElement is no longer available.");
}

// Old function names for backwards compatibility
var setupParts = dashcode.setupParts;
var getLocalizedString = dashcode.getLocalizedString;
var createInstancePreferenceKey = dashcode.createInstancePreferenceKey;
var getElementHeight = dashcode.getElementHeight;
var getElementWidth = dashcode.getElementWidth;
var getElementSize = dashcode.getElementSize;

if (!('querySelector' in document))
    document.write('<script apple-no-regeneration="yes" type="text/javascript" src="../Parts/core/external/sizzle_c.js"></script>');
