Index: documentViewer.py
===================================================================
--- documentViewer.py	(revision 525)
+++ documentViewer.py	(revision 526)
@@ -17,4 +17,5 @@
 import re
 import string
+import json
 
 from SrvTxtUtils import getInt, utf8ify, getText, getHttpData, refreshingImageFileIndexHtml
@@ -124,7 +125,10 @@
     viewer_index = PageTemplateFile('zpt/viewer_index', globals())
     # available layer types
-    availableLayers = {'text': ['dict','search','gis','annotator'],
-                       'xml': None, 'images': None, 'index': None}
+    builtinLayers = {'text': ['dict','search','gis','annotator'],
+                     'xml': None, 'images': None, 'index': None}
+    availableLayers = builtinLayers;
     # layer templates
+    layer_text_dict = PageTemplateFile('zpt/layer_text_dict', globals())
+    layer_text_search = PageTemplateFile('zpt/layer_text_search', globals())
     layer_text_annotator = PageTemplateFile('zpt/layer_text_annotator', globals())
     layer_text_gis = PageTemplateFile('zpt/layer_text_gis', globals())
@@ -133,8 +137,8 @@
     toc_text = PageTemplateFile('zpt/toc_text', globals())
     toc_figures = PageTemplateFile('zpt/toc_figures', globals())
+    toc_concordance = PageTemplateFile('zpt/toc_concordance', globals())
     toc_none = PageTemplateFile('zpt/toc_none', globals())
     # other templates
     common_template = PageTemplateFile('zpt/common_template', globals())
-    search_template = PageTemplateFile('zpt/search_template', globals())
     info_xml = PageTemplateFile('zpt/info_xml', globals())
     docuviewer_css = ImageFile('css/docuviewer.css',globals())
@@ -409,4 +413,43 @@
         return self.getLink(param=param, val=val, params=params, baseUrl=baseUrl, paramSep='&amp;', duplicates=duplicates)
     
+
+    def setAvailableLayers(self, newLayerString=None):
+        """sets availableLayers to newLayerString or tries to autodetect available layers.
+        assumes layer templates have the form layer_{m}_{l} for layer l in mode m.
+        newLayerString is parsed as JSON."""
+        if newLayerString is not None:
+            try:
+                layers = json.loads(newLayerString)
+                if 'text' in layers and 'images' in layers:
+                    self.availableLayers = layers
+                    return
+            except:
+                pass
+
+            logging.error("invalid layers=%s! autodetecting..."%repr(newLayerString))
+            
+        # start with builtin layers
+        self.availableLayers = self.builtinLayers.copy()
+        # add layers from templates
+        for t in self.template:
+            if t.startswith('layer_'):
+                try:
+                    (x, m, l) = t.split('_', 3)
+                    if m not in self.availableLayers:
+                        # mode m doesn't exist -> new list
+                        self.availableLayers[m] = [l]
+                        
+                    else:
+                        # m exists -> append
+                        if l not in self.availableLayers[m]:
+                            self.availableLayers[m].append()
+                            
+                except:
+                    pass
+
+    def getAvailableLayersJson(self):
+        """returns available layers as JSON string."""
+        return json.dumps(self.availableLayers)
+    
     
     def getInfo_xml(self,url,mode):
@@ -838,5 +881,5 @@
             batch['prevStart'] = None
             
-        if start + grpsize < maxIdx:
+        if start + grpsize <= maxIdx:
             batch['nextStart'] = start + grpsize
         else:
@@ -864,10 +907,10 @@
         this = []
         j = 0
-        for i in range(start, min(start+size, end)):
+        for i in range(start, min(start+size, end+1)):
             if data:
                 if fullData:
-                    d = data[i]
+                    d = data.get(i, None)
                 else:
-                    d = data[j]
+                    d = data.get(j, None)
                     j += 1
             
@@ -888,4 +931,5 @@
             batch['nextStart'] = None
         
+        logging.debug("getBatch start=%s size=%s end=%s batch=%s"%(start,size,end,repr(batch)))
         return batch
         
@@ -894,5 +938,5 @@
     changeDocumentViewerForm = PageTemplateFile('zpt/changeDocumentViewer', globals())
     
-    def changeDocumentViewer(self,title="",digilibBaseUrl=None,thumbrows=2,thumbcols=5,authgroups='mpiwg',RESPONSE=None):
+    def changeDocumentViewer(self,title="",digilibBaseUrl=None,thumbrows=2,thumbcols=5,authgroups='mpiwg',availableLayers=None,RESPONSE=None):
         """init document viewer"""
         self.title=title
@@ -906,4 +950,6 @@
         except Exception, e:
             logging.error("Unable to find MetaDataFolder 'metadata': "+str(e))
+            
+        self.setAvailableLayers(availableLayers)
 
         if RESPONSE is not None:
