var facetPanels = [
];
var homePanelDom;
var viewPanelDom;
var lensPanelDom;
var currentPanelDom;
var windowWidth = window.innerWidth;

function createIPhoneExhibit() {
    // Prime the history or else Safari doesn't behave correctly later on.
    SimileAjax.History.addLengthyAction(
        function() {},
        function() {},
        "Loaded"
    );
    
    window.database = Exhibit.Database.create();
    window.database.loadDataLinks(internalCreateIPhoneExhibit);
}

function internalCreateIPhoneExhibit() {
    window.exhibit = Exhibit.create();
    
    var uiContext = exhibit.getUIContext();
    var viewElmt = null;
    
    var node = document.body.firstChild;
    while (node != null) {
        if (node.nodeType == 1) {
            var role = Exhibit.getAttribute(node, "role");
            switch (role) {
            case "lens":
                Exhibit.UIContext.registerLensFromDOM(node, uiContext.getLensRegistry());
                break;
            case "facet":
                facetPanels.push({ originalNode: node });
                break;
            case "view":
                viewElmt = node;
                break;
            case "collection":
                var id = node.id;
                if (id == null || id.length == 0) {
                    id = "default";
                }
                window.exhibit.setCollection(id, Exhibit.Collection.createFromDOM2(id, node, uiContext));
                break;
            default:
                node.style.display = "none";
            }
        }
        node = node.nextSibling;
    }
    
    /*
     *  Create facet panels
     */
    
    for (var i = 0; i < facetPanels.length; i++) {
        var record = facetPanels[i];
        
        record.originalNode.setAttribute("ex:scroll", "false");
        record.originalNode.parentNode.removeChild(record.originalNode);
        
        var panel = createPanelDiv();
        var panelDom = SimileAjax.DOM.createDOMFromString(
            panel,
            "<div id='panelHeader' class='panel-header'>" +
                "<h1 id='panelTitle'></h1>" +
                "<span id='backButton' class='back-button' href='#' onclick='goBack()'>home</span>" +
            "</div>" +
            "<div id='panelBody'></div>",
            { panelBody: record.originalNode }
        );
        document.body.appendChild(panel);
        
        record.panelDom = panelDom;
        record.facet = Exhibit.UI.createFacetFromDOM(record.originalNode, null, uiContext);
        
        panelDom.panelTitle.innerHTML = getFacetLabel(record.facet);
    }
    
    /*
     *  Create the view panel
     */
    var insertDefaultLens = function() {
        var div = document.createElement("div");
        div.className = "iPhone-default-lens";
        div.setAttribute("ex:role", "lens");
        div.innerHTML = "<span ex:content='.label'></span>";
        viewElmt.appendChild(div);
    };
    if (viewElmt == null) {
        viewElmt = document.createElement("div");
        viewElmt.setAttribute("ex:role", "lens");
        insertDefaultLens();
    } else {
        var childNode = viewElmt.firstChild;
        while (childNode != null) {
            if (childNode.nodeType == 1 && Exhibit.getAttribute(childNode, "role") == "lens") {
                break;
            }
            childNode = childNode.nextSibling;
        }
        
        if (childNode == null) {
            insertDefaultLens();
        }
        
        viewElmt.parentNode.removeChild(viewElmt);
    }
    viewElmt.setAttribute("ex:showHeader", "false");
    viewElmt.setAttribute("ex:showAll", "true");
    viewElmt.setAttribute("ex:grouped", "false");
    viewElmt.setAttribute("ex:showToolbox", "false");
    
    var viewPanel = createPanelDiv();
    viewPanelDom = SimileAjax.DOM.createDOMFromString(
        viewPanel,
        "<div id='panelHeader' class='panel-header'>" +
            "<h1 id='panelTitle'>Results</h1>" +
            "<span id='backButton' class='back-button' href='#' onclick='goBack()'></span>" +
        "</div>" +
        "<div id='panelBody'></div>",
        { panelBody: viewElmt }
    );
    document.body.appendChild(viewPanel);
    var view = Exhibit.UI.createViewFromDOM(viewElmt, null, uiContext);
    var collection = window.exhibit.getDefaultCollection();
    view._listener.onItemsChanged = function() {
        if (collection.countRestrictedItems() < collection.countAllItems()) {
            view._reconstruct();
            slideForwardToView();
        } else {
            slideBackToFacet();
        }
    };
    
    /*
     *  Create the lens panel
     */
    var lensPanel = createPanelDiv();
    lensPanelDom = SimileAjax.DOM.createDOMFromString(
        lensPanel,
        "<div id='panelHeader' class='panel-header'>" +
            "<h1 id='panelTitle'></h1>" +
            "<span id='backButton' class='back-button' href='#' onclick='goBack()'>results</span>" +
        "</div>" +
        "<div id='panelBody'></div>"
    );
    document.body.appendChild(lensPanel);
    
    /*
     *  Create the home panel
     */
    var homePanel = createPanelDiv();
    homePanelDom = SimileAjax.DOM.createDOMFromString(
        homePanel,
        "<div id='panelHeader' class='panel-header'>" +
            "<h1 id='panelTitle'>" + SimileAjax.History._plainDocumentTitle + "</h1>" +
        "</div>" +
        "<div id='panelBody'></div>"
    );
    currentPanelDom = homePanelDom;
    
    document.body.appendChild(homePanel);
    
    homePanel.style.display = "block";
    var makeFacetLink = function(i) {
        var facetLink = document.createElement("div");
        facetLink.className = "facet-link";
        facetLink.innerHTML = getFacetLabel(facetPanels[i].facet);
        facetLink.onclick = function() {
            showFacet(i);
        };
        homePanelDom.panelBody.appendChild(facetLink);
    };
    for (var i = 0; i < facetPanels.length; i++) {
        makeFacetLink(i);
    }
}

function createPanelDiv() {
    var panel = document.createElement("div");
    panel.className = "panel";
    panel.style.width = window.innerWidth + "px";
    return panel;
}

function getFacetLabel(facet) {
    return facet._settings.facetLabel;
}

function findFacet() {
    for (var i = 0; i < facetPanels.length; i++) {
        var record = facetPanels[i];
        if (record.facet.hasRestrictions()) {
            return i;
        }
    }
    return -1;
}

function showFacet(index) {
    SimileAjax.History.addLengthyAction(
        function() { slideForward(facetPanels[index].panelDom); },
        function() { slideBackward(homePanelDom); },
        getFacetLabel(facetPanels[index].facet)
    );
}

var lastFacetIndex = -1;
function slideForwardToView() {
    lastFacetIndex = findFacet();
    if (lastFacetIndex >= 0) {
        viewPanelDom.backButton.innerHTML = getFacetLabel(facetPanels[lastFacetIndex].facet);
        slideForward(viewPanelDom);
    }
}

function slideBackToFacet() {
    if (lastFacetIndex >= 0) {
        slideBackward(facetPanels[lastFacetIndex].panelDom);
    }
}

function showLens(itemID) {
    var label = window.database.getObject(itemID, "label");
    label = (label != null) ? label : itemID;
    lensPanelDom.panelTitle.innerHTML = label;
    
    var div = lensPanelDom.panelBody;
    div.innerHTML = "";
    
    var uiContext = window.exhibit.getUIContext();
    uiContext.getLensRegistry().createLens(itemID, div, uiContext);
    
    SimileAjax.History.addLengthyAction(
        function() { slideForward(lensPanelDom); },
        function() { slideBackward(viewPanelDom); },
        label
    );
}

function goBack() {
    window.history.go(-1); // for Safari
}

function slideForward(newPanelDom, cont) {
    var top = window.scrollY;
    
    newPanelDom.elmt.style.left = windowWidth + "px";
    newPanelDom.elmt.style.top = top + "px";
    newPanelDom.elmt.style.zIndex = 10;
    newPanelDom.elmt.style.display = "block";
    
    SimileAjax.Graphics.createAnimation(
        function(current, change) {
            newPanelDom.elmt.style.left = current + "px";
            currentPanelDom.elmt.style.left = (current - windowWidth) + "px";
        }, 
        windowWidth, 
        0, 
        350, 
        function() {
            currentPanelDom.elmt.style.display = "none";
            newPanelDom.elmt.style.zIndex = 0;
            if (top > 0) {
                newPanelDom.elmt.style.top = "0px";
                window.scrollY = 0;
            }
            currentPanelDom = newPanelDom;
            
            if (typeof cont == "function") {
                cont();
            }
        }
    ).run();
}

function slideBackward(newPanelDom, cont) {
    var top = window.scrollY;
    
    newPanelDom.elmt.style.left = -windowWidth + "px";
    newPanelDom.elmt.style.top = top + "px";
    newPanelDom.elmt.style.zIndex = 10;
    newPanelDom.elmt.style.display = "block";
    
    SimileAjax.Graphics.createAnimation(
        function(current, change) {
            newPanelDom.elmt.style.left = current + "px";
            currentPanelDom.elmt.style.left = (current + windowWidth) + "px";
        }, 
        -windowWidth, 
        0, 
        350, 
        function() {
            currentPanelDom.elmt.style.display = "none";
            newPanelDom.elmt.style.zIndex = 0;
            if (top > 0) {
                newPanelDom.elmt.style.top = "0px";
                window.scrollY = 0;
            }
            currentPanelDom = newPanelDom;
            
            if (typeof cont == "function") {
                cont();
            }
        }
    ).run();
}

/*--------------------------------------------------
 * Overriding Exhibit
 *--------------------------------------------------
 */

Exhibit.UI.showBusyIndicator = function() {};
Exhibit.UI.hideBusyIndicator = function() {};

Exhibit.Functions["first-initial"] = {
    f: function(args) {
        var set = new Exhibit.Set();
        for (var i = 0; i < args.length; i++) {
            var arg = args[i];
            if (arg.size > 0) {
                arg.forEachValue(function (v) {
                    var s = v.toString();
                    if (s.length > 0) {
                        set.add(s.substr(0, 1).toLowerCase());
                    }
                })
            }
        }
        return new Exhibit.Expression._Collection(set, "text");
    }
};
Exhibit.Functions["last-name"] = {
    f: function(args) {
        var set = new Exhibit.Set();
        for (var i = 0; i < args.length; i++) {
            var arg = args[i];
            if (arg.size > 0) {
                arg.forEachValue(function (v) {
                    var s = v.toString();
                    if (s.length > 0) {
						var space = s.indexOf(" ");
                        set.add(space > 0 ? s.substr(space + 1) : s);
                    }
                })
            }
        }
        return new Exhibit.Expression._Collection(set, "text");
    }
};

Exhibit.TileView.prototype._reconstruct = function() {
    var view = this;
    var state = {
        div:            this._dom.bodyDiv,
        contents:       null,
        groupDoms:      [],
        groupCounts:    []
    };

    var closeGroups = function(groupLevel) {
        for (var i = groupLevel; i < state.groupDoms.length; i++) {
            state.groupDoms[i].countSpan.innerHTML = state.groupCounts[i];
        }
        state.groupDoms = state.groupDoms.slice(0, groupLevel);
        state.groupCounts = state.groupCounts.slice(0, groupLevel);

        if (groupLevel > 0) {
            state.div = state.groupDoms[groupLevel - 1].contentDiv;
        } else {
            state.div = view._dom.bodyDiv;
        }
        state.contents = null;
    }

    this._orderedViewFrame.onNewGroup = function(groupSortKey, keyType, groupLevel) {
        closeGroups(groupLevel);

        var groupDom = Exhibit.TileView.constructGroup(groupLevel, groupSortKey);

        state.div.appendChild(groupDom.elmt);
        state.div = groupDom.contentDiv;

        state.groupDoms.push(groupDom);
        state.groupCounts.push(0);
    };

    this._orderedViewFrame.onNewItem = function(itemID, index) {
        if (state.contents == null) {
            state.contents = Exhibit.TileView.constructList();
            state.div.appendChild(state.contents);
        }

        for (var i = 0; i < state.groupCounts.length; i++) {
            state.groupCounts[i]++;
        }

        var itemLensItem = document.createElement("li");
        itemLensItem.onclick = function() { showLens(itemID); };
        var itemLens = view._uiContext.getLensRegistry().createLens(itemID, itemLensItem, view._uiContext);
        state.contents.appendChild( itemLensItem );
    };

    this._div.style.display = "none";

    this._dom.bodyDiv.innerHTML = "";
    this._orderedViewFrame.reconstruct();
    closeGroups(0);

    this._div.style.display = "block";
};
