"""   QuArK  -  Quake Army Knife

Implementation of QuArK Map editor features for the "Search" menu
"""
#
# Copyright (C) 1996-99 Armin Rigo
# THIS FILE IS PROTECTED BY THE GNU GENERAL PUBLIC LICENCE
# FOUND IN FILE "COPYING.TXT"
#

Info = {
   "plug-in":       "Basic Search",
   "desc":          "Basic items for the Search menu.",
   "date":          "31 oct 98",
   "author":        "Armin Rigo",
   "author e-mail": "arigo@planetquake.com",
   "quark":         "Version 5.1" }


import string
import quarkpy.qmenu
import quarkpy.qmacro
import quarkpy.mapsearch
from quarkpy.maputils import *


#
# Search broken polyhedron and faces.
#

def Brok1Click(m):
    editor = mapeditor()
    if editor is None: return
    list = editor.Root.findallsubitems("", ':p')+editor.Root.findallsubitems("", ':f')
    list = filter(lambda p: p.broken, list)
    quarkpy.mapsearch.SearchResult(editor, list)



class SearchDlg(quarkpy.qmacro.dialogbox):

    def __init__(self, reserved):
        editor = mapeditor()
        self.sellist = editor.visualselection()

        src = quarkx.newobj(":")
	if not len(self.sellist):
	    src ["scope"] = "W"
	    src ["scope$Items"] = "Whole map"
	    src ["scope$Values"] = "W"
	else:
	    src ["scope"] = "S"
	    src ["scope$Items"] = "Selection\nWhole map"
	    src ["scope$Values"] = "S\nW"

        quarkpy.qmacro.dialogbox.__init__(self, quarkx.clickform, src,
          ok = qtoolbar.button(self.search, "search for the given classname", ico_editor, 1, "Search"),
          cancel = qtoolbar.button(self.close, "close this box", ico_editor, 0, "Cancel"))
        self.editor = editor



#
# Search by Classname.
#

class SearchByName(SearchDlg):

    #
    # dialog layout
    #

    size = (300, 175)
    dfsep = 0.4        # separation at 40% between labels and edit boxes

    dlgdef = """
      {
        Style = "15"
        Caption = "Search by classname"
        sep: = {Typ="S" Txt=" "}
        classname: = {
          Txt = " Search for :"
          Typ = "E"
          SelectMe = "1"
        }
        scope: = {
          Typ = "CL"
          Txt = " Search in :"
          Items = "%s"
          Values = "%s"
        }
        sep: = {Typ="S" Txt=" "}
        sep: = {Typ="S"}
        ok:py = { }
        cancel:py = { }
      }
    """

    def search(self, reserved):
        quarkx.globalaccept()
        searchfor = self.src["classname"]
        if searchfor:
            if self.src["scope"] == "S":
                sellist = self.sellist
            else:
                sellist = [self.editor.Root]
            list = []
            for obj in sellist:
                list = list + obj.findallsubitems(searchfor, ':e') + obj.findallsubitems(searchfor, ':b')
            quarkpy.mapsearch.SearchResult(self.editor, list)
            self.close()



#
# Search by Specific/Arg.
#

class SearchBySpec(SearchDlg):

    #
    # dialog layout
    #

    size = (300, 195)
    dfsep = 0.4        # separation at 40% between labels and edit boxes

    dlgdef = """
      {
        Style = "15"
        Caption = "Search by Specific/Arg"
        sep: = {Typ="S" Txt=" "}
        spec: = {
          Txt = " Search for Specific :"
          Typ = "E"
          SelectMe = "1"
          Hint = "Specific to search for (optionnal)"
        }
        arg: = {
          Txt = " Search for Arg :"
          Typ = "E"
          Hint = "Arg to search for (optionnal)"
        }
        scope: = {
          Typ = "CL"
          Txt = " Search in :"
          Items = "%s"
          Values = "%s"
        }
        sep: = {Typ="S" Txt=" "}
        sep: = {Typ="S"}
        ok:py = { }
        cancel:py = { }
      }
    """

    def search(self, reserved):
        quarkx.globalaccept()
        spec = self.src["spec"]
        arg = self.src["arg"]
        if self.src["scope"] == "S":
            sellist = self.sellist
        else:
            sellist = self.editor.Root.subitems
        list = []
        for obj in sellist:
            list = list + obj.findallsubitems("", ':e') + obj.findallsubitems("", ':b')

        if not spec:
            if not arg:
                testfn = lambda x: 1
            else:
                def testfn(obj, arg0=arg):
                    for spec, arg in obj.dictspec.items():
                        if arg == arg0:
                            return 1
                    return 0
        else:
            if not arg:
                def testfn(obj, spec0=spec):
                    return obj[spec0]
            else:
                def testfn(obj, spec0=spec, arg0=arg):
                    return obj[spec0]==arg0

        list = filter(testfn, list)

        quarkpy.mapsearch.SearchResult(self.editor, list)
        self.close()



#
# Register these new menu items for the "Search" menu.
#

quarkpy.mapsearch.items.append(quarkpy.qmenu.item("Entities by &name", SearchByName))
quarkpy.mapsearch.items.append(quarkpy.qmenu.item("Entities by &Specific", SearchBySpec))
quarkpy.mapsearch.items.append(quarkpy.qmenu.item("&Broken polys and faces", Brok1Click))

