*--------------------------------------------------------------------------------------------------------------------------------------------------
*Program Listing for:  bot_process.prg
*Project:  webbot
*Namespace:  foxpro
*----------------------------------------------------------------------------------------------------------------------------------------------------

*****************************************************************************************************************************
*****************************************************************************************************************************
*****  bot_process.prg
*****  processing routines for autobot project
***** Scott Laing
*****************************************************************************************************************************
*****************************************************************************************************************************
#include "foxpro.h"

*****************************************************************************************************************************
function nothing()
*****************************************************************************************************************************

         if MB2("Cancel process?", MB_YESNO) = IDYES
                  lHitCancel = .T.
                  *goBotApp.lCancel = .T.
         endif
         
return

*****************************************************************************************************************************
function process_day( tnDOW, toListBox, tlManual, toMainForm )
*****************************************************************************************************************************


goBotApp.oMainForm = toMainForm

* nrec is private it keeps track of record number for wait window
private nrec
private npage

private critical_stop
critical_stop = .F.
goBotApp.lCancel = .F.
goBotApp.lHitCancel = .F.
lHitCancel = .F.

if tlManual
         select * from dayrun where ddate = date() into cursor day_chk
         if recc() > 0
                  if MB2("Process has run for today already, run again?", MB_YESNO) != IDYES
                           use in day_chk
                           return
                  endif
         endif
endif

use in day_chk


* all makes supported by the site as of the writing of this
dime amakes[47]

amakes[1]="ACURA"
amakes[2]="ALFA"
amakes[3]="AMC"
amakes[4]="AMGEN"
amakes[5]="AUDI"
amakes[6]="BMW"
amakes[7]="BUICK"
amakes[8]="CAD"
amakes[9]="CHEV"
amakes[10]="CHRY"
amakes[11]="DAEW"
amakes[12]="DAIHAT"
amakes[13]="DATSUN"
amakes[14]="DODGE"
amakes[15]="EAGLE"
amakes[16]="FORD"
amakes[17]="GEO"
amakes[18]="GMC"
amakes[19]="HONDA"
amakes[20]="HYUND"
amakes[21]="INFIN"
amakes[22]="ISU"
amakes[23]="JAG"
amakes[24]="JEEP"
amakes[25]="KIA"
amakes[26]="ROV"
amakes[27]="LEXUS"
amakes[28]="LINC"
amakes[29]="MAZDA"
amakes[30]="MB"
amakes[31]="MERC"
amakes[32]="MERKUR"
amakes[33]="MIT"
amakes[34]="NISSAN"
amakes[35]="OLDS"
amakes[36]="PLYM"
amakes[37]="PONT"
amakes[38]="POR"
amakes[39]="SAAB"
amakes[40]="SATURN"
amakes[41]="SUB"
amakes[42]="SUZUKI"
amakes[43]="TOYOTA"
amakes[44]="trI"
amakes[45]="VOLKS"
amakes[46] ="VOLVO"
amakes[47]="YUGO"


if ! used("note_text")
         use note_text in 0
endif
select note_text
go top

if empty(note_text.mtext)
         MB2("No email message in the note_text data file!")
         return
endif

private gcNoteText
local ctemp
ctemp = note_text.mtext

gcNoteText = cgi_ify(ctemp)
if empty(gcNoteText)
         MB2("email note text appears empty after cgi translation - possible bug - cannot proceed")
         return
else
         *MB2("note text / cgi-encoded:" + chr(13) + gcNoteText )
endif

*So, the locations we need to search for emails right now are:
*1. Arizona.. I do the entire state, makes it kinda easy
*2. Garden Grove, CA  92841... Ive been doing a 75 mile radius of that zip
*3. Las Vegas, NV 89119    75 mile radius
*4. Reno, NV 89431      75 mile radius
*5. Tulsa, OK 74112     100 mile radius
local n, n1, n2

select * from runinfo where ndow = tnDOW order by norder into cursor run_this

