text: define([
    'dojo/_base/declare', 'dojo/on', 'dojo/_base/lang',  'dojo/query',
    'dojo/dom-class', 'dojo/dom-attr', 'dojo/dom-construct', './JobsGrid', './JobContainerActionBar',
    'dojo/_base/Deferred', '../JobManager', './Confirmation',
    'dojo/topic', 'dijit/layout/BorderContainer', './ActionBar', './ItemDetailPanel', '../util/encodePath'
  ], function (
    declare, on, lang, query,
    domClass, domAttr, domConstr, JobsGrid, JobContainerActionBar,
    Deferred, JobManager, Confirmation,
    Topic, BorderContainer, ActionBar, ItemDetailPanel, encodePath
  ) {
    return declare([BorderContainer], {
      disabled: false,
      path: '/',
  
      listJobs: function () {
        var _self = this;
        return Deferred.when(JobManager.getJobs(), function (res) {
          return res;
        }, function (err) {
          console.log('Error Getting Jobs:', err);
          _self.showError(err);
        });
      },
      postCreate: function () {
        this.inherited(arguments);
        domClass.add(this.domNode, 'JobManager');
      },
  
      showError: function (err) {
        domConstr.create('div', {
          style: {
            position: 'relative',
            zIndex: 999,
            padding: '10px',
            margin: 'auto',
            marginTop: '300px',
            width: '30%',
            border: '2px solid #aaa',
            borderRadius: '4px',
            textAlign: 'center',
            color: 'red',
            fontSize: '1.2em'
          },
          innerHTML: err
        }, this.domNode);
  
      },
  
      render: function (items) {
        items.sort(function (a, b) {
          return (Date.parse(a.submit_time) < Date.parse(b.submit_time)) ? 1 : -1;
        });
  
        this.grid.refresh();
        this.grid.renderArray(items);
      },
  
      selectionActions: [
        [
          'ToggleItemDetail',
          'fa icon-chevron-circle-right fa-2x', {
            label: 'HIDE',
            persistent: true,
            validTypes: ['*'],
            tooltip: 'Toggle Selection Detail'
          },
          function (selection) {
            var children = this.getChildren();
            if (children.some(function (child) {
              return this.itemDetailPanel && (child.id == this.itemDetailPanel.id);
            }, this)) {
              this.removeChild(this.itemDetailPanel);
            }
            else {
              this.addChild(this.itemDetailPanel);
            }
          },
          true
        ], [
          'ViewFeatureItem',
          'MultiButton fa icon-eye fa-2x',
          {
            label: 'VIEW',
            validTypes: ['*'],
            multiple: false,
            tooltip: 'View Job Results',
            validContainerTypes: ['*']
          },
          function (selection) {
            var params = selection[0].parameters;
            var path = encodePath(params.output_path + '/' + params.output_file);
            Topic.publish('/navigate', { href: '/workspace' + path });
          },
          false
        ], [
          'KillJob',
          'MultiButton fa icon-ban fa-2x',
          {
            label: 'KILL JOB',
            validTypes: ['*'],
            multiple: false,
            tooltip: 'Kill (Cancel) Selected Job',
            validContainerTypes: ['*']
          },
          function (selection) {
            var sel = selection[0],
              id = sel.id;
  
            var conf = 'Are you sure you want to terminate this ' + sel.app + ' job?<br><br>' +
                       '<b>Job ID</b>: ' + id + '<br><br>';
  
            var dlg = new Confirmation({
              title: 'Kill Job',
              content: conf,
              style: { width: '375px' },
              onConfirm: function (evt) {
                JobManager.killJob(id);
              }
            });
            dlg.startup();
            dlg.show();
  
          },
          false
        ], [
          'ReportIssue',
          'MultiButton fa icon-commenting-o fa-2x',
          {
            label: 'REPORT<br>ISSUE...',
            validTypes: ['*'],
            multiple: false,
            tooltip: 'Report an Issue with this Job',
            validContainerTypes: ['*']
          },
          function (selection) {
            var sel = selection[0];
  
            var descriptRequired = sel.status !== 'failed';
  
            try {
              var content =
                (descriptRequired ? '' :
                  '\n[Please feel free to add any additional information regarding this issue here.]\n\n\n') +
                '********************** JOB INFO *************************\n\n' +
                'Job ID: ' + sel.id + '\n' +
                'Job Status: ' + sel.status + '\n' +
                'App Name: ' + sel.app + '\n\n' +
                'Stdout: ' + window.App.serviceAPI + '/task_info/' + sel.id + '/stdout\n' +
                'Stderr: ' + window.App.serviceAPI + '/task_info/' + sel.id + '/stderr\n\n' +
                'Submit Time: ' + sel.submit_time + '\n' +
                'Start Time: ' + sel.submit_time + '\n' +
                'Completed Time: ' + sel.submit_time + '\n\n' +
                'Paremeters:\n' +
                '{code}\n' +
                JSON.stringify(sel.parameters, null, 4) +
                '\n{code}\n';
            } catch (e) {
              var content = 'There was an issue fetching some of job info.  Error: ' + e;
            }
  
            Topic.publish('/openDialog', {
              type: 'reportProblem',
              params: {
                issueText: content,
                issueSubject: 'Reporting Issue with ' + sel.app,
                jobDescriptRequired: descriptRequired,
                jobStatus: sel.status
              }
            });
          },
          false
        ], [
          'Rerun',
          'MultiButton fa icon-rotate-left fa-2x',
          {
            label: 'RERUN',
            validTypes: ['*'],
            multiple: false,
            tooltip: 'Return to service page with same job parameters',
            validContainerTypes: ['*']
          },
          function (selection) {
            var job_params = JSON.stringify(selection[0].parameters);
            //TODO: make sure service_id variable is present for every service
            var service_id = selection[0].app;
            var localStorage = window.localStorage;
            if (localStorage.hasOwnProperty("bvbrc_rerun_job")) {
              localStorage.removeItem("bvbrc_rerun_job");
            }
            localStorage.setItem("bvbrc_rerun_job",job_params);
            var service_app_map = {"ComprehensiveGenomeAnalysis":"ComprehensiveGenomeAnalysis","ComprehensiveSARS2Analysis":"ComprehensiveSARS2Analysis","DifferentialExpression":"Expression",
            "FastqUtils":"FastqUtil","GeneTree":"GeneTree","GenomeAssembly2":"Assembly2","GenomeAssembly":"Assembly2","GenomeAlignment":"GenomeAlignment","GenomeAnnotation":"Annotation","GenomeComparison":"SeqComparison",
            "Homology":"Homology","MetaCATS":"MetaCATS","MetagenomeBinning":"MetagenomicBinning","MetagenomicReadMapping":"MetagenomicReadMapping","MSA":"MSA",
            "CodonTree":"PhylogeneticTree","PrimerDesign":"PrimerDesign","RNASeq":"Rnaseq","TaxonomicClassification":"TaxonomicClassification","TnSeq":"Tnseq","Variation":"Variation"};
            if (service_app_map.hasOwnProperty(service_id)) {
              Topic.publish('/navigate',{href:'/app/'+service_app_map[service_id]});
            }
            else{
              console.log('Rerun not enabled for: ',service_id);
            }
          },
          false
        ]
      ],
  
      startup: function () {
        if (this._started) {
          return;
        }
        this.inherited(arguments);
  
        var _self = this;
  
        this.grid = new JobsGrid({
          region: 'center'
        });
  
        this.grid.set('sort', [
          { attribute: 'submit_time', descending: true }
        ]);
  
        this.containerActionBar = new JobContainerActionBar({
          region: 'top',
          className: 'BrowserHeader',
          header: 'Job Status',
          layoutPriority: 3
        });
  
        this.actionBar = new ActionBar({
          splitter: false,
          region: 'right',
          layoutPriority: 2,
          style: 'width:58px;text-align:center;'
        });
  
        this.itemDetailPanel = new ItemDetailPanel({
          region: 'right',
          layoutPriority: 1,
          splitter: true,
          style: 'width:250px;'
        });
  
        this.setupActions();
  
        this.grid.on('ItemDblClick', lang.hitch(this, function (evt) {
          if (evt.selected) {
            var params = evt.selected.parameters,
              path = encodePath(params.output_path + '/' + params.output_file);
            Topic.publish('/navigate', { href: '/workspace' + path });
          }
        }));
  
        this.grid.on('select', lang.hitch(this, function (evt) {
          var sel = Object.keys(evt.selected).map(lang.hitch(this, function (rownum) {
            var d = evt.grid.row(rownum).data;
  
            d._formatterType = 'job_status_meta';
            return d;
          }));
  
          this.actionBar.set('selection', sel);
          this.itemDetailPanel.set('selection', sel);
        }));
  
        this.addChild(this.grid);
        this.addChild(this.containerActionBar);
        this.addChild(this.actionBar);
        this.addChild(this.itemDetailPanel);
  
        // show / hide item detail panel event
        var hideBtn = query('[rel="ToggleItemDetail"]', this.actionBar.domNode)[0];
        on(hideBtn, 'click',  function (e) {
          var icon = query('.fa', hideBtn)[0],
            text = query('.ActionButtonText', hideBtn)[0];
  
          domClass.toggle(icon, 'icon-chevron-circle-right');
          domClass.toggle(icon, 'icon-chevron-circle-left');
  
          if (domClass.contains(icon, 'icon-chevron-circle-left'))
          { domAttr.set(text, 'textContent', 'SHOW'); }
          else
          { domAttr.set(text, 'textContent', 'HIDE'); }
        });
  
        // listen for new job data
        Topic.subscribe('/Jobs', function (info) {
          if (info.status == 'updated') {
            var store = JobManager.getStore();
            _self.grid.set('store', store);
          }
        });
  
  
        // listen for filtering
        Topic.subscribe('/JobFilter', function (filters) {
          // remove any non-specific filter states
          if (filters.app === 'all') delete filters.app;
          if (!filters.status) delete filters.status;
  
          // need to filter on all possible AWE-defined statuses
          if (filters.status === 'queued') {
            filters.status = new RegExp('queued|init|pending');
          } else if (filters.status === 'failed') {
            filters.status = new RegExp('failed|deleted');
          }
  
          _self.grid.set('query', filters);
        });
      },
  
      setupActions: function () {
        this.selectionActions.forEach(function (a) {
          this.actionBar.addAction(a[0], a[1], a[2], lang.hitch(this, a[3]), a[4]);
        }, this);
      }
  
    });
  });
  