from mod_python import Session, util, apache, psp
from include.siteSQL import Trucks, DB, Accounts, UnqLatLong
from sqlobject.sqlbuilder import AND,OR,NOT,IN,LIKE
from math import cos, pi
from sqlobject import sqlbuilder

def index(req):
  PSDefaults = apache.import_module("include.PSDefaults")
  
  req.content_type = "text/html"
  psdef = PSDefaults.Template(req)
  #session = psdef.sessionCheck()
  session = psdef.sessionCheck(page="/login?location=/truck_search.py", redirect=False)
  session["firstSearchTruck"] = True
  status = session["status"]

  session.save()
  
  psdef.addVars({'TruckTypeOptions':PSDefaults.truckTypeOptionsSearch(req), 'status':status, \
                 'StateAbbrVerboseOptions':PSDefaults.stateAbbrVerboseOptions(req), \
                 'StateAbbrOptions':PSDefaults.stateAbbrOptions(req), \
                 'CompanyOptions':PSDefaults.companyOptionsTruck(req), 'showTrucks':False })
  psdef.compileTemplate("./templates/truck_search.tpl")
  psdef.runTemplate()

  return

def search(req, truckType=None, rpp=None, showAll=None, filter=None, originCity=None, originState=None, \
        page=None, newSearch='0', destCity=None, destState=None, orderBy=None, pos=0, demo=None, \
        originRadius=None, destRadius=None, company=None, fullpartial=None):
#  try:
    PSDefaults = apache.import_module("include.PSDefaults")
    
    req.content_type = "text/html"
    psdef = PSDefaults.Template(req)
    msg = None
    status = 'None'
    if demo == None:
      session = psdef.sessionCheck(page="/login?location=/truck_search.py", redirect=False)
      status = session["status"]
      
      if rpp == None and not session.has_key("rpp"):
        session["rpp"] = 25
      else:
        if not rpp == None:
          session["rpp"] = int(rpp)
      if session["status"] == "Free":
         demo = 1
      elif session["status"] == "Pay" or session["status"] == "Admin":
        demo = None
      elif session["status"] == "Disable":
        util.redirect(req, '/disabled')
    else:
      session = Session.Session(req)
      session["firstSearchTruck"] = True
      session["rpp"] = 25
    
    limit, nextPos, prevPos = 0, 0, 0
    if session["rpp"] == "ALL":
      limit = "ALL"
    else:
      try:
        limit = float(session["rpp"])
      except:
        limit = 25.0
    
    if not page == None:
      pos = int(page) * int(limit)
    
    searchSQLList = list()
        
    if newSearch == '1':
        session["firstSearchTruck"] = True

    db = DB("freightterminal")
    db.connect()
    filterSQL = 0
    if session.has_key("firstSearchTruck"):
      if session["firstSearchTruck"]:
        session["truckType"] = truckType
        session["originCity"] = originCity
        session["originState"] = originState
        session["originRadius"] = originRadius



        session["company"] = company
        session["fullOrPartial"] = fullpartial
        session["firstSearchTruck"] = False
      else:
        if not showAll == None and int(showAll) == 1:
          session["filterTruck"] = []
        elif showAll == None or int(showAll) == 0:
          currentFilter = []
          if session.has_key("filterTruck"):
            currentFilter = session["filterTruck"]
            if filter:
              if type(filter) == list:
                currentFilter = list(currentFilter) + list(filter)
              else:
                currentFilter.append(filter)
            session["filterTruck"] = currentFilter
          else:
            if filter:
              if type(filter) == list:
                currentFilter = list(currentFilter) + list(filter)
              else:
                currentFilter.append(filter)
            session["filterTruck"] = currentFilter
          
          if currentFilter:
            if not currentFilter == []:
              accountQuery = Accounts.select(IN(Accounts.q.company,currentFilter))
              accountResults = list(accountQuery)
              accountList = list()
              for account in accountResults:
                accountList.append(account.id)
              accountList = dict.fromkeys(accountList).keys()
              filterSQL = NOT(IN(Trucks.q.accountid, accountList))

      if session["truckType"]:
        searchSQLList.append(eval(PSDefaults.generateTruckTypeEval(session["truckType"], "Trucks")))
      if session["fullOrPartial"]:
        searchSQLList.append(Trucks.q.fullOrPartial=='%s' % (session["fullOrPartial"]))
      if session['originCity'] and session['originState'] and session['originRadius']:
        searchLLQuery = UnqLatLong.select(AND(UnqLatLong.q.city_alias_name==session['originCity'], UnqLatLong.q.state==session['originState']))
        totalLL = searchLLQuery.count()
        if totalLL<1:
          PSDefaults = apache.import_module("include.PSDefaults")
          req.content_type = "text/html"
          psdef = PSDefaults.Template(req)
          req.content_type = "text/html"
          psdef.addVars({'FeedbackMessage':'City/State not found', 'success':False, 'status':None})
          psdef.compileTemplate("./templates/feedback.tpl")
          psdef.runTemplate()
          return
        latitude = float(searchLLQuery[0].latitude)
        longitude = float(searchLLQuery[0].longitude)
        radiusFloat = float(originRadius)
        minLat = latitude-radiusFloat/69.048
        maxLat = latitude+radiusFloat/69.048
        minLong = longitude-radiusFloat/69.048/cos(latitude*pi/180)
        maxLong = longitude+radiusFloat/69.048/cos(latitude*pi/180)
        searchLLResults = list()
        searchSQLList.append(Trucks.q.originLatitude<=maxLat)
        searchSQLList.append(Trucks.q.originLatitude>=minLat)
        searchSQLList.append(Trucks.q.originLongitude<=maxLong)
        searchSQLList.append(Trucks.q.originLongitude>=minLong)
      else:
        if session["originCity"]:
          searchSQLList.append(Trucks.q.originCity=='%s' % (session["originCity"]))
        if session["originState"]:
          searchSQLList.append(Trucks.q.originState=='%s' % (session["originState"]))
      if session['company']:
        searchSQLList.append(Trucks.q.company_name=='%s' % (session['company']))
      if session['fullOrPartial']:
        searchSQLList.append(Trucks.q.fullOrPartial=='%s' % (session['fullOrPartial']))
      
    if orderBy:
      session["orderByLoad"] = orderBy
    else:
      if not session.has_key("orderByTruck"):
        session["orderByLoad"] = "originState,originCity,destState,destCity"

    session.save()

    if session.has_key("filterSQLTruck") and session["filterSQLTruck"]:
        filterSQL = session["filterSQLTruck"]
        searchSQLList.append(filterSQL)
        
    if searchSQLList == []:
        searchSQLList.append(NOT(Trucks.q.id == 0)) # give the AND helper something to work with if the using a blank search

    db.setdb("freightterminal")
    orderByLoad = session["orderByLoad"]
    orderByEval = eval(','.join(map(lambda ob: "Trucks.q.%s" % (ob), orderByLoad.split(','))))
    searchQuery = Trucks.select(AND(*searchSQLList), orderBy = orderByEval)
    totalTrucks = searchQuery.count()
    searchResults = list(searchQuery[int(pos):int(pos)+int(limit)])
    
    db.close()
    
    import math
    totalPages = math.ceil(totalTrucks / limit) # ceil the calculation to avoid adding / cutting off records for
                                               # exact matches and more rpp than matches
    currentPage = math.floor(totalPages - ((totalTrucks - float(pos)) / float(limit))) # floor the currentPage to avoid starting at page 1 instead of 0
    
    paging = PSDefaults.Paging(currentPage, totalPages, pos, limit)
    
    truckListHtml, rowcount = _truckSearchResults(searchResults)
    psdef.addVars({'truckSearchResults':truckListHtml, 'demo':demo, 'status':status, \
                   'previousPosition':paging.prevPos, 'nextPosition':paging.nextPos, 'totalTrucks':totalTrucks, \
                   'previousInput':paging.prevInput(demo), \
                   'nextInput':paging.nextInput(demo), 'accountid':session["accountid"], \
                   'totalTrucks':int(totalTrucks), 'totalPages':int(totalPages), 'currentPage':int(currentPage+1), \
                   'pageSelection':paging.pageSelection, \
                   'rpp':int(limit), 'showTrucks':True, \
                   'TruckTypeOptions':PSDefaults.truckTypeOptionsSearch(req), \
                   'StateAbbrVerboseOptions':PSDefaults.stateAbbrVerboseOptions(req), \
                   'CompanyOptions':PSDefaults.companyOptionsTruck(req) })
    psdef.compileTemplate("./templates/truck_search.tpl")
    psdef.runTemplate()
    
    return
#  except:
#    PSDefaults = apache.import_module("include.PSDefaults")
#    
#    req.content_type = "text/html"
#    psdef = PSDefaults.Template(req)
#    import sys
#    feedback = str(sys.exc_info()[0])
#    req.content_type = "text/html"
#    psdef.addVars({'ErrorMessage':feedback, 'success':False, 'status':None})
#    psdef.compileTemplate("./templates/error.tpl")
#    psdef.runTemplate()
#    return
def _truckSearchResults(searchResults):
  PSDefaults = apache.import_module("include.PSDefaults")
  rowcount = len(searchResults)
  ret = ''
  if rowcount == 0:
    ret = '<tr class="white">\n'
    ret += '<td id="none" colspan="9">There are no trucks that match your search terms.</td>\n'
    ret += '</tr>\n'
  else:
    rowMod = 0
    for truck in searchResults:
      if rowMod % 2 == 1:
        ret += '<tr class="white">\n'
      else:
        ret += '<tr class="alt">\n'
      rowMod += 1
      
      ret += '<td><a class="line" href="#" onclick="document.detailsForm.truckid.value=\'%s\';document.detailsForm.submit(); return false;">details</a></td>\n' % (truck.id)

      ret += '<td>%s</td>\n' % (PSDefaults.flipDate(truck.availDate))
      
      if (truck.originCity == "" or truck.originCity == " ") and (truck.originState == "" or truck.originState == " "):
        ret += '<td></td>\n'
      else:
        ret += '<td>%s, &nbsp; %s</td>\n' % (truck.originState, truck.originCity)
        
      if (truck.destCity == "" or truck.destCity == " ") and (truck.destState == "" or truck.destState == " "):
        ret += '<td></td>\n'
      else:
        ret += '<td>%s, &nbsp; %s</td>\n' % (truck.destState, truck.destCity)
      ret += '<td>%s</td>\n' % (truck.truckType)
   

      
      
      
      
      if not truck.fullOrPartial == "" or truck.fullOrPartial:
        if truck.fullOrPartial[0]=='P' or truck.fullOrPartial[0]=='p':
        
          ret += '<td>Partial</td>\n'
        else:
          ret += '<td>Full</td>\n'
      else:
        ret += '<td></td>\n'      
      
      try:
        db = DB()
        db.connect()
        db.connection.cache.clear()
        account = list(Accounts.select(Accounts.q.id == truck.accountid))[0]
        db.close()
    
        if len(str(account.company)) > 20:
          ret += '''<td>%s..</td>\n''' % (account.company[0:19])         
        else:
          ret += '''<td>%s</td>\n''' % (account.company)
      except:
        ret += '''<td>%s</td>\n''' % (truck.company_name)
        #ret += '''<td><a class="join" href="">Subscribe</a></td>\n'''
      ret += '</tr>\n'
  return [ret, rowcount]