* if no zip records for this date then just return here, this day isn't really "processed" since no records exist for
* this date, so don't get new batch_id or insert record into dayrun, this way if they add a new record to this
* day, a new zipcode record, it will continue to attempt to run and then, run by hitting this record
if recc() = 0         
         use in run_this
         if tlManual
                  MB2("No zip's seem to be defined for this day - nothing run")
         endif
         
         return
endif

goBotApp.nbatch_id =  nextkey( "BATCH_ID")

if ! used("batches")
         use batches in 0
endif
select batches
append blank
repl batch_id with goBotApp.nbatch_id
repl truntime with datetime()
repl drundate with date()
repl ndow with tnDow
repl lstart with .T.

goBotApp.nnew_phones = 0
goBotApp.nemails_sent = 0

goBotApp.nold_phones = 0
goBotApp.nemails_skpd = 0
goBotApp.nspam_skip = 0

if ! used("dayrun")
         use dayrun in 0
endif

sele dayrun
append blank
repl ddate with date()
repl lstarted with .T.
repl tstart with datetime()
repl batch_id with goBotApp.nbatch_id
repl dayrun_id with nextkey("DAYRUN_ID")

use in dayrun

* open phone_contacts

if ! used("phone_contacts")
         use phone_contacts in 0
endif

select phone_contacts
set order to tag cphone

if ! used("phone_link")
         use phone_link in 0
endif

goBotApp.nday = tnDow

select run_this
scan


         if type("toListBox") = "O"
                  toListBox.additem("start run for zip:" + run_this.czip + " " + ttoc( datetime() )  )
         endif

         if val(run_this.czip         ) = 0
                  MB2("A valid record for this day of the week had an empty zip, it will be skipped, please delete this record or fix")
                  select run_this
                  loop
         endif
         if val(run_this.cdistance) = 0
                  MB2("A valid record for this day of the week had an empty distance (of zero), it will be skipped, please delete this record or fix")
                  select run_this
                  loop
         endif
         
         n1 = seconds()

         goBotApp.nGrpLastEmailCnt  = 0
         goBotApp.nGrpLastNonEmailCnt  = 0
         goBotApp.nGrpRecentMailSkip = 0

         for n = 1 to alen(amakes)
                  if type("toListBox") = "O"
                           toListBox.additem("processing:" + run_this.czip + ":" + amakes[n] )
                  endif
                  
                  goBotApp.nLastEmailCnt = 0
                  goBotApp.nLastNonEmailCnt = 0
                  goBotApp.nRecentMailSkip         = 0

                  if type("goBotApp.oMainForm") = "O"
                           goBotApp.oMainForm.txtDetails.value = "beginning processing of make: " + amakes[n]
                           goBotApp.oMainForm.refresh()
                  endif
                  
                  * do the actual search now
                  SearchInfo( amakes[n], 1999, 2002, val(run_this.czip), val(run_this.cdistance) )
                  if goBotApp.lCancel 
                           exit
                  endif
                  
                  if type("toListBox") = "O"
                           toListBox.additem("emails sent:" + ltrim(str(goBotApp.nLastEmailCnt )) )
                  endif
                  if type("toListBox") = "O"
                           toListBox.additem("recent mail skips:" + ltrim(str( goBotApp.nRecentMailSkip )) )
                  endif
                  if type("toListBox") = "O"
                           toListBox.additem("non-email contacts:" + ltrim(str(goBotApp.nLastNonEmailCnt )) )
                  endif
                  toListBox.listindex = toListBox.listcount
                  toListBox.parent.refresh()
                  
         next

         if goBotApp.lCancel 
                  if type("toListBox") = "O"
                           toListBox.additem("process aborted by user" )
                  endif
         
         endif

         n2 = seconds()

         
         if type("toListBox") = "O"
                  if ! goBotApp.lCancel 
                           toListBox.additem("finished run for " + run_this.czip )
                  endif
                  
                  if type("toListBox") = "O"
                           toListBox.additem("emails sent:" + ltrim(str(goBotApp.nGrpLastEmailCnt )) )
                  endif
                  if type("toListBox") = "O"
                           toListBox.additem("recent mail skips:" + ltrim(str( goBotApp.nGrpRecentMailSkip )) )
                  endif
                  if type("toListBox") = "O"
                           toListBox.additem("non-email contacts:" + ltrim(str(goBotApp.nGrpLastNonEmailCnt )) )
                  endif
                  
                  if type("toListBox") = "O"
                           toListBox.additem("mins for run: " + run_this.czip + ":"  + str(  (n2 - n1)/60  ) )
                  endif
                  
         endif

         if goBotApp.lCancel 
                  exit
         endif
                  
         select run_this

