package Religion::Islam::PrayMind;
#
# Copyright (c) 2002 Tasmin Ahmad
# All rights reserved.
#
# Implements Class to connect and retrieve data from the PrayerMinder server
#
# This library is free software; you can redistribute it and/or modify
# it under the "Artistic License", as described in the accompanying
# License.txt file.
#
#
# DISCLAIMER
# THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# Acknowledgement
# The following people have contributed to the development of
# this tool, in addition to the copyright owner:
#
# 1. Mr. Tariq Chaudhary
# 2. Allied Software Corporation Islamabad, Pakistan; particularly the
# following folks:
# 2.1 Mr. S. Taimur Hassan
# 2.2 Ms. Shaista Rashid
# 2.3 Mr. Ijaz Rashid
#
use IO::Socket;
use XML::Parser;
use 5.006;
use strict;
use warnings;
require Exporter;
our @ISA = qw(Exporter);
# Items to export into callers namespace by default. Note: do not export
# names by default without a very good reason. Use EXPORT_OK instead.
# Do not simply export all your public functions/methods/constants.
# This allows declaration use Religion::Islam::PrayMind ':all';
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK
# will save memory.
our %EXPORT_TAGS = ( 'all' => [ qw(
) ] );
our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
our @EXPORT = qw($VERSION
eContinentsList eCountriesList eStatesList
eCitiesListForState eCitiesListForCountry
ePrayerTimes ePrayerTimeTable
IDS_NO_Error IDS_ERROR_OpenNotCalled IDS_ERROR_ClientIDNotSpecified IDS_ERROR_EmptyString
IDS_ERROR_GetListNotCalled IDS_ERROR_GetPrayerTimesNotCalled IDS_ERROR_EmptyList
);
our $VERSION = '1.01';
#define constant values for type of listing requested by caller
use constant eContinentsList => 0;
use constant eCountriesList => 1;
use constant eStatesList => 2;
use constant eCitiesListForState => 3;
use constant eCitiesListForCountry => 4;
use constant eCitiesSearchList => 5;
use constant ePrayerTimes => 6;
use constant ePrayerTimeTable => 7;
#define constant values for error codes
use constant IDS_NO_Error => 0;
use constant IDS_ERROR_OpenNotCalled => 1;
use constant IDS_ERROR_ClientIDNotSpecified => 2;
use constant IDS_ERROR_EmptyString => 3;
use constant IDS_ERROR_GetListNotCalled => 4;
use constant IDS_ERROR_GetPrayerTimesNotCalled => 5;
use constant IDS_ERROR_EmptyList => 6;
#define local constant values used to know type of listing obtained
use constant eNoData => 0;
use constant eLocationsList => 1;
use constant ePrayerTimings => 2;
use constant host => "www.prayerminder.com";
#use constant host => "209.185.200.148";
use constant EOL => "\015\012";
use constant BLANK => EOL x 2;
#class private global member variable declaration
#our ($host, $EOL, $BLANK);
#Hash to store error codes and their corresponding text
our @PMErrors =
(
"No Errors",
"Open function not called",
"Client ID not specified",
"Host returned an empty string please check that you have passed correct parameters",
"Call GetList function first",
"Call GetPrayerTimes function first",
"List does not contain elements"
);
#function that will return class reference
sub new
{
my ($class, %args) = @_;
my $self = bless \%args, $_[0];
if(!defined($args{ClientID}))
{
$args{ErrorCode} = IDS_ERROR_ClientIDNotSpecified;
}
else
{
$args{ErrorCode} = IDS_NO_Error;
$args{_DataType} = eNoData;
$args{_TimesData} =
{
nCityID => 0,
nCountryId => 0,
nStateID => 0,
sCityTitle => '',
sCityTimeZone => '',
sCityIslamicDate => '',
sCityGregorianDate => '',
sCityAsrFiqh => '',
CityPrayerTimes => {Fajr => "", Shurooq => "", Zuhr => "", AsrHanafi => "", AsrShafei => "", Maghrib => "", Isha => ""}
};
$args{_LocationsList} =
{
LocNames => [],
LocIDs => [],
nCurrItem => 0
};
}
$self;
}
# Preloaded methods go here.
# Autoload methods go after =cut, and are processed by the autosplit program.
#sends HTTP query to obtain the list required and saves the result in run time structure
sub GetList
{
#store parameters received to functions local variables
my ($self, $ListType, $nParentID) = @_;
my ($document, $nListType);
$nListType = eNoData;
#implementing error when GetList called before making a call to new function
if(!defined($self->{ErrorCode}))
{
$self->{ErrorCode} = IDS_ERROR_OpenNotCalled;
}
if($self->{ErrorCode} != IDS_NO_Error)
{
return;
}
$document = "/cgi-bin/PMCalc.cgi?F=X&I=" . $self->{ClientID} . "&R=";
#Get the required list if Open function called before calling it
if($self->{ErrorCode} != IDS_ERROR_OpenNotCalled)
{
#now it depends upon $ListType which list to obtain
#make the query string that will be passed to get continent, countrie and city listing
#asked for continents list
if($ListType == eContinentsList)
{
$document = $document . "LCN";
}
#asked for countries list
elsif($ListType == eCountriesList)
{
$document = $document . "LCY&CN=";
$document = $document . $nParentID;
}
#asked for cities list
elsif($ListType == eCitiesListForCountry)
{
$document = $document . "LCT&CY=";
$document = $document . $nParentID;
}
#print " in GetList 1<BR>\n";
#establish the connection to the host
my ($remote, $StartData, $aline);
$remote = IO::Socket::INET->new( Proto => "tcp",
PeerAddr => host,
PeerPort => "http(80)",
);
#print " in GetList , doc=" . $document . "<BR>\n";
#error message to report if connection is not established with host
unless($remote)
{
die "Cannot connect to http daemon on host " . host;
}
print $remote "GET $document HTTP/1.0" . BLANK;
$StartData = 0;
#$DesiredString = "";
#while remote is returning cetain text
while(($StartData < 1) && (defined ($aline = <$remote>)))
{
#print " > " . $aline . "<br>\n";
#check if line is a blank line, after which the XML document follows
if($aline eq "\r\n")
{
$StartData = 1;
}
}
# If we got any data, parse it
if($StartData == 1)
{
# Make a call to function that will xml data returned by server
# the XML data will be parsed by XML parser and information will be
# stored in class member variables
ParseXMLFile($self, $remote, eLocationsList);
}
close $remote;
#print " *** GetList ErrorCode: " . $self->{ErrorCode} . " ErrorText: " . $self->{ErrorText} . "<BR>\n";
#you get the required text from host
# if($self->{_DataType} != eLocationsList)
# {
#discard errors previously set
#Error Code IDS_ERROR_GetListNotCalled "Call GetList function first";
#Error Code IDS_ERROR_GetPrayerTimesNotCalled "Call GetPrayerTimes function first";
#Error Code IDS_ERROR_EmptyList "Empty List";
# $self->{ErrorCode} = IDS_NO_Error
# if($self->{ErrorCode} == IDS_ERROR_GetListNotCalled || $self->{ErrorCode} == IDS_ERROR_GetPrayerTimesNotCalled ||
# $self->{ErrorCode} == IDS_ERROR_EmptyList);
# }
#check whether some string is returned by host
# if($self->{_DataType} != eLocationsList)
# {
# $self->{ErrorCode} = IDS_ERROR_EmptyString
# if($self->{ErrorCode}) == IDS_NO_Error;
# }
#discard error that was set that empty string returned by host
# elsif($self->{ErrorCode} == IDS_ERROR_EmptyString)
# {
# $self->{ErrorCode} = IDS_NO_Error;
# }
}
}
#functions that are called when asked for listing of continents, countries and cities
#returns number of elements in the list retreived by GetList
sub GetListSize
{
#store parameters received to functions local variables
my $self = shift;
#$nListType is set to eLocationsList when asked for continents, countries or city listing
if($self->{_DataType} != eLocationsList)
{
$self->{ErrorCode} = IDS_ERROR_GetListNotCalled;
return -1;
}
else
{
#check for empty list
if($#{$self->{_LocationsList}->{LocNames}} < 0)
{
$self->{ErrorCode} = IDS_ERROR_EmptyList;
}
return $#{$self->{_LocationsList}->{LocNames}} + 1;
}
}
#returns parent element's ID, to which this list belongs
#sub GetParentID
#{
# #$nListType is set to eLocationsList when asked for continents, countries or city listing
# if($nListType != eLocationsList)
# {
# $ErrorCode = IDS_ERROR_GetListNotCalled;
# return -1;
# }
# else
# {
# return $ParentID;
# }
#}
#returns ID of the current element from the list
sub GetElementID
{
my $self = shift;
#$nListType is set to eLocationsList when asked for continents, countries or city listing
if($self->{_DataType} != eLocationsList)
{
$self->{ErrorCode} = IDS_ERROR_GetListNotCalled;
return -1;
}
else
{
return $self->{_LocationsList}->{LocIDs}->[$self->{_LocationsList}->{nCurrItem}];
}
}
#returns the name of the current element from the list
sub GetElementName
{
my $self = shift;
#$nListType is set to eLocationsList when asked for continents, countries or city listing
if($self->{_DataType} != eLocationsList)
{
$self->{ErrorCode} = IDS_ERROR_GetListNotCalled;
return -1;
}
else
{
return $self->{_LocationsList}->{LocNames}->[$self->{_LocationsList}->{nCurrItem}];
}
}
#moves to next element in the list
sub NextElement
{
my $self = shift;
#$nListType is set to eLocationsList when asked for continents, countries or city listing
if($self->{_DataType} != eLocationsList)
{
$self->{ErrorCode} = IDS_ERROR_GetListNotCalled;
return -1;
}
else
{
if($self->{_LocationsList}->{nCurrItem} >= $#{$self->{_LocationsList}->{LocNames}})
{
return -1;
}
elsif($self->{_LocationsList}->{nCurrItem} < $#{$self->{_LocationsList}->{LocNames}})
{
$self->{_LocationsList}->{nCurrItem}++;
return 0;
}
}
}
#sends HTTP query to obtain prayer times for the required city and saves the
#results in run time structure
sub GetPrayerTimes
{
my ($self, $CityID) = @_;
my($nListType, $document, $remote, $StartData, $aline);
$nListType = eNoData;
#implementing error when GetPrayerTimes called before making a call to Open function
unless (host ne "")
{
$self->{ErrorCode} = IDS_ERROR_OpenNotCalled;
}
$document = "/cgi-bin/PMCalc.cgi?F=X&I=" . $self->{ClientID} . "&R=";
#Get the required list if Open function called before calling it
if($self->{ErrorCode} != IDS_ERROR_OpenNotCalled)
{
#store parameters received to functions local variables
#document is query string that will be passed to host
$document = $document . "GD&CT=";
$document = $document . $CityID;
#establish the connection to the host
$remote = IO::Socket::INET->new( Proto => "tcp",
PeerAddr => host,
PeerPort => "http(80)",
);
#report an error if connection to host is not established
unless($remote)
{
die "cannot connect to http daemon on host ". host;
}
print $remote "GET $document HTTP/1.0" . BLANK;
$StartData = 0;
#while remote is returning cetain text
while(($StartData < 1) && (defined ($aline = <$remote>)))
{
#print " > " . $aline . "\n";
#check if line is a blank line, after which the XML document follows
if($aline eq "\r\n")
{
$StartData = 1;
}
}
#make a call to function that will write response returned by host to file
#file will be parsed by XML parser and desired information will be stored in class member variables
ParseXMLFile($self, $remote, ePrayerTimings);
#close the connection established to host
close $remote;
#print " *** GetPrayerTimes ErrorCode: " . $self->{ErrorCode} . " ErrorText: " . $self->{ErrorText} . "<BR>\n";
# if($self->{_DataType} == ePrayerTimings)
# {
#discard previously set errors
#Error Code IDS_ERROR_GetListNotCalled "Call GetList function first";
#Error Code IDS_ERROR_GetPrayerTimesNotCalled "Call GetPrayerTimes function first";
#Error Code IDS_ERROR_EmptyList "Empty List";
# $self->{ErrorCode} = IDS_NO_Error
# if($self->{ErrorCode} == IDS_ERROR_GetListNotCalled || $self->{ErrorCode} == IDS_ERROR_GetPrayerTimesNotCalled ||
# $self->{ErrorCode} == IDS_ERROR_EmptyList);
# }
#check whether some string is returned by host
# if($self->{_DataType} != ePrayerTimings)
# {
# $self->{ErrorCode} = IDS_ERROR_EmptyString
# if($self->{ErrorCode}) == IDS_NO_Error;
# }
#discard error that was set that empty string returned by host
# elsif($self->{ErrorCode} == IDS_ERROR_EmptyString)
# {
# $self->{ErrorCode} = IDS_NO_Error;
# }
}
}
#functions that will be called when asked for prayer timings
#returns parent element(Country's ID) to which this city belongs
sub GetCountryID
{
my $self = shift;
#$nListType is set to ePrayerTimings when asked for prayer timings
if($self->{_DataType} != ePrayerTimings)
{
$self->{ErrorCode} = IDS_ERROR_GetPrayerTimesNotCalled;
return -1;
}
else
{
return $self->{_TimesData}->{nCountryID};
}
}
#returns ID of the city
sub CityID
{
my $self = shift;
#$nListType is set to ePrayerTimings when asked for prayer timings
if($self->{_DataType} != ePrayerTimings)
{
$self->{ErrorCode} = IDS_ERROR_GetPrayerTimesNotCalled;
return -1;
}
else
{
return $self->{_TimesData}->{nCityID};
}
}
#returns Title of the city
sub CityTitle
{
my $self = shift;
#$nListType is set to ePrayerTimings when asked for prayer timings
if($self->{_DataType} != ePrayerTimings)
{
$self->{ErrorCode} = IDS_ERROR_GetPrayerTimesNotCalled;
return -1;
}
else
{
return $self->{_TimesData}->{sCityTitle};
}
}
#returns time zone of the city
sub CityTimeZone
{
my $self = shift;
#$nListType is set to ePrayerTimings when asked for prayer timings
if($self->{_DataType} != ePrayerTimings)
{
$self->{ErrorCode} = IDS_ERROR_GetPrayerTimesNotCalled;
return -1;
}
else
{
return $self->{_TimesData}->{sCityTimeZone};
}
}
#returns Islamic date for city
sub CityIslamicDate
{
my $self = shift;
#$nListType is set to ePrayerTimings when asked for prayer timings
if($self->{_DataType} != ePrayerTimings)
{
$self->{ErrorCode} = IDS_ERROR_GetPrayerTimesNotCalled;
return -1;
}
else
{
return $self->{_TimesData}->{sCityIslamicDate};
}
}
#returns Gregorian date for city
sub CityGregorianDate
{
my $self = shift;
#$nListType is set to ePrayerTimings when asked for prayer timings
if($self->{_DataType} != ePrayerTimings)
{
$self->{ErrorCode} = IDS_ERROR_GetPrayerTimesNotCalled;
return -1;
}
else
{
return $self->{_TimesData}->{sCityGregorianDate};
}
}
#returns default/official Asr Fiqh for city
sub CityAsrFiqh
{
my $self = shift;
#$nListType is set to ePrayerTimings when asked for prayer timings
if($self->{_DataType} != ePrayerTimings)
{
$self->{ErrorCode} = IDS_ERROR_GetPrayerTimesNotCalled;
return -1;
}
else
{
return $self->{_TimesData}->{sCityAsrFiqh};
}
}
#returns requested prayer time for city
sub CityPrayerTime
{
my ($self, $PrayerName) = @_;
#$nListType is set to ePrayerTimings when asked for prayer timings
if($self->{_DataType} != ePrayerTimings)
{
$self->{ErrorCode} = IDS_ERROR_GetPrayerTimesNotCalled;
return -1;
}
else
{
return $self->{_TimesData}->{CityPrayerTimes}->{$PrayerName};
}
}
#returns 0 for no error and non zero error code for error
sub GetError
{
my $self = shift;
return $self->{ErrorCode};
}
#returns error string if error function will return non zero
sub GetErrorText
{
my $self = shift;
my $err = $self->{ErrorCode};
if(($err >= IDS_NO_Error) && ($err <= IDS_ERROR_EmptyList))
{
return $PMErrors[$err];
}
else
{
if(defined($self->{ErrorText}))
{
return $self->{ErrorText}
}
else
{
return "Error text not received from server.";
}
}
}
#Function that will parse XML file
sub ParseXMLFile
{
#access arguments passed
my ($self, $xmlstream, $List) = @_;
#discard all element names previously stored in an array
$#{$self->{_LocationsList}->{LocNames}} = -1;
#discard all element IDs previously stored in an array
$#{$self->{_LocationsList}->{LocIDs}} = -1;
$self->{_LocationsList}->{nCurrItem} = 0;
#declare parser object
my $Parser = new XML::Parser(Style=>'Stream');
#variable that will hold the text appearing within start and end tag that is country name
#my ($csText);
$Parser->{PMText} = '';
$Parser->{PMListType} = $List;
$Parser->{PMObj} = $self;
#socket having response from the server
$Parser->parse($xmlstream);
$self->{_LocationsList}->{nCurrItem} = 0;
#Parser calls StartTag sub when it reads opening tag from XML file
sub StartTag
{
#first argument is reference to parser object and second is string containing element type name
my ($expat,$elementtype) = @_;
#print " -- StartTag: elementtype = " . $elementtype . "<br>\n";
if($elementtype eq "PMxml")
{
my $datatype = %_->{datatype};
#print " -- StartTag: datatype = " . $datatype . "<br>\n";
if($datatype eq "Error")
{ $expat->{PMObj}->{_DataType} = eNoData; }
elsif($datatype eq "Errors")
{ $expat->{PMObj}->{_DataType} = eNoData; }
elsif($datatype eq "PrayerTimes")
{ $expat->{PMObj}->{_DataType} = ePrayerTimings; }
else
{ $expat->{PMObj}->{_DataType} = eLocationsList; }
}
}
#Parser calls Text sub when it sees characters. $_ contains text up to next tag, end tag,
# processing instruction, or comment
sub Text
{
my($expat) = @_;
#print " -- expat = $expat, text= " . $_ . "<br>\n";
#translate new line to single space
tr/\n/ /;
#discard all leading white space characters
s/^\s+//;
#discard all trailing white space characters
s/\s+$//;
#return empty string if nothing found as text
return if $_ eq "";
#if there is found some text within start and end tag then store it to $parabuf
$expat->{PMText} = $_;
#print "text= " . $_ . "<br>\n";
}
#Parser calls EndTag sub when it reads end tag from XML file
sub EndTag
{
#first argument is reference to parser object and second is string containing element type name
my ($expat,$elementtype) = @_;
my $self = $expat->{PMObj};
my $nX = $self->{_LocationsList}->{nCurrItem};
#print " -- End: index = " . $nX . ", element type = " . $elementtype . ", value =" . $expat->{PMText} . "<br>\n";
#print " > EndTag: DataType = " . $self->{_DataType} . "<BR>\n";
#get name and ID from XML file when asked for continents, countries or cities listing
if($self->{_DataType} == eLocationsList)
{
if ($elementtype eq "LocID")
{
#Storing element ID accessed, to an array
$self->{_LocationsList}->{LocIDs}->[$nX] = $expat->{PMText};
}
if ($elementtype eq "Name")
{
#Storing name accessed, to an array
$self->{_LocationsList}->{LocNames}->[$nX] = $expat->{PMText};
$self->{_LocationsList}->{nCurrItem} = $nX + 1;
}
}
#asked for prayer times
elsif($self->{_DataType} == ePrayerTimings)
{
#get city local id
if ($elementtype eq "LocID")
{
$self->{_TimesData}->{nCityID} = $expat->{PMText};
}
#get city title
if ($elementtype eq "LocTitle")
{
$self->{_TimesData}->{sCityTitle} = $expat->{PMText};
}
#get Country ID
if ($elementtype eq "CountryID")
{
$self->{_TimesData}->{nCountryID} = $expat->{PMText};
}
#get State ID
if ($elementtype eq "StateID")
{
$self->{_TimesData}->{nStateID} = $expat->{PMText};
}
#get city title
if ($elementtype eq "LocTitle")
{
$self->{_TimesData}->{sCityTitle} = $expat->{PMText};
}
#get city time zone
if ($elementtype eq "LocTimeZone")
{
$self->{_TimesData}->{sCityTimeZone} = $expat->{PMText};
}
#get city islamic date
if ($elementtype eq "IDate")
{
$self->{_TimesData}->{sCityIslamicDate} = $expat->{PMText};
}
#get city gregorian date
if ($elementtype eq "GDate")
{
$self->{_TimesData}->{sCityGregorianDate} = $expat->{PMText};
}
#get city As Fiqh
if ($elementtype eq "AsrFiqh")
{
$self->{_TimesData}->{sCityAsrFiqh} = $expat->{PMText};
}
#get fajr timing
if ($elementtype eq "Fajr")
{
$self->{_TimesData}->{CityPrayerTimes}->{$elementtype} = $expat->{PMText};
}
#get Shurooq timing
if ($elementtype eq "Shurooq")
{
$self->{_TimesData}->{CityPrayerTimes}->{$elementtype} = $expat->{PMText};
}
#get Zuhr timing
if ($elementtype eq "Zuhr")
{
$self->{_TimesData}->{CityPrayerTimes}->{$elementtype} = $expat->{PMText};
}
#get AsrHanafi timing
if ($elementtype eq "AsrHanafi")
{
$self->{_TimesData}->{CityPrayerTimes}->{$elementtype} = $expat->{PMText};
}
#get AsrShafei timing
if ($elementtype eq "AsrShafei")
{
$self->{_TimesData}->{CityPrayerTimes}->{$elementtype} = $expat->{PMText};
}
#get Maghrib timing
if ($elementtype eq "Maghrib")
{
$self->{_TimesData}->{CityPrayerTimes}->{$elementtype} = $expat->{PMText};
}
#get Isha timing
if ($elementtype eq "Isha")
{
$self->{_TimesData}->{CityPrayerTimes}->{$elementtype} = $expat->{PMText};
}
}
else
{
#get error code
if ($elementtype eq "ErrorCode")
{
$self->{ErrorCode} = $expat->{PMText};
$self->{ErrorCode} += 500 if $self->{ErrorCode} < 500;
}
#get error text
if ($elementtype eq "ErrorText")
{
$self->{ErrorText} = $expat->{PMText};
}
}
$expat->{PMText} = '';
}
}
1;
__END__
# Below is stub documentation for your module. You better edit it!
=head1 NAME
Religion::Islam::PrayMind - a Perl module that is a client for PrayerMinder server
=head1 SYNOPSIS
use Religion::Islam::PrayMind;
$p1 = new PMConnect(ClientID => "xxxx");
#where xxxx is the client web site's ID at the PrayerMinder server.
$p1->GetList(<listtype> [, <parentID>);
$p1->GetPrayerTimes(<cityID>);
=head1 DESCRIPTION
This module provides ways to obtain data from the PrayerMinder server.
It is built on top of L<XML::Parser>. Each call to L<GetList> or L<GetPrayerTimes>
methods opens a socket connection to the PrayerMinder server,
and creates a new instance of XML::Parser which is then used to parse the
data received through the socket.
B<Example>
The following files show example usage of the PrayMind module:
=over 4
=item - ContinentsList.pl
=item - CountriesList.pl
=item - CitiesList.pl
=item - CityTimes.pl
=back
=head2 EXPORT
Exported constants and variables
=over 4
=item * Version of the module.
=over 4
=item . $VERSION
=back
=item * LIST_TYPE
=over 4
=item . eContinentsList
=item . eCountriesList
=item . eStatesList
=item . eCitiesListForState
=item . eCitiesListForCountry
=item . ePrayerTimes
=item . ePrayerTimeTable
=back
=item * Error_ID
=over 4
=item . IDS_NO_Error
=item . IDS_ERROR_OpenNotCalled
=item . IDS_ERROR_ClientIDNotSpecified
=item . IDS_ERROR_EmptyString
=item . IDS_ERROR_GetListNotCalled
=item . IDS_ERROR_GetPrayerTimesNotCalled
=item . IDS_ERROR_EmptyList
=back
=back
=head1 METHODS
=over 4
=item new(ClientID => "CLIENTID")
This is a class method, the constructor for PMConnect. Client ID for
the caller's PrayerMinder account is passed as keyword value pair.
=item GetList(LIST_TYPE [, PARENT_ID])
This method retrieves a list of locations.
B<PARAMETERS>
=over 4
=item * LIST_TYPE
Specifies type of list desired. The properties and
elementes of the list can be retrieved using relevant methods
listed later. L<GetError> and L<GetErrorText> must be called
before calling any other methods to make sure no errors
occurred. Possible values for LIST_TYPE are listed below:
=over 4
=item . eContinentsList
=item . eCountriesList
=item . eStatesList (not yet implemented)
=item . eCitiesListForState (not yet implemented)
=item . eCitiesListForCountry
=item . eCitiesSearchList (not yet implemented)
=back
=item * PARENT_ID
Not needed if LIST_TYPE is I<eContinentsList>, required otherwise.
Specifies the parent whose children are to be listed.
=back
=item GetListSize
B<Returns> integer
Called after L<GetList> to obtain the number of locations in the list.
=item GetElementID
B<Returns> integer
Called after L<GetList> to obtain the number of locations in the list.
=item GetElementName
B<Returns> string
Called after L<GetList> to obtain the number of locations in the list.
=item NextElement
B<Returns> I<true> if successful, I<false> for no more elements.
Called after L<GetList> to obtain the number of locations in the list.
=item GetPrayerTimes(CITY_ID)
This method retrieves prayer times for the requested city. CITY_ID specifies
the ID of the city requested. L<GetError> and L<GetErrorText> must be called
before calling any other methods to make sure no errors
occurred.
=item CityID
B<Returns> integer
Called after L<GetPrayerTimes> to obtain the ID for the city.
=item CityTitle
B<Returns> string
Called after L<GetPrayerTimes> to obtain the title for the city.
=item CityTimeZone
B<Returns> string (floating point decimal number)
Called after L<GetPrayerTimes> to obtain the time zone for the city.
=item CityIslamicDate
B<Returns> string
Called after L<GetPrayerTimes> to obtain today's Islamic date for the city.
=item CityGregorianDate
B<Returns> string
Called after L<GetPrayerTimes> to obtain today's Gregorian date for the city.
=item CityAsrFiqh
B<Returns> string
Called after L<GetPrayerTimes> to obtain the default Asr fiqh method for
the city.
=item CityPrayerTime(PRAYER_NAME)
B<Returns> string
Called after L<GetPrayerTimes> to obtain the requested prayer time for the city.
B<PARAMETERS>
=over 4
=item * PRAYER_NAME
Specifies prayer whose time is desired. Possible values for PRAYER_NAME are listed below:
=over 4
=item . Fajr
=item . Shurooq
=item . Zuhr
=item . AsrHanafi
=item . AsrShafei
=item . Maghrib
=item . Isha
=back
=back
=item GetError
B<Returns> L<Error_ID>
Called after L<GetPrayerTimes> or L<GetList> to obtain the error ID. Returns
values indicates error ID or IDS_NoError if no errors occurred.
=item GetErrorText
B<Returns> string
Called after L<GetError> to obtain the text description of the last error.
=back
=head1 AUTHOR
Tasmin Ahmad, E<lt>support@prayerminder.comE<gt>
Web site: L<http://www.prayerminder.com/>
=cut