<%inherit file="//layout/base.html" />
<%namespace name="lib" file="//lib.html" import="*" />
<%!
import os
import logging
logger = logging.getLogger('splunk.appserver.templates.view')

successfullyRenderedPanels = {}
%>

<div class="layout">
    ${next.body()}
</div>
${next.custom_body()}
<%def name="make_app_url(path)" >
    <% return (make_url(['static', 'app', APP['id'], path]) if path[0]!='/' else make_url(path)) %>
</%def>

<%def name="title()">
    ${VIEW['label']} - ${APP['label']|h} - Splunk ${cherrypy.config.get('version_label')} ${cherrypy.config.get('build_number')}
</%def>

<%def name="head()">
    % if VIEW.get("refresh"):
	<META http-equiv="refresh" content="${VIEW['refresh']}"/> 
    % endif
</%def>

<%def name="body_element_open()">
    <body class="splTemplate-${os.path.split(self.filename)[-1].split('.')[0] | h} splView-${VIEW['id'] | h}" s:app="${APP['id']}" s:view="${VIEW['id']}" s:displayview="${VIEW['displayView']}" s:onunloadcanceljobs="${VIEW['onunloadCancelJobs']}" s:autocancelinterval="${VIEW['autoCancelInterval']}">
</%def>

<%def name="css()">
    <%coreCSSFiles = ["/static/css/view.css", "/static/css/jquery.autocomplete.css", "/static/css/skins/default/default.css", '/static/css/print.css'] %>
    <%lib:stylesheet_tags files="${coreCSSFiles}" />
    <%lib:stylesheet_tags files="${cssFiles}" />
</%def>

<%def name="custom_css()">
    <%lib:stylesheet_tags files="${customCssFiles}" />
    <%lib:stylesheet_tags files="${printCssFiles}" media="print"/>
</%def>

<%def name="js()">
    <%
    coreJsFiles = [
        
        # external packages
        "/static/js/contrib/lowpro_for_jquery.js",
        "/static/js/contrib/json2.js",
        "/static/js/contrib/swfobject.js",
        "/static/js/contrib/firebug.js",
        "/static/js/contrib/jquery-ui-1.7.2.custom.min.js",
        #"/static/js/contrib/jquery-ui-1.7.1.custom.min.js",
        "/static/js/contrib/jquery.ui.tablesorter.js",
        "/static/js/contrib/jquery.uitablefilter.js",
        "/static/js/contrib/jquery.bgiframe.min.js",
        "/static/js/contrib/jquery.cookie.js",
        "/static/js/contrib/jquery.form.js",
        "/static/js/contrib/jquery.autocomplete.pack.js",
    
        # TEMPORARY - we're still looking for something better than strftime
        "/static/js/contrib/strftime.js",
    
        # splunk packages
        "/static/js/logger.js",
        "/static/js/error.js",
        "/static/js/session.js",
        "/static/js/job.js",
        "/static/js/messenger.js",
        "/static/js/search_context.js",
        "/static/js/jobber.js",
        "/static/js/menu_builder.js",
        "/static/js/admin.js",
        "/static/js/time_range.js",
        "/static/js/module_loader.js",
        "/static/js/ja_bridge.js",
        "/static/js/legend.js",
        "/static/js/jquery.sparkline.js",
        "/static/js/popup.js",
        "/static/js/layout_engine.js",
        "/static/js/print.js",
        "/static/js/page_status.js",
        "/static/js/dev.js",
        "/static/js/window.js",
        "/static/js/field_summary.js",

        # Check for the CSRF token
        "/static/js/splunk.jquery.csrf_protection.js",

        # Check for the X-Splunk-Messages-Available flag and instruct the Messenger to update itself
        "/static/js/splunk.jquery.check_messages.js",

        # start up the system
        "/static/js/init.js",
    ]
    %>

    ## start: core js
    <%lib:script_tags files="${coreJsFiles}" />
    ## dynamic view dependency js
    <%lib:script_tags files="${jsFiles}" />
    
	<%
    params = {}
    paramConfig = {
        'sticky': {},
		'persistable': {}
    }

    # process every module
    for panelName in modules:
        for module in modules[panelName]:
            
            # generate module configuration dict
            params[module.get('id')] = module.get('params', dict())

            # output persistence data, if available
            if module['stickyParams']:
                paramConfig['sticky'][module['id']] = module['stickyParams']
            if module['persistableParams']:
                paramConfig['persistable'][module['id']] = module['persistableParams']
    %>
    ## required params js
    <script type="text/javascript">
    //<![CDATA[
    Splunk.Module.loadParams = ${jsonify(params)};
    Splunk.Module.paramConfig = ${jsonify(paramConfig)};
    
    // dropping current view config into a dict; probably could be further
    // optimized to place data directly with its consumer
    Splunk.ViewConfig = {
        'view': ${jsonify(VIEW)},
        'app': ${jsonify(APP)},
        'savedSearch': ${jsonify(SAVED)}
    }
    % if toBeResurrected:
        Splunk.toBeResurrected = ${json_decode(toBeResurrected)};
    % else:
        Splunk.toBeResurrected = null;
    % endif
    //]]>
    </script>

    ## buffered inline js
    <%lib:get_script_blocks />
</%def>

<%def name="buildModule(module)"><%
    attributesToEmit = {"id":1,"parentmodule":1,"autoRun":1}
    %>
    <div class="SplunkModule ${module['className']}"\
        % for configKey in module :
            % if configKey =="id" : 
                ${configKey}="${module[configKey]}"\
            % elif configKey in attributesToEmit : 
                s:${configKey}="${module[configKey] | h}"\
            % endif
        % endfor
        >\
        % if "templatePath" in module :
            <% logger.debug('rendering module %s' % module['templatePath']) %>\
            <%include file="${module['templatePath']}" args="module=module"/>\
        % endif
    </div>
</%def>

## generates the markup for all modules within the given panel. Currently used by all view templates.
<%def name="buildPanelContents(modules, panelName)"><% 
    successfullyRenderedPanels[panelName] = 1
    
    # TODO - Remove this once the params stanza is implemented everywhere
    for module in modules[panelName]:
        if module.has_key('params'):
            for param in module['params']:
                if not module.has_key(param):
                    module[param] = module['params'][param]
    %>\
    % if (panelName=="splSearchControls-inline") :
        <table class="mainSearchControlsTable" cellspacing="0"><tr>
        % for i in range(len(modules[panelName])) :
            <td 
            % if i==0:
                width="100%"
            % endif
            ><%call expr="buildModule(modules[panelName][i])"></%call></td>
        % endfor
        </tr></table>
    % else :
        % for module in modules[panelName] :
            <%call expr="buildModule(module)"></%call>
        % endfor
    % endif
</%def>

## much simpler rendering used by the top masthead modules. Currently used by all view templates.
<%def name="buildSimplePanelContainer(modules, panelName)">
    % if (panelName in modules) :    
        <div class="layoutRow oneColRow splClearfix ${panelName}">
            <%call expr="buildPanelContents(modules, panelName)"></%call>
        </div>
    % endif
</%def>

<%doc>
    This is used by the row x column layouts in dashboard.html and in builder.html
    for the given row number,  it will generate the internal html and overall  
    layout for the layoutPanels in that row.  
    The complexity here is considerable.  The full picture is as follows: 
    this template builds a row of N * layoutPanels (N<4 currently)
    each of the N layoutPanels. can contain 
    -- M * "ungrouped" modules
    -- P * "groups", each of which can contain several modules. 
    eg:  dashboard.html uses the full range available here. See comments in that file.
       builder.html  has no use for the "grouped" modules so it only has the "ungrouped" ones.
</%doc>
<%def name="getFloatLayoutRow(modules, row)">    
    <%    
    rowMatrix = []

    basePanelName = 'panel_row' + str(row) + '_col'
    col = 1

    ungrouped = []
    
    if (modules.get(basePanelName + str(col))) :
        while (modules.get(basePanelName + str(col))) :
            panelName = basePanelName + str(col)
            successfullyRenderedPanels[panelName] = 1
            rowMatrix.append([panelName])
            
            col = col + 1

    ## rowMatrix is now filled with ONLY the ungrouped modules from each panel.
    ## start second pass, to get the grouped modules.
    col = 1
    for col in range(1,4) :
        # maybe this panel has no grouped modules. Skip it.
        if (not modules.get(basePanelName + str(col) + "_grp1")) :
            pass

        else :
            group = 1
            baseGroupName = basePanelName + str(col) + "_grp"
            while (modules.get(baseGroupName + str(group))) :
                panelName = baseGroupName + str(group)
                rowMatrix[col-1].append(panelName)

                successfullyRenderedPanels[panelName] = 1
                group = group + 1 

    rowClasses = ["layoutRow", "equalHeightRow", "splClearfix", basePanelName]

    if (row==1) :
        rowClasses.append("firstRow")
    if (len(rowMatrix) == 1) :
        rowClasses.append("oneColRow")
    elif (len(rowMatrix) == 2) :
        rowClasses.append("twoColRow")
    elif (len(rowMatrix) == 3) :
        rowClasses.append("threeColRow")
    
    %>

    <div class="${' '.join(rowClasses)}">
    % for i in range(len(rowMatrix)) :
        <%
        cellClasses = ["layoutCell"]
        if (i==0) :
            cellClasses.append("firstCell")
        if (i==len(rowMatrix)-1) :
            cellClasses.append("lastCell")
        %>
        <div class="${' '.join(cellClasses)}">
            <%call expr="next.getDashboardPanel(modules, rowMatrix[i])"></%call>
        </div>
    % endfor
    </div>
</%def>

## we check that all the layoutPanels we had ended up with a home. If not we tell the user.
% for panelName in modules : 
    % if (panelName not in successfullyRenderedPanels) :
         <%call expr="lib.add_script_block()">
            this.messenger = Splunk.Messenger.System.getInstance();
            this.messenger.send("error", "splunk", sprintf(_("found an invalid value for layoutPanel - '%s'."), "${panelName}"));
            // a misconfigured hierarchy can often derail the module loading, so the 'Loading' string can get stuck there.
            $("#loading").hide();
        </%call>
    % endif
% endfor