endscan
use in run_this

update batches set lfinish = ! goBotApp.lCancel, ;
                           labort =  goBotApp.lCancel, ;
                           nemails_sent = goBotApp.nemails_sent, ;
                           nnew_phones = goBotApp.nnew_phones, ;
                           nold_phones = goBotApp.nold_phones , ;
                           nemails_skpd = goBotApp.nemails_skpd , ;
                           nspam_skip = goBotApp.nspam_skip ;
                            where batch_id = goBotApp.nbatch_id
                            
if _tally = 0
         MB2("trouble updating finish flag in batches table")
endif

wait clear

*select maininfo
*browse nowait


return


*****************************************************************************************************************************
function SearchInfo( tcMake, tnStartYr, tnEndYr, tnZip, tnDistance)
*****************************************************************************************************************************

if type("tnStartYr") = "L"
         tnStartYr = 1999
endif
if type("tnEndYr") = "L"
         tnEndYr = 2002
endif
if type("tnZip") = "L"
         tnZip = 85281
endif

local nStartRec
nStartRec = 1
* nrec used with wait window
nrec = 1
npage = 1

do while .T.

         SearchDetail( tcMake, tnStartYr, tnEndYr, tnZip, nStartRec, tnDistance)
         
         if goBotApp.lCancel 
                  return
         endif
         
         nStartRec = nStartRec + 25
         npage = npage + 1
         
         * 500 is max results
         if nStartRec > 500
                  exit
         endif
                  
enddo

return

*****************************************************************************************************************************
function SearchDetail( tcMake, tnStartYr, tnEndYr, tnZip, tnStartRec, tnDistance)
*****************************************************************************************************************************

local buildstr
local cfullpage
local mstr2
local lEmail
local crecrange          
local lPhoneFound, lnPhoneID
local lnMainInfoID 
local cphone
local cmisc
local ccorrected 

cphone = ""

private  cphonepage, cphone2


buildstr = "/findacar/results.jtmpl?&model=&start_year=" + alltrim(str(tnStartYr)) + ;
          "&end_year=" + alltrim(str(tnEndYr)) + ;
          "&min_price=&max_price=&distance=" + alltrim(str(tnDistance)) + "&make=" + alltrim(tcMake) + ;
          "&address=" + alltrim(str(tnZip)) + "&search_type=used&advcd_on=n&advanced=y&ac_afflt=none&"

*MB2(buildstr)

* "x=54&y=9&"

crecrange = "first_record=" + alltrim(str(tnStartRec)) + "&"
*     "first_record=26&"

buildstr = buildstr + crecrange

if type("goBotApp.oMainForm") = "O"
         goBotApp.oMainForm.txtDetails.value = "getting next page of results, page: " + ltrim(str(npage))
         goBotApp.oMainForm.refresh()
endif

cfullpage = GetUrlAsString("www.autotrader.com", buildstr)

if empty(cfullpage)

         cfullpage = GetUrlAsString("www.autotrader.com", buildstr)
         if empty(cfullpage)
         
                  k = select()
                  if ! used("url_errors")
                           use url_errors in 0
                  endif
                  sele url_errors
                  append blank
                  repl ctype with "EMPTY_RET"
                  repl curl with buildstr
                  repl tadded with datetime()
                  repl batch_id with goBotApp.nbatch_id
                  
                  select (k)
                  *MB2("possible error, no text returned from last lookup:" + buildstr)
                  
         endif
         
         return
         
endif

local cparsestr
cparsestr = cfullpage
local cthis_string
local n, k, k2

k = len("<!-- Set Car properties -->")
n = 2 && skip the first set car properties area that isn't a car but some other stuff
local crawcopy

do while .T.

         *set step on
         
         if lHitCancel
                  if MB2("Stop report?", MB_YESNO) == IDYES
                           goBotApp.lCancel = .T.
                           return
                  else
                           lHitCancel = .F.
                  endif
         endif
         wait window "Processing Day:  " + ltrim(str(goBotApp.nday)) + " Zip: " + ltrim(str(tnzip)) + " Make: " + tcMake + " Record: " + ltrim(str(nrec))  ;
                           + chr(13) + " Hit ESC to stop processing" nowait noclear 
         *? str(nrec,4) + "  " + tcMake
         
         npos = at("<!-- Set Car properties -->", cfullpage, n)
         npos2 = at("<!-- Set Car properties -->", cfullpage, n + 1)
         n = n + 1
         
         if npos == 0 AND npos2 == 0
                  exit
         endif
         
         * create the sub string to parse for this particular vehicle
         if npos2 == 0
                  cthis_string = substr( cfullpage, npos + k)
         else
                  cthis_string = substr(cfullpage, npos + k, npos2 - npos)
         endif
         
         * translate out these because this is chunking info, the site returns chunked info per http1.1
         * note I am using low level sockets not an IE wrapper, I am grabbing the lowest level http return text, for
         * speed and a few other reasons, IE wrappers force caching always on (some of them do) and this is possibly a bit more efficient also
         * chunking is a low level HTTP methodology where it sends in info in "chunks" separated out by lines which give the length of the next
         * chunk, for this server these length indicator lines usually contain "2000" per their server, so this info is extraneous and can throw off
         * the parsing logic hence it is removed.  a better version would removing chunking on the data obtaining end but that is for the future
         * or until I switch back to IE's or inetlib url obtaining functions (warning: some of them are made to always cache pages, despite documentation
         * to the contrary in visual c++ msdn).  also some are quite slow compared to their raw socket equivalents.
         cthis_string = strtran( cthis_string, chr(13) + chr(10) + "2000" + chr(13) + chr(10), "")

         * save the raw copy of this parsing string in case of errors to the dbf also
         crawcopy = cthis_string

         * we don't want to deal with dealers
         if ! ( "Private Seller" $ cthis_string )
         
                  * don't increment record counter for ads, ads dont have a checkbox cgi param in them, for this part of the html page
                  if [type="checkbox"] $ cthis_string
                           nrec = nrec + 1         
                  endif
                                    
                  if .F.
                           select maininfo
                           append blank
                  
                           *replace make with tcMake
                           replace mrawstr with crawcopy                  
                  endif
                  
                  loop
         endif

         lEmail = ( "Email Seller" $ cthis_string )
         
         * skips ahead in the string a certain distance based on pattern match
         *         MB2( "a:" + cthis_string )
         
         *SkipAhead( @cthis_string, "<a href", 1)
         lWithImage = .F.
         
         if    "/img/findacar/photo_icon.gif" $ cthis_string
                  lWithImage = .T.
         endif
         
         *set step on
         if ! lWithImage
                  cdetails_link = ParseStr( @cthis_string, "<a href", 1, [">] )
         else

                  discard =          ParseStr( @cthis_string, "<a href", 1, [">] )
                  cdetails_link = ParseStr( @cthis_string, [href="], 1, [">] )
         endif

         *         MB2( "b:" + cthis_string )
         * find a string bounded by the these sub strings, alters cthis_string
         cfulltitle = ParseStr( @cthis_string, [], 1, "</a>")

         cdescrip = ParseStr( @cthis_string, [size="1">], 1, "</font>" )
         
         lPhoneFound = .F.
         lnMainInfoID = 0
                  
         if  left(cfulltitle,4) != "<img"
         
                  lnMainInfoID = nextkey( "MAININFO_ID")
                  select maininfo
                  append blank
         
                  replace make with tcMake
                  replace mrawstr with crawcopy
                  replace fulltitle with cfulltitle
                  repl descrip with cdescrip
                  repl tadd_dt with datetime()
                  repl details_link with cdetails_link
                  repl maininfo_id with lnMainInfoID 
                  repl batch_id with goBotApp.nbatch_id
                  repl czip with alltrim(str( tnZip ) )
                  
                  local car_id, dealer_id, car_year
                  if ! empty( cdetails_link )

                           *MB2( cdetails_link)
                           ccar_id = ParseStr( @cdetails_link, [car_id=], 1, [&] )
                           cdealer_id = ParseStr( @cdetails_link, [dealer_id=], 1, [&] )
                           ccar_year = ParseStr( @cdetails_link, [car_year=], 1, [&] )
                           */findacar/vdetail.jtmpl?car_id=83796030&dealer_id=1328115&max_price=&start_year=1999&end_year=2002&address=85281&search_type=used&make=FORD&model=&min_price=&distance=25&advcd_on=n&advanced=n&=&color=&car_year=2001&ac_afflt=none         
                           repl car_id1 with m.ccar_id
                           repl dealer_id1 with m.cdealer_id
                           repl car_year1 with m.ccar_year

                           phone_linka = "/findacar/phone_seller.jtmpl?message_type=link#link_type=PHONE#type=phone#max_price=#start_year=1999" + ;
                                     "#end_year=2002#ac_afflt=none#address=85281#car_year=" + alltrim(m.ccar_year) 
                                     
                           phone_linkb = "#search_type=used#make=FORD#model=#" + ;
                                     "car_id=" + alltrim(m.ccar_id) + "#min_price=#distance=25#dealer_id=" + alltrim(m.cdealer_id) + "#advcd_on=n#advanced=n#=#color="
                                     
                           repl phone_link with strtran(m.phone_linka + m.phone_linkb, "#", "&")
                           repl lhas_email with lEmail                  
                           if type("goBotApp.oMainForm") = "O"
                                    goBotApp.oMainForm.txtDetails.value = "getting phone details per record " + ltrim(str(nrec))
                                    goBotApp.oMainForm.refresh()
                           endif
                           
                           cphonepage = GetUrlAsString("www.autotrader.com", alltrim(phone_link))
                           if ! empty( cphonepage )                           

                                    if ! empty(cphonepage)
                                             repl phone_raw with padr(cphonepage, 15)
                                    endif
                                    
                                    cphone2 = cphonepage
                                    
                                    SkipAhead( @cphone2, "<b>Comments</b>", 1)
                                    SkipAhead( @cphone2, "<tr>", 3)
                                    SkipAhead( @cphone2, ">", 2)
                                    repl mcomments with ParseStr( @cphone2, [], 1, "</font>")
                                    *MB2( mcomments )
                                                      
                                    SkipAhead( @cphonepage, "<i>Contact:</i>", 1)
                                    cname = ParseStr( @cphonepage, [size="2">], 1, "</font>" )
                                    repl name with m.cname
                                    m.cphone = ParseStr( @cphonepage, [<b>Phone:], 1, [</b></font>] )
                                    repl phone with alltrim(m.cphone)
                                    lPhoneFound = .T.
                                    
                                    cAddr = ParseStr( @cphonepage, [&dAddr=], 1, [">] )
                                    cAddr = strtran( cAddr, "&dCity=", chr(13) )
                                    cAddr = strtran( cAddr, "&dState=", chr(13) )
                                    cAddr = strtran( cAddr, "&dZip=", chr(13) )
                                    cAddr = strtran( cAddr, "+", " ")
                                    
                                    repl address with cAddr
                                    
                           endif                                    
                           
                           * if this item didn't have an email option, save it as a phone contact to be sent to HQ
                           if  ! lEmail
                           
                                    * update the tracking var for LB
                                    goBotApp.nLastNonEmailCnt  = goBotApp.nLastNonEmailCnt + 1
                                    
                                    * make sure this last record found a phone, and it's not empty
                                    if lPhoneFound AND ! empty( maininfo.phone)

                                             sele phone_contacts
                                             
                                             * if this phone number doesn't exist in phone_contacts, add it and add it to the links
                                             * file, the links file will be used to see what phone numbers were new per this batch run
                                             if ! seek( alltrim(maininfo.phone) )
                                             
                                                      lnPhoneID = nextkey( "PHONE_CONTACTS_ID")         
                                                      if empty(lnPhoneID)
                                                               MB2("trouble getting new phone record ID, critical error")
                                                               loop
                                                      endif

                                                      goBotApp.nnew_phones = goBotApp.nnew_phones + 1
                                                                                                            
                                                      select phone_contacts
                                                      append blank
                                                      
                                                      repl phone_contacts_id with lnPhoneID
                                                      repl cphone with alltrim(maininfo.phone)
                                                      repl tadded with datetime()
                                                      repl batch_id with goBotApp.nbatch_id 
                                                      repl dlastsend with date()

                                                      * phone link tracks what batches had new phone numbers assigned to phone_contacts table                                                      
                                                      * this could be extracted from existing tables but logic would be complex this is simpler and faster
                                                      * to use a separate linking table, info less likely to be lost also
                                                      
                                                      * a report will use phone_link to see what new phone numbers exist for a given batch, note the phone
                                                      * number isn't kept in the link table that would be redundant, it is in maininfo and also in phone_contacts,
                                                      * whichever is more convenient to grab.  batch_id corresponds to a record in batches.dbf
                                                      select phone_link
                                                      append blank
                                                      
                                                      repl batch_id with goBotApp.nbatch_id 
                                                      repl maininfo_id with lnMainInfoID 
                                                      repl phone_contacts_id with lnPhoneID
                                                      repl phone_link_id with nextkey( "PHONE_LINK_ID")         
                                                      repl tadded with datetime()

                                             else
                                             
                                                      goBotApp.nold_phones = goBotApp.nold_phones + 1

                                             endif
                                                                                                                                       
                                    endif
                           
                           else
                           
                                    * make sure a valid car id was found for this section
                                    if val(m.ccar_id) > 0

                                             lOkay = .F.
                                             llNoSpam = .F.
                                             
                                             * to avoid spams avoid this car id if in nospam table and
                                             if ! empty(m.ccar_id)
                                             
                                                      * see if match in the "nospam" table, table with list of people who dont want emails in it
                                                      select * from nospam where alltrim(car_id) == alltrim(m.ccar_id) into cursor nospam_chk         
                                                      if recc() > 0
                                                               llNoSpam = .T.
                                                      endif
                                                      use in nospam_chk
                                             endif
                                             
                                             * and avoid any cars with this same phone number in nospam also 
                                             if lPhoneFound  AND ! empty(m.cphone)
                                             
                                                      select * from nospam where alltrim(phone) == alltrim(m.cphone) into cursor nospam_chk         
                                                      if recc() > 0
                                                               llNoSpam = .T.
                                                      endif
                                                      use in nospam_chk
                                             
                                             endif

                                             if llNoSpam
                                                      goBotApp.nspam_skip = goBotApp.nspam_skip + 1
                                                      lOkay = .F.
                                             else
                                             
                                                      * now look in tracking for a previous email send and make sure expire period has passed before sending another
                                                      select * from tracking where car_id = val(m.ccar_id) order by tlastemailsent desc into cursor quick_check
                                                      select quick_check
                                                      
                                                      select quick_check
                                                      if recc() = 0
                                                               lOkay = .T.
                                                      else
                                                               dlastsend = ttod( quick_check.tlastemailsent)
                                                               if dlastsend <= date() - goBotApp.nExpirePeriod
                                                                        lOkay = .T.
                                                               else
                                                                        goBotApp.nRecentMailSkip = goBotApp.nRecentMailSkip + 1
                                                                        goBotApp.nemails_skpd = goBotApp.nemails_skpd + 1
                                                               endif
                                                      endif
                                                      use in quick_check
                                             endif
                                                               
                                             if lOkay
                                             
                                                      goBotApp.nLastEmailCnt = goBotApp.nLastEmailCnt  + 1

                                                      goBotApp.nemails_sent = goBotApp.nemails_sent + 1
                                                      
                                                      select maininfo
                                                      repl lemailsent with .T.
                                                      
                                                      lcCgiParams = "message_type=email&"
                                                      lcCgiParams = lcCgiParams + "contact_name=Nancy+Pomeroy&"
                                                      
                                                      cmisc = cgi_ify("480-464-1969")
                                                      *messagebox(cmisc)
                                                      lcCgiParams = lcCgiParams + "day_phone_number=" + cmisc + "&"
                                                      lcCgiParams = lcCgiParams + "night_phone_number=&"
                                                      
                                                      cmisc = cgi_ify("nancy.pomeroy@usautomanagementllc.com")
                                                      *messagebox(cmisc)
                                                      
                                                      lcCgiParams = lcCgiParams + "email_address=" + cmisc + "&"
                                                      
                                                      *messagebox(gcNoteText)
                                                      lcCgiParams = lcCgiParams + "contact_time=Day&"
                                                      lcCgiParams = lcCgiParams + "comment=" + gcNoteText + "&"
                                                      lcCgiParams = lcCgiParams + "ac_contact=no&"
                                                      lcCgiParams = lcCgiParams + "partner_contact=no&"
                                                      lcCgiParams = lcCgiParams + "page=results&"
                                                      lcCgiParams = lcCgiParams + "car_id=" + alltrim(m.ccar_id) + "&"
                                                      lcCgiParams = lcCgiParams + "dealer_id=" + alltrim(m.cdealer_id) + "&"
                                                      lcCgiParams = lcCgiParams + "address=" + alltrim(str(tnZip)) + "&"
                                                      lcCgiParams = lcCgiParams + "sort_type=" + "&"
                                                      lcCgiParams = lcCgiParams + "start_year=" + alltrim(str(tnStartYr)) + "&"
                                                      lcCgiParams = lcCgiParams + "distance=25&"
                                                      lcCgiParams = lcCgiParams + "end_year=" + alltrim(str(tnEndYr)) + "&"
                                                      lcCgiParams = lcCgiParams + "max_price=&"
                                                      lcCgiParams = lcCgiParams + "make=" + alltrim(tcMake) + "&"
                                                      lcCgiParams = lcCgiParams + "model=&"
                                                      lcCgiParams = lcCgiParams + "first_record=1&"
                                                      lcCgiParams = lcCgiParams + "ac_afflt=none&"
                                                      
                                                      *<input type="hidden" value="82616543" name="car_id"> 
                                                    * <input type="hidden" value="" name="dealer_id"> 
                                                    * <input type="hidden" value="85281" name="address">     
                                                    * <input type="hidden" value="" name="sort_type"> 
                                                    * <input type="hidden" value="1999" name="start_year"> 
                                                    * <input type="hidden" value="25" name="distance"> 
                                                    * <input type="hidden" value="2002" name="end_year"> 
                                                    * <input type="hidden" value="" name="max_price"> 
                                                    * <input type="hidden" value="FORD" name="make"> 
                                                    * <input type="hidden" value="" name="model">         
                                                    * <input type="hidden" value="1" name="first_record">       
                                                    *                                                                                           <!-- pass ac_afflt so it appears in location field for tracking -->
                                                    *    <input value="none" type="Hidden" name="ac_afflt"> </form>
                                               
                                                        select tracking
                                                        append blank
                                                      repl tracking_id with nextkey( "TRACKING_ID")
                                                        replace car_id with val(m.ccar_id) 
                                                        repl tlastemailsent with datetime()
                                                        repl maininfo_id with maininfo.maininfo_id
                                                        *repl nospam with .F.
                                                        
                                                        select maininfo
                                                        
                                                      if type("goBotApp.oMainForm") = "O"
                                                               goBotApp.oMainForm.txtDetails.value = "sending email for " + m.cphone
                                                               goBotApp.oMainForm.refresh()
                                                      endif
                                                        if .F. && val(m.ccar_id) != 91575546
                                                        
                                                                 inkey(.5)
                                                                 repl cemailparams with lcCgiParams
                                                                 
                                                        else
                                                        
                                                                 *messagebox("starting actual send")
                                                                 *set step on
                                                                 
                                                                 * send the actual post mimicking behavior of a manual send
                                                                 
                                                                 * foxpro sometimes interprets the amperstand as a special char to avoid this I do a trick with substitution
                                                                 ccorrected = strtran("/dealer/send_email.jtmpl?link_type=results#search_type=#ac_afflt=none", "#", "&")
                                                                 
                                                                 * note the post is a bit weird it both includes command line parameters as well as normal post variables, this is
                                                                 * the way the actual auto-trader post works during form submission by the way.
                                                               mstr2 = GetUrlStrFromPost( "www.autotrader.com", ccorrected, ;
                                                                                 lcCgiParams)

                                                               select maininfo
                                                               repl lemailsent with .T.
                                                               repl memail_rsp with mstr2
                                                               
                                                               if  "Thank you for contacting this seller" $ memail_rsp
                                                                        repl leconfirmed with .T.
                                                               else
                                                                        repl leconfirmed with .F.
                                                                        *messagebox("confirmation receive possible issue")
                                                               endif
                                                               
                                                               * some debug code
                                                               if .F.                                                                                 
                                                                        k2 = select()
                                                                        if ! used("memo1")
                                                                                 use memo1 in 0
                                                                        endif
                                                                        select memo1
                                                                        go top
                                                                        repl memo1 with mstr2
                                                                        messagebox(mstr2)
                                                                        select (k2)
                                                               endif
                                                               
                                                      endif
                                                      
                                             else
                                             
                                                      select maininfo
                                                      repl lemailsent with .F.
                                             
                                             endif
                                             
                                    
                                    endif
                           
                           endif
                  
                  endif
                  
         endif


enddo


return

*****************************************************************************************************************************
function TestParam( thisval )
*****************************************************************************************************************************

thisval = "B"

return

*****************************************************************************************************************************
function SkipAhead( cthis_string, tcStartText, nMatchNo)
*****************************************************************************************************************************
local k2

k2 = len( tcStartText)
npos2 = at( tcStartText, cthis_string, nMatchNo)
if npos2 == 0
         return .F.
else
         cthis_string = substr(cthis_string, npos2 + k2)
endif

return .T.

*****************************************************************************************************************************
function ParseStr( tcstring, tcStartText, nMatchNo, tcEndText)
*****************************************************************************************************************************

local k2
local cret
local npos
local nstartmark

if empty( tcStartText )
         npos = 1
else
         npos = at( tcStartText, tcstring, nMatchNo)
         if npos == 0
                  return "/N/F:1"
         endif
endif
nstartmark = npos

tcstring = substr( tcstring, nstartmark + len( tcStartText) )

npos = at( tcEndText, tcstring)

if npos == 0
         return "/N/F:2"
else

         cret  = left(tcstring, npos - 1 )
         tcstring = substr(tcstring, npos + len(tcEndText) )
endif

return cret

*****************************************************************************************************************************
function MB2( tcs1, tcn1, tcs2)
*****************************************************************************************************************************

local nret
if type("tcs2") != "L"
         nret = messagebox( tcs1, tcn1, tcs2 )
else
         if type("tcn1") != "L"
                  nret = messagebox( tcs1, tcn1, "AutoBot")
         else
                  nret = messagebox( tcs1, 0, "AutoBot")
         endif
endif
return nret

*****************************************************************************************************************************
*****************************************************************************************************************************
*****************************************************************************************************************************
*****************************************************************************************************************************
*****************************************************************************************************************************
*****************************************************************************************************************************