--  ========================================================================
--
--  FILE: datastore.lua
--
--  SERVICES: 
--     Data store management script 
--     The OnDemand 2.0 datastore stores data to be displayed in the client
--     Exports functions for storing data from datapackages into the store
--     Also exports functions for retrieval of the data from the interface layer
--
--  ========================================================================
--  ========================================================================
--
--               Copyright  1999-2006 QUALCOMM Incorporated
--                     All Rights Reserved.
--                   QUALCOMM Proprietary/GTDR
--
--  ========================================================================
--  ========================================================================

------------------------------------------------------------------------------

--[[

API Exposed:
 
  For boot script:
  datastore.initNewStore()
  datastore.readFromFS()

  For fillstore:
  datastore.clear()

  For Fetch:
  datastore.run_payload(expire_time)
  datastore.get_username()
  datastore.set_username(username)
  datastore.get_password()
  datastore.set_password(password)
  datastore.get_showtime()
  datastore.set_showtime(showtime)
  datastore.get_expiretime()
  datastore.set_expiretime()
  datastore.get_http_status_code()
  datastore.set_http_statud_code(status_code)
  datastore.get_last_update_time()
  datastore.set_last_update_time(last_update_time)
  datastore.get_last_pathid()
  datastore.set_last_pathid(last_pathid)
  datastore.get_mdn()
  datastore.set_mdn(MDN)
  datastore.getZipCode()
  datastore.setZipCode(zipCode)
  datastore.set_miui_base(miui_base)
  datastore.get_miui_base()
  datastore.set_miui_triglet(miui_triglet)
  datastore.get_miui_triglet()
  datastore.set_ondemand_triglet(ondemand_triglet)
  datastore.get_ondemand_triglet()
   
  For debug:
  datastore.dumpstore()

Globals Exported:
  datastore (table)
  SUCCESS, FAILURE (variables)

--]]

--these flags allow compilation on both PC Lua and ILua 
_utlua = 1 
_pclua = nil

if not _pclua then
	loadlib("lpersist")
	loadlib("lfile")
end

SUCCESS = 0
FAILURE = -1

-- Create a package

local P = {}

datastore = P

--[[ 
 ensure that I still have access to global env before I change
the env to this package
--]]
setmetatable(P, {__index = _G})


--setting environment to this package
setfenv(1,P)


--stop all debug messages (useful if too many debug statements are being seen in the log)
removeDebugMessages = false

if removeDebugMessages then
   function print()

   end

end


--***************************************************************

-- DATASTORE CANONICAL TABLES INITIALIZATION

--***************************************************************

--[[-------------------------------------------------------------

Function: initNewStore()

 Initialize a fresh copy of the datastore. Create the canonical 
 tables and initialize then with false data

Parameters: None
Return value: None




--]]-------------------------------------------------------------

function initNewStore()

	print ("-- Initializing a fresh copy of the data store (first-run) --")
	
	


	--Datastore internal flags, to maintain state
	internal = {
				  IsFakeData = true,      --set to true when datastore does not have real data
				  IsInit = false,         --set to true when datastore is initialized
			  	  IsBeingUpdated = true,  --set to true when datastore is in the process of
			  						       --being updated (to be used as a datastore lock)
				  scriptPersistReqd = false,
 			
		      }

	--stores configuration information for use by fetch/datastore
	
	config = {
			application = "ondemand", --always "ondemand" for now
			
			--these variables are for fetch use
			lastviewed = 0,           
			lastupdate = 0,
			nextupdates = { 0,0,0,},
			nextshowtime = 0,
			expiretime = 0,
			
		  }
		  

	file.remove("datastore_script.dat")
	scripts = nil

        --ToDo: Add code here for initializing some config data from GetDeviceInfo()
	
	--stores the current images available to the on-demand client
	--format: [short_name] = "full FS path"
	
	images = {

			["news/story/icon"]	=  "fs:/~/images/news/story/",
			["sports/story/icon"]	=  "fs:/~/images/sports/story/",


			["news/health/0"]	=  "fs:/~/images/news/health/health_news_25x25.png",
			["news/features/0"]	=  "fs:/~/images/news/features/features_news_25x25.png",
			["news/politics/0"]	=  "fs:/~/images/news/politics/politics_news_25x25.png",
			["news/science/0"]	=  "fs:/~/images/news/science/science_news_25x25.png",
			["news/showbiz/0"]	=  "fs:/~/images/news/showbiz/showbiz_news_25x25.png",
			["news/strange/0"]	=  "fs:/~/images/news/strange/strange_news_25x25.png",
			["news/technology/0"]	=  "fs:/~/images/news/technology/technology_news_25x25.png",
			["news/top_stories/0"]	=  "fs:/~/images/news/top_stories/top_stories_25x25.png",
			["news/usa/0"]	=  "fs:/~/images/news/usa/usa_news_25x25.png",
			["news/world/0"]	=  "fs:/~/images/news/world/world_news_25x25.png",
			["news/health/1"]	=  "fs:/~/images/news/health/health_news_47x47.png",
			["news/features/1"]	=  "fs:/~/images/news/features/features_news_47x47.png",
			["news/politics/1"]	=  "fs:/~/images/news/politics/politics_news_47x47.png",
			["news/science/1"]	=  "fs:/~/images/news/science/science_news_47x47.png",
			["news/showbiz/1"]	=  "fs:/~/images/news/showbiz/showbiz_news_47x47.png",
			["news/strange/1"]	=  "fs:/~/images/news/strange/strange_news_47x47.png",
			["news/technology/1"]	=  "fs:/~/images/news/technology/technology_news_47x47.png",
			["news/top_stories/1"]	=  "fs:/~/images/news/top_stories/top_stories_47x47.png",
			["news/usa/1"]	=  "fs:/~/images/news/usa/usa_news_47x47.png",
			["news/world/1"]	=  "fs:/~/images/news/world/world_news_47x47.png",

	
			["weather/alert/0"]	=  "fs:/~/images/weather/alert/alert_47x47.png",
			["weather/blizzard/0"]	=  "fs:/~/images/weather/blizzard/blizzard_47x47.png",
			["weather/cloudy/0"]	=  "fs:/~/images/weather/cloudy/cloudy_47x47.png",
			["weather/cold_chilly/0"]	=  "fs:/~/images/weather/cold_chilly/cold_chilly_47x47.png",
			["weather/cool/0"]	=  "fs:/~/images/weather/cool/cool_47x47.png",
			["weather/drizzle/0"]	=  "fs:/~/images/weather/drizzle/drizzle_47x47.png",
			["weather/dry/0"]	=  "fs:/~/images/weather/dry/dry_47x47.png",
			["weather/fine_clear/0"]	=  "fs:/~/images/weather/fine_clear/fine_clear_47x47.png",
			["weather/fog/0"]	=  "fs:/~/images/weather/fog/fog_47x47.png",
			["weather/freezing/0"]	=  "fs:/~/images/weather/freezing/freezing_47x47.png",
			["weather/freezing_rain/0"]	=  "fs:/~/images/weather/freezing_rain/freezing_rain_47x47.png",
			["weather/frost/0"]	=  "fs:/~/images/weather/frost/frost_47x47.png",
			["weather/hail/0"]	=  "fs:/~/images/weather/hail/hail_47x47.png",
			["weather/haze/0"]	=  "fs:/~/images/weather/haze/haze_47x47.png",
			["weather/hot/0"]	=  "fs:/~/images/weather/hot/hot_47x47.png",
			["weather/humid_wet/0"]	=  "fs:/~/images/weather/humid_wet/humid_wet_47x47.png",
			["weather/isolated_showers/0"]	=  "fs:/~/images/weather/isolated_showers/isolated_showers_47x47.png",
			["weather/mist/0"]	=  "fs:/~/images/weather/mist/mist_47x47.png",
			["weather/overcast/0"]	=  "fs:/~/images/weather/overcast/overcast_47x47.png",
			["weather/rain/0"]	=  "fs:/~/images/weather/rain/rain_47x47.png",
			["weather/rain_heavy/0"]	=  "fs:/~/images/weather/rain_heavy/rain_heavy_47x47.png",
			["weather/sandstorm/0"]	=  "fs:/~/images/weather/sandstorm/sandstorm_47x47.png",
			["weather/scattered_showers/0"]	=  "fs:/~/images/weather/scattered_showers/scattered_showers_47x47.png",
			["weather/sleet/0"]	=  "fs:/~/images/weather/sleet/sleet_47x47.png",
			["weather/smoke/0"]	=  "fs:/~/images/weather/smoke/smoke_47x47.png",
			["weather/snow_heavy/0"]	=  "fs:/~/images/weather/snow_heavy/snow_heavy_47x47.png",
			["weather/snow_light/0"]	=  "fs:/~/images/weather/snow_light/snow_light_47x47.png",
			["weather/snow_showers/0"]	=  "fs:/~/images/weather/snow_showers/snow_showers_47x47.png",
			["weather/sunny_fair/0"]	=  "fs:/~/images/weather/sunny_fair/sunny_fair_47x47.png",
			["weather/sunny_intervals/0"]	=  "fs:/~/images/weather/sunny_intervals/sunny_intervals_47x47.png",
			["weather/sunny_periods/0"]	=  "fs:/~/images/weather/sunny_periods/sunny_periods_47x47.png",
			["weather/thunder_lightning/0"]	=  "fs:/~/images/weather/thunder_lightning/thunder_lightning_47x47.png",
			["weather/warm/0"]	=  "fs:/~/images/weather/warm/warm_47x47.png",
			["weather/windy/0"]	=  "fs:/~/images/weather/windy/windy_47x47.png",
			["weather/alert/1"]	=  "fs:/~/images/weather/alert/alert_87x70.png",
			["weather/blizzard/1"]	=  "fs:/~/images/weather/blizzard/blizzard_87x70.png",
			["weather/cloudy/1"]	=  "fs:/~/images/weather/cloudy/cloudy_87x70.png",
			["weather/cold_chilly/1"]	=  "fs:/~/images/weather/cold_chilly/cold_chilly_87x70.png",
			["weather/cool/1"]	=  "fs:/~/images/weather/cool/cool_87x70.png",
			["weather/drizzle/1"]	=  "fs:/~/images/weather/drizzle/drizzle_87x70.png",
			["weather/dry/1"]	=  "fs:/~/images/weather/dry/dry_87x70.png",
			["weather/fine_clear/1"]	=  "fs:/~/images/weather/fine_clear/fine_clear_87x70.png",
			["weather/fog/1"]	=  "fs:/~/images/weather/fog/fog_87x70.png",
			["weather/freezing/1"]	=  "fs:/~/images/weather/freezing/freezing_87x70.png",
			["weather/freezing_rain/1"]	=  "fs:/~/images/weather/freezing_rain/freezing_rain_87x70.png",
			["weather/frost/1"]	=  "fs:/~/images/weather/frost/frost_87x70.png",
			["weather/hail/1"]	=  "fs:/~/images/weather/hail/hail_87x70.png",
			["weather/haze/1"]	=  "fs:/~/images/weather/haze/haze_87x70.png",
			["weather/hot/1"]	=  "fs:/~/images/weather/hot/hot_87x70.png",
			["weather/humid_wet/1"]	=  "fs:/~/images/weather/humid_wet/humid_wet_87x70.png",
			["weather/isolated_showers/1"]	=  "fs:/~/images/weather/isolated_showers/isolated_showers_87x70.png",
			["weather/mist/1"]	=  "fs:/~/images/weather/mist/mist_87x70.png",
			["weather/overcast/1"]	=  "fs:/~/images/weather/overcast/overcast_87x70.png",
			["weather/rain/1"]	=  "fs:/~/images/weather/rain/rain_87x70.png",
			["weather/rain_heavy/1"]	=  "fs:/~/images/weather/rain_heavy/rain_heavy_87x70.png",
			["weather/sandstorm/1"]	=  "fs:/~/images/weather/sandstorm/sandstorm_87x70.png",
			["weather/scattered_showers/1"]	=  "fs:/~/images/weather/scattered_showers/scattered_showers_87x70.png",
			["weather/sleet/1"]	=  "fs:/~/images/weather/sleet/sleet_87x70.png",
			["weather/smoke/1"]	=  "fs:/~/images/weather/smoke/smoke_87x70.png",
			["weather/snow_heavy/1"]	=  "fs:/~/images/weather/snow_heavy/snow_heavy_87x70.png",
			["weather/snow_light/1"]	=  "fs:/~/images/weather/snow_light/snow_light_87x70.png",
			["weather/snow_showers/1"]	=  "fs:/~/images/weather/snow_showers/snow_showers_87x70.png",
			["weather/sunny_fair/1"]	=  "fs:/~/images/weather/sunny_fair/sunny_fair_87x70.png",
			["weather/sunny_intervals/1"]	=  "fs:/~/images/weather/sunny_intervals/sunny_intervals_87x70.png",
			["weather/sunny_periods/1"]	=  "fs:/~/images/weather/sunny_periods/sunny_periods_87x70.png",
			["weather/thunder_lightning/1"]	=  "fs:/~/images/weather/thunder_lightning/thunder_lightning_87x70.png",
			["weather/warm/1"]	=  "fs:/~/images/weather/warm/warm_87x70.png",
			["weather/windy/1"]	=  "fs:/~/images/weather/windy/windy_87x70.png",
			["weather/blizzard/2"]	=  "fs:/~/images/weather/blizzard/blizzard_36x36.png",
			["weather/cloudy/2"]	=  "fs:/~/images/weather/cloudy/cloudy_36x36.png",
			["weather/cold_chilly/2"]	=  "fs:/~/images/weather/cold_chilly/cold_chilly_36x36.png",
			["weather/cool/2"]	=  "fs:/~/images/weather/cool/cool_36x36.png",
			["weather/drizzle/2"]	=  "fs:/~/images/weather/drizzle/drizzle_36x36.png",
			["weather/dry/2"]	=  "fs:/~/images/weather/dry/dry_36x36.png",
			["weather/fine_clear/2"]	=  "fs:/~/images/weather/fine_clear/fine_clear_36x36.png",
			["weather/fog/2"]	=  "fs:/~/images/weather/fog/fog_36x36.png",
			["weather/freezing/2"]	=  "fs:/~/images/weather/freezing/freezing_36x36.png",
			["weather/freezing_rain/2"]	=  "fs:/~/images/weather/freezing_rain/freezing_rain_36x36.png",
			["weather/frost/2"]	=  "fs:/~/images/weather/frost/frost_36x36.png",
			["weather/hail/2"]	=  "fs:/~/images/weather/hail/hail_36x36.png",
			["weather/haze/2"]	=  "fs:/~/images/weather/haze/haze_36x36.png",
			["weather/hot/2"]	=  "fs:/~/images/weather/hot/hot_36x36.png",
			["weather/humid_wet/2"]	=  "fs:/~/images/weather/humid_wet/humid_wet_36x36.png",
			["weather/isolated_showers/2"]	=  "fs:/~/images/weather/isolated_showers/isolated_showers_36x36.png",
			["weather/mist/2"]	=  "fs:/~/images/weather/mist/mist_36x36.png",
			["weather/overcast/2"]	=  "fs:/~/images/weather/overcast/overcast_36x36.png",
			["weather/rain/2"]	=  "fs:/~/images/weather/rain/rain_36x36.png",
			["weather/rain_heavy/2"]	=  "fs:/~/images/weather/rain_heavy/rain_heavy_36x36.png",
			["weather/sandstorm/2"]	=  "fs:/~/images/weather/sandstorm/sandstorm_36x36.png",
			["weather/scattered_showers/2"]	=  "fs:/~/images/weather/scattered_showers/scattered_showers_36x36.png",
			["weather/sleet/2"]	=  "fs:/~/images/weather/sleet/sleet_36x36.png",
			["weather/smoke/2"]	=  "fs:/~/images/weather/smoke/smoke_36x36.png",
			["weather/snow_heavy/2"]	=  "fs:/~/images/weather/snow_heavy/snow_heavy_36x36.png",
			["weather/snow_light/2"]	=  "fs:/~/images/weather/snow_light/snow_light_36x36.png",
			["weather/snow_showers/2"]	=  "fs:/~/images/weather/snow_showers/snow_showers_36x36.png",
			["weather/sunny_fair/2"]	=  "fs:/~/images/weather/sunny_fair/sunny_fair_36x36.png",
			["weather/sunny_intervals/2"]	=  "fs:/~/images/weather/sunny_intervals/sunny_intervals_36x36.png",
			["weather/sunny_periods/2"]	=  "fs:/~/images/weather/sunny_periods/sunny_periods_36x36.png",
			["weather/thunder_lightning/2"]	=  "fs:/~/images/weather/thunder_lightning/thunder_lightning_36x36.png",
			["weather/warm/2"]	=  "fs:/~/images/weather/warm/warm_36x36.png",
			["weather/windy/2"]	=  "fs:/~/images/weather/windy/windy_36x36.png",


			["sports/mlb/0"] = 	"fs:/~/images/sports/mlb/baseball_mlb_25x25.png",
			["sports/mlb/1"] = 	"fs:/~/images/sports/mlb/baseball_mlb_47x47.png",
			["sports/nba/0"] = 	"fs:/~/images/sports/nba/basketball_nba_25x25.png",
			["sports/nba/1"] = 	"fs:/~/images/sports/nba/basketball_nba_47x47.png",
			["sports/ncaab/0"] = 	"fs:/~/images/sports/ncaab/basketball_ncaa_25x25.png",
			["sports/ncaab/1"] =	"fs:/~/images/sports/ncaab/basketball_ncaa_47x47.png",
			["sports/ncaaf/0"] =	"fs:/~/images/sports/ncaaf/football_ncaa_25x25.png",
			["sports/ncaaf/1"] = 	"fs:/~/images/sports/ncaaf/football_ncaa_47x47.png",
			["sports/nfl/0"] =	"fs:/~/images/sports/nfl/football_nfl_25x25.png",
			["sports/nfl/1"] =	"fs:/~/images/sports/nfl/football_nfl_47x47.png",
			["sports/nhl/0"] =	"fs:/~/images/sports/nhl/hockey_nhl_25x25.png",
			["sports/nhl/1"] =	"fs:/~/images/sports/nhl/hockey_nhl_47x47.png",

                    }


                    downloadImages = {}

            

	marketing = {}   --marketing screen details table
	news = {}        
	weather = {}
	sports = {}
	money = {}
	movies = {}
	extras = {}


			
--Money tables: Store information for the money channel in OnDemand


--[[
     money.markets: Stores stock quotes for the three indexes: DOW, NASDAQ, S&P500
	 
	 Format:
	 money.markets {
	 
		id = {
				value = xx
				change = xx
				direction = xx
		     }
      }    


--]]
money.markets = {
		}
				
				
--[[
	money.portfolio: Stores stock quotes for the tickers that come down in data packages
	
	Format:
	money.portfolio = {
		    id = {
			   		ticker = xx
		            label = xx
			   		value = xx
			   		change = xx
		            direction = xx
                  
                  }
                }


--]]

money.portfolio = 
{

}

--[[
     money.stockdetails: Stores stock details by portfolio ID
     
     Format:
     money.stockdetails {
							id = <details string>
                 	    }

--]]                 	                 	    
   	
money.stockdetails =
{


}


-- END: money tables



-- Movies tables: These tables store information for movies,theatres, showtimes, purchase URLs


--[[
	movies.movielist: List of movies currently in database
	
	Format:
	 movies.movielist = {
			id = 
				name = xx
				genre = xx
				rating = xx
				newMovieFlag = xx
		    }		    
	
 Note: The "newMovieFlag" means that the actual movie (and not the datastore entry) is a new release
--]]

movies.movielist =
{
	            
}


--[[
	movies.theatres: Details of theatres currently in database
	
	format:
	  movies.theatres = {
			id = 
				name = xx
				address = xx
				city = xx
				state = xx
				zipcode = xx
		  } 
--]]

movies.theatres =
{

}



--[[
	movies.theatreshowsbymovie: For each movie, a list of theatre showtimes and
	purchase URLs (if available - empty string "" otherwise), stored by day (upto
	a week from today)
	
	format:
	  movies.theatreshowsbymovie = {
				movie_id =  {
						day_id = {
							    theatre_id = {
									   showtime_string = purchase_URL or "" if none
									 }
							}

					 }
			    }

--]]

movies.theatreshowsbymovie = 
{
}

--[[
	movies.movieshowsbytheatre: For each theatre, a list of movie showtimes and
	purchase URLs (if available - empty string "" otherwise), stored by day (upto 7 days
	from today)
	
	format:
	  movies.theatreshowsbymovie = {
				movie_id =  {
						day_id = {
							    theatre_id = {
									   showtime_string = purchase_URL or "" if none
									 }
							}

					 }
			    }

--]]

movies.movieshowsbytheatre = {

}




-- END movies tables


--news tables: Data to support news channel in OnDemand client


--[[
		news.headlines: List of current headlines, with categories, image, and an optional
		detailed story
		
		Format:
		news.headlines = {
			id = {
				timestamp = xx
				story = xx
				label = xx
				categories = { category1,category2..}

			     }
		}
--]]
		
	
movies.movie_tickets_per_movie_and_theatre = {}

news.headlines =
{
}


--[[
    news.categories: List of current news categories, with an image and a list of news IDs currently available
    for this category 
    
    Format:
    news.categories = {
			id = {
				label = xx
				image = xx
				description = xx
				news_ids_with_this_category = { id1,id2,.. }

			     }
		}
--]]
    
news.categories =
{

}
   
 
 -- weather tables: data to support the weather channel in on-demand client
 
 --[[ 
      weather.locations: Stores weather information for the weather locations of interest
                         to the user, along with weather alert IDs for each location

      Format:
	  weather.locations = {
			id = {
				timestamp = xx
				city = xx
				state = xx
				zipcode = xx
				current = xx
				high = xx
				low = xx
				images = { list_of_images }
				alerts = { list of current alerts for this location }
			      }
		    }                         
--]]                         
                        
 
 weather.locations = 
 {
      
  }
  
  
  --[[
        weather.alerts: Stores all the weather alert details, for alerts pertinent to the user's locations
        Format:
        weather.alerts = {
			alert_id = {
					timestamp = xx
					text = xx
					flag = xx
				   }
		}
  --]]
          
  weather.alerts = 
  {
  }
  
  
    --[[
        weather.summary: Stores the 7-day weather summary for locations pertinent to the user
        Format:
        weather.summary = {
		     location_id = {
					day_id = {
						   summary = xx
						   images = { list_of_images }
						   high = xx
						   low = xx
						   radarcontent = xx 
						 }
				  }
		}

		
  --]]

  weather.summary = 
  {
  } 

  --]]
  
  
    --[[
        weather.details: Stores each day's radar image and text
        Format:
        weather.details = {
		     location_id = {
					day_id = {
							   text = xx
							   radar = xx
				  			 }
						    }
						   }	

		
  --]]

  weather.details = 
  {
  } 
 
--END weather tables

-- Sports tables: Data to store the sports channel in the on-demand client

--[[

     sports.types - Stores all the sports types available, along with an image reference
     
     Format:
     sports.types = {
		  id = {
			 label = xx
		         image = xx
			}
		}

--]]

sports.types = 
{
 			  
}   
   

--[[
	 sports.teams = Stores data relavant to particular sport teams
	 
	 Format:
	 sports.teams = {
		  type_id = {
				team_id = {
						city = xx
						name = xx
						image = xx
					  }
			    }
		}
	 
--]]	 
sports.teams = 
{
   			 
}


--[[

  sports.standings = Stores sports standings/polls depending on sport type
  
  Format:
  
  sports.standings = {
			type_id = {
					conference/poll = xx
					picker_label = xx
					standings_label = xx
					week = xx
					details = xx
				  }
		   }


--]]
sports.standings =
{

}



--[[

	sports.scores = Scores from recent/current games

	Format: 
		sports.scores = {
				  type_id = {
						date = {
							  game_id = details_string
						       }
					    }
				}

--]]
sports.scores = 
{
}

--[[
	sports.schedules = team schedules
	Format:
	sports.schedules = {
				team_id = {
						game_id = details_string
					  }
			   }
--]]

sports.schedules = 
{
					   	
}


--[[
	sports.games = information about current games: preview/recap/summary
	Format: 
	sports.games = {
			 game_id = {
					label = xx
					summary = xx
					details = xx
					date = xx
					teams = xx
					score1 = xx
					score2 = xx
					status = xx
				   }
			}

--]]
--
sports.games = 
{
				
}   					

  --datastore initialization is now complete - set IsInit to true
  internal.IsInit = true
  internal.IsFakeData = true
  internal.IsBeingUpdated = false  -- Remove lock on datastore

end --end initNewStore()

--[[
--
--   Function: readFromFS
--   Description: Tries to initialize datastore from FS 
--   Unpersists and reinitializes all the data tables from the datastore
--   Return value: true - if a persisted datastore exists and is correctly unpersisted
--    false: If no persisted datastore exists - or if it exists but there is an error in
--   unpersisting
--
--]]

function readFromFS()

         print ("Datastore:: readFromFS():  checking for persisted store...")

	 if not unpersist() then
		 print ("Datastore:: -- Unpersist failed") 
		 return false
	 end

	 print("Datastore:: Unpersist succeeded")
	 return true

end

function clearImages()
  for i,shortname in ipairs(downloadImages) do
	print("shortname " .. shortname)
	print("Deleting " .. images[shortname])
	file.remove(images[shortname])
  end	

  downloadImages = {}

end


--[[ 
--   Clears the data store - removes fake/old data
--
--]]

function clear()

  clearImages()
  --marketing = {}
  marketing.ticker = nil
  marketing.image  = nil
  marketing.target = ""
  marketing.text   = ""

  money.portfolio = {}
  money.markets = {}
  money.markets["NASDAQ"] = {}
  money.markets["NASDAQ"].value = ""
  money.markets["NASDAQ"].change = "-"
  money.markets["NASDAQ"].direction = "default"
		  
  money.markets["DJX"] = {}
  money.markets["DJX"].value = ""
  money.markets["DJX"].change = "-"
  money.markets["DJX"].direction = "default"

  money.markets["SnP500"] = {}
  money.markets["SnP500"].value = ""
  money.markets["SnP500"].change = "-"
  money.markets["SnP500"].direction = "default"

  money.stockdetails = {}

  movies.movielist = {}
  movies.theatres = {}
  movies.theatreshowsbymovie = {}
  movies.movieshowsbytheatre = {}
  movies.movie_tickets_per_movie_and_theatre = {}

  -- Do not clear alerts, this would get cleaned up in fillweather
  -- weather.alerts = {}
  weather.locations = {}
  weather.summary = {}
  weather.details = {}

  news.headlines = {}
  news.categories = {}

  sports.types = {}
  sports.teams = {}
  sports.standings = {}
  sports.scores = {}
  sports.schedules = {}
  sports.games = {}

  ota = {}

--persist is "required" after this - because we want to blow away the old persisted data store
  internal.persistReqd = true
  internal.confPersistReqd = true

  collectgarbage()
  
  

end


--[[ 
--   Function: dumpStore()
--   Dumps the data store contents in Lua code format
--
--]]



function dumpStore(dumpMoney, dumpMovies, dumpNews, dumpWeather, dumpSports)

 print("--Dumping store....")

  -- if none, then all! (if someone calls datastore.dumpStore() without params - dump everythong)
  if not (dumpMoney and dumpMovies and dumpNews and dumpWeather and dumpSports) then
	 dumpMoney = 1
	 dumpMovies = 1
	 dumpNews = 1
	 dumpWeather = 1
	 dumpSports = 1
  end
  

 --local printfn = print
 --print = print
  
 _debug = 1
 if _debug then

	 if dumpMoney == 1 then
     print("--Dumping store money....")
     print( "datastore.money.portfolio = {")

	 for k,v in pairs(money.portfolio) do
			 print ("[\"".. k .. "\"] = {")
			 print ("ticker = \"" .. (money.portfolio[k].ticker or "none") .. "\",")
			 print ("label = \"" .. (money.portfolio[k].label or "none") .. "\",")
			 print ("value = \"" .. (money.portfolio[k].value or "none") .. "\",")
			 print ("change = \"" .. (money.portfolio[k].change or "none") .. "\",")
			 print ("direction = \"" .. (money.portfolio[k].direction or "none") .. "\",")
			 print ("},\n")
		end
		print ("}\n")

	print ("datastore.money.markets = {")
	for k,v in pairs( money.markets) do
			 print ("[\"".. k .. "\"] = {")
			 print ("value = \"" .. (money.markets[k].value or "none") .. "\",")
			 print ("change = \"" ..  (money.markets[k].change or "none") .. "\",")
			 print ("direction = \"" ..  (money.markets[k].direction or "none") .. "\",")
			 print ("},\n")
	end

	print ("}\n")


	print ("datastore.money.stockdetails = {")

	for k,v in pairs(money.stockdetails) do
			 print ("[\"".. k .. "\"] = {")

			 print ("details = [[\n" .. (money.stockdetails[k].details or "none") .. "]]\n,")
--			 print ("exchange" .. " = " .. (money.stockdetails[k].exchange or "none"))
--			 print ("prevClose" .. " = " .. (money.stockdetails[k].prevClose or "none"))
--			 print ("openprice" .. " = " .. (money.stockdetails[k].OpenPrice or "none"))
--			 print ("dayRange" .. " = " .. (money.stockdetails[k].dayRange or "none"))
--			 print ("p52wkrange" .. " = " .. (money.stockdetails[k].p52wkrange or "none"))
--			 print ("volume" .. " = " .. (money.stockdetails[k].Volume or "none"))
			 print ("},\n")
	end

	print("}\n")
	end --dumpMoney

	if dumpMovies == 1 then

	print("--Dumping store movies....")
	print ("datastore.movies.movielist = {")
	for k,v in pairs(movies.movielist) do

			print ("[\"".. k .. "\"] = {")
			print ("name = \"" .. (movies.movielist[k].name or "none") .. "\",")
			print ("genre = \"" .. (movies.movielist[k].genre or "none") .. "\",")
			print ("rating = \"" .. (movies.movielist[k].rating or "none") .. "\",")
			print ("newMovieFlag = " .. (movies.movielist[k].newMovieFlag or "\"none\"") .. ",")
			print ("},\n")

	end

	print ("}\n")

	print ("datastore.movies.theatres = {")
	for k,v in pairs(movies.theatres) do

			print ("[\"".. k .. "\"] = {")
			print ("name = \""  .. (movies.theatres[k].name or "none") .. "\",")
			print ("address = \"" .. (movies.theatres[k].address or "none") .. "\",")
			print ("city = \"" .. (movies.theatres[k].city or "none") .. "\",")
			print ("state = \"" .. (movies.theatres[k].state or "none") .. "\",")
			print ("zipcode = \"" .. (movies.theatres[k].zipcode or "none") .. "\",")
			print ("},\n")

	end

	print ("}\n")

	print ("datastore.movies.theatreshowsbymovie = {")
	for k,v in pairs(movies.theatreshowsbymovie) do
			print ("[\"".. k .. "\"] = {") -- k = theatreid
			for k2,v2 in pairs(v) do
			 print ("[\"".. k2 .. "\"] = {") -- k2 = dayid
			  for k3,v3 in pairs(v2) do
				print ("[\"".. k3 .. "\"] = " .. "\"" .. v3 .. "\",") -- k3 = movieid
			  end  -- end for k3,v3
			end  -- end for k2,v2
			print "},\n"
		end  -- end for k,v
       print ("}\n")

   print ("datastore.movies.movieshowsbytheatre = {")
	for k,v in pairs(movies.movieshowsbytheatre) do
			print ("[\"".. k .. "\"] = {") -- k = movieid
			for k2,v2 in pairs(v) do
			 print ("[\"".. k2 .. "\"] = {") -- k2 = dayid
			 for k3,v3 in pairs(v2) do
				print ("[\"".. k3 .. "\"] = " .. "\"" .. v3 .. "\",") -- k3 = theatre_id
			  end  -- end for k3,v3
			end  -- end for k2,v2
			print "},\n"
		end  -- end for k,v
       print ("}\n")
  end

  if dumpNews == 1 then

  print("--Dumping store categories....")
  print ("datastore.news.categories = {")
  for k,v in pairs(news.categories) do

    print ("[\"".. k .. "\"] = {") -- k = categoryid
    print ("label = \"" .. (news.categories[k].label or "none") .. "\",")
    print ("image = \"" .. (news.categories[k].image or "none") .. "\",")
    print ("description = \"" .. (news.categories[k].description or "none") .. "\",")
    if (news.categories.news) then

	    	print ("news = { ")
		for k1,v1 in pairs(news.categories.news) do
		    print ("\"" .. news.categories.news[k1] .. "\",")
		end
		print ("},\n")
    end

    print ("},\n")

  end

  print ("}\n")
  print ("datastore.news.headlines = {")

  for k,v in pairs(news.headlines) do
    print ("[\"".. k .. "\"] = {") -- k = categoryid
    print ("timestamp = \"" .. (news.headlines[k].timestamp or "none") .. "\",")
    print ("label = \"" .. (news.headlines[k].label or "none") .. "\",")
    print ("story = \"" .. (news.headlines[k].story or "none") .. "\",")
    print ("categories = {")
    for k1,v1 in pairs(news.headlines[k].categories) do
      print ("\"" .. v1 .. "\",")
    end
	print ("},")
	print ("},\n")
  end

  print ("}\n")

  end

  if dumpWeather == 1 then

  print ("datastore.weather.alerts = {")

  for k,v in pairs(weather.alerts) do
	        print ("[\"".. k .. "\"] = {") -- k = categoryid
		print ("timestamp = \"" .. (weather.alerts[k].timestamp or "none") .. "\",")
		print ("text = \"" .. (weather.alerts[k].text or "none") .. "\",")
		print ("flag = " .. (weather.alerts[k].flag or "none") .. ",")
		print ("},\n")
  end

  print "}\n"


  print ("datastore.weather.locations = {" )


  for k,v in pairs(weather.locations) do

	        print ("[\"".. k .. "\"] = {") -- k = categoryid
		print ("timestamp = \"" .. (weather.locations[k].timestamp or "none") .. "\",")
		print ("city = \"" .. (weather.locations[k].city or "none") .. "\",")
		print ("state = \"" .. (weather.locations[k].state or "none") .. "\",")
		print ("zipcode = \"" .. (weather.locations[k].zipcode or "none") .. "\",")
		print ("current = \"" .. (weather.locations[k].current or "none") .. "\",")
		print ("high = \"" .. (weather.locations[k].high or "none") .. "\",")
		print ("low = \"" .. (weather.locations[k].low or "none") .. "\",")

		if weather.locations[k].images then
		        print ("images = {")
			for k1,v1 in pairs(weather.locations[k].images) do
			    print ("\"" .. v1 .. "\",")
			end
			print ("},\n")
		end
		print "},\n"

  end


  print ("}\n")
  print ("datastore.weather.summary = {")


  for k,v in pairs(weather.summary) do

	        print ("[\"".. k .. "\"] = {") -- k = categoryid

		for k1,v1 in pairs(weather.summary[k]) do

			print ("[\"".. k1 .. "\"] = {") -- k = categoryid
			print("summary = \"" .. weather.summary[k][k1].summary .. "\",")

			if weather.summary[k][k1].images then
			print("images = {")
				for k2,v2 in pairs(weather.summary[k][k1].images) do
				    print ("\"" .. v2 .. "\",")
				end
			print ("},")
			end

			print("high = \"" .. weather.summary[k][k1].high .. "\",")
			print("low  = \"" .. weather.summary[k][k1].low .. "\",")
			print("radar = \"" .. (weather.summary[k][k1].radar or "none") .. "\",")

			print ("},\n")
		end
		print ("}\n")

  end
  print ("}\n")
  print ("datastore.weather.details = {")


  for k,v in pairs(weather.details) do
	      print ("[\"".. k .. "\"] = {") -- k = categoryid
	      
		  for k1,v1 in pairs(weather.summary[k]) do
			print ("[\"".. k1 .. "\"] = {") -- k = categoryid
			print("text = \"" .. weather.details[k][k1].text .. "\",")

			if weather.details[k][k1].images then
			print("images = {")
				for k2,v2 in pairs(weather.details[k][k1].radar) do
				    print ("\"" .. v2 .. "\",")
				end
			print ("},")
			end
		  end
		  
		  print ("},\n")
		  
		end
		print ("}\n")

  end

  if dumpSports == 1 then

  print("--Dumping store sports....")
  print ("datastore.sports.types = {")

  for k,v in pairs(sports.types) do

    print ("[\"".. k .. "\"] = {") -- k = categoryid
    print( "label = \"" .. (sports.types[k].label or "none") .. "\",")
    print( "image = \"" .. (sports.types[k].image or "none") .. "\",")
    print( "},\n")

  end
  print( "}\n")

  print ("datastore.sports.standings = {")

  for k,v in pairs(sports.standings) do

    print ("[\"".. k .. "\"] = {") -- k = categoryid

    for k1,v1 in pairs(sports.standings[k]) do

        print ("[\"".. k1 .. "\"] = {") -- k = categoryid
        print ("picker_label = \"" .. (sports.standings[k][k1].picker_label or "none") .. "\",")
        print ("standings_label = \"" .. (sports.standings[k][k1].standings_label or "none") .. "\",")
        print ("week = \"" .. (sports.standings[k][k1].week or "none") .. "\",")
        print ("details = \"" .. (sports.standings[k][k1].details or "none") .. "\",")
        print( "},\n")
	end
   print ("},\n")
  end
  print ("}\n")

  print ("datastore.sports.teams = {")

  for k,v in pairs(sports.teams) do

	  print ("[\"".. k .. "\"] = {") -- k = categoryid

	  for k1,v1 in pairs(v) do

		  print ("[\"".. k1 .. "\"] = {") -- k = categoryid
	  	  print ("city = \"" .. (sports.teams[k][k1].city or "none") .. "\",")
		  print ("name = \"" .. (sports.teams[k][k1].name or "none") .. "\",")
		  print ("image = \"" .. (sports.teams[k][k1].image or "none") .. "\",")
		  print( "},")
	  end
	  print ("},\n")
  end
  print ("}\n")


  print ("datastore.sports.schedules = {")

  for k,v in pairs(sports.schedules) do

    print ("[\"".. k .. "\"] = {") -- k = categoryid

    for k1,v1 in pairs(v) do
        print("\"" .. sports.schedules[k][k1] .. "\" = \"" .. v1 .. "\",")
    end

   print ("},\n")
  end
  print ("}\n")


 print ("datastore.sports.games = {")

 for k,v in pairs(sports.games) do

    print ("[\"".. k .. "\"] = {") -- k = categoryid
    print("label = \"" .. (sports.games[k].label or "none") .. "\",")
    print("summary = \"" .. (sports.games[k].summary or "none") .. "\",")
    print("details = \"" .. (sports.games[k].details or "none") .. "\",")
    print("date = \"" .. (sports.games[k].date or "none") .. "\",")
    print("teams = \"" .. (sports.games[k].teams or "none") .. "\",")
    print("score1 = \"" .. (sports.games[k].score1 or "none") .. "\",")
    print("score2 = \"" .. (sports.games[k].score2 or "none") .. "\",")
    print("status = \"" .. (sports.games[k].status or "none") .. "\",")
    print( "}\n")

 end -- for
 print ("}\n")

 print ("datastore.sports.scores = {")

 for k,v in pairs(sports.scores) do

    print ("[\"".. k .. "\"] = {") -- k = categoryid
	for k1,v1 in pairs(v) do
	    print ("[\"".. k1 .. "\"] = {") -- k = categoryid

	    for k2,v2 in pairs(v1) do
		 print ("[\"".. k2 .. "\"] = \"" .. v2 .. "\",") -- k = categoryid
     	    end
	    print ("},")
	end
	print ("},\n")

  end
  print ("}\n")

   end -- dumpSports

 --print = printfn
 end -- _debug

end -- dumpStore()





function removeOldTables(url)
-- parse the URL and find out if the URL is for any channel
-- If so, whack the corresponding table from the datastore

   if string.find(url, "/od2/channels?id=",1,true) then
	-- need to whack some tables
	
	if string.find(url,"all",1,true) then
	        clear()
	end
	
	if string.find(url,"news",1,true) then
		  news.headlines = {}
		  news.categories = {}
	end
	
	if string.find(url,"weather",1,true) then
		  -- Do not clear alerts, this would get cleaned up in fillweather
		  -- weather.alerts = {}
		  weather.locations = {}
		  weather.summary = {}
		  weather.details = {}
	end
	
	
	if string.find(url, "movies",1,true) then
		  movies.movielist = {}
		  movies.theatres = {}
		  movies.theatreshowsbymovie = {}
		  movies.movieshowsbytheatre = {}
		  movies.movie_tickets_per_movie_and_theatre = {}
	end
	
	if string.find(url, "money",1,true) then
		  money.portfolio = {}

		  money.markets = {}
		  money.markets["NASDAQ"] = {}
		  money.markets["NASDAQ"].value = ""
		  money.markets["NASDAQ"].change = "-"
		  money.markets["NASDAQ"].direction = "default"
		  
		  money.markets["DJX"] = {}
		  money.markets["DJX"].value = ""
		  money.markets["DJX"].change = "-"
		  money.markets["DJX"].direction = "default"

		  money.markets["SnP500"] = {}
		  money.markets["SnP500"].value = ""
		  money.markets["SnP500"].change = "-"
		  money.markets["SnP500"].direction = "default"

		  money.stockdetails = {}
	end
	

   end


end

function removeDanglingAlerts()
   if datastore.weather.alerts then
      for k,v in pairs(datastore.weather.alerts) do
         datastore.weather.alerts[k].flag = false
      end
   end

   if datastore.weather.locations then
      for k,v in pairs(datastore.weather.locations) do
         if datastore.weather.locations[k].alerts ~= nil then
            for i, alertID in datastore.weather.locations[k].alerts do
               datastore.weather.alerts[alertID].flag = true
            end
         end
      end
   end

   if datastore.weather.alerts then
      for k,v in pairs(datastore.weather.alerts) do
         if datastore.weather.alerts[k].flag == false then
            datastore.weather.alerts[k] = nil
         end
      end
   end
end

-- API for fetch layer
--[[
Function: run_payload
 Run the payload - to store data package into datastore

 Assumptions: Expects fillstore.lua to be in the path
 
 Parameters: expire_time: Update to the expire time entry
 in the datatable


Return Value:
   SUCCESS, if successful
   FAILURE, otherwise   

--]]
function run_payload(datapackage, url, persistStore)
 
   --First remove any tables that need whacking
   removeOldTables(url)
   print ("Datastore: Running payload..." .. datapackage)

   local loaderr, runerr
   local runret = true
   
   if scripts == nil then
      print("Loading up fillstore script...")
      packfn, loaderr = loadfile("fillstore.lua")
      if not loaderr then
           scripts = {}
           scripts.fillstorefuncs = packfn
      end 
   end

   packfn, loaderr = loadfile(datapackage) -- load the datapackage
   
 	
   if not loaderr then
	   runret, runerr = pcall(packfn) -- run the datapackage
   end
   
   if type(runerr) == "string" then   
	local info = debug.getinfo(1, "Sl")
	print ( string.format("[%s]:%d ERROR [%s]", info.short_src, info.currentline,runerr) )
   end
   
   if loaderr or (not runret) then -- if datapackage is corrupt
	print("Data package " .. datapackage .. " is corrupt or has a run-time error")
	internal.IsBeingUpdated =  false -- unlock datastore - update failed
	if interfaceCB then
	   interfaceCB(FAILURE) -- negative value indicates error to interface
	end

	local info = debug.getinfo(1, "Sl")
	print ( string.format("[%s]:%d ERROR - run_payload returns [%d]", info.short_src, info.currentline,FAILURE) )

	return FAILURE
   end
   
   -- remove the alerts if no locations are available for that alert
   if string.find(url, "/od2/channels?id=",1,true) then
      if string.find(url,"all",1,true) or string.find(url,"weather",1,true) then
         removeDanglingAlerts() 
      end
   end

   internal.persistReqd = true
   if persistStore then
     print("Datastore: Persisting store after applying data package")
     persist()
   end

   local info = debug.getinfo(1, "Sl")
   print ( string.format("[%s]:%d PASS - run_payload returns [%d]", info.short_src, info.currentline,SUCCESS) )

   return SUCCESS

end


--[[ 
-- Function: get_username()
-- Gets the stored username from datastore
-- Parameters: None
-- Return value: username (string)
--]]

function get_username()
	print ("Datastore: In get_username...")
	return config.username
end

--[[
-- Function: set_username()
--  Sets the username into config table
--  Parameters: username 
--  Return value: none
--  ]]
function set_username(username)
	config.username = username
	internal.confPersistReqd = true
end

--[[
-- Function: get_password()
-- Returns the current password set in config
-- Parameters: None
-- Return Value: the password (string)
-- ]]

function get_password()
	return config.password
end

--[[
-- Function: set_password()
-- Sets the password in the config table 
-- Parameters: New password to be set
-- Return Value: None
-- ]]
function set_password(password)
	config.password = password
	internal.confPersistReqd = true
end

-- [[
-- Function: get_showtime()
-- Returns the showtime stored in the datastore
-- Parameters: None
-- Return value: Current showtime
-- ]]

function get_showtime()
	print("Datastore: get_showtime\(\) called ..." .. tostring(config.showTime))
	return config.showTime
end

-- [[
-- Function: set_showtime()
-- Sets the showtime into the datastore
-- Parameters: showtime
-- Return value: none 
-- ]]

function set_showtime(showtime)
	print("Datastore: set_showtime\(\) called ..." .. tostring(showtime))
	config.showTime = showtime
	internal.confPersistReqd = true
end

-- [[
-- Function: get_expiretime()
-- Gets the current expire time from the datastore
-- Parameters: None
-- Return value: Current expire time
-- ]]
function get_expiretime()
	print("Datastore: get_expiretime\(\) called ...".. tostring(config.expireTime))
	return config.expireTime
end

-- [[
-- Function: set_expiretime()
-- Sets the current expire time into the datastore
-- Parameters: The current expire time
-- Return value: None
-- ]]
function set_expiretime(expiretime)
	print("Datastore: set_expiretime\(\) called ..." .. tostring(expiretime))
	config.expireTime = expiretime
         internal.confPersistReqd = true
end

-- [[
-- Function: get_nextgettime()
-- Gets the current next-get time from the datastore
-- Parameters: None
-- Return value: Current next-get time
-- ]]
function get_nextgettime()
	print("Datastore: get_nextgettime\(\) called ...".. tostring(config.nextgettime))
	return config.nextgettime
end

-- [[
-- Function: set_nextgettime(nextgettime)
-- Sets the current next-get time into the datastore
-- Parameters: The current next-get time
-- Return value: None
-- ]]
function set_nextgettime(nextgettime)
	print("Datastore: set_nextgettime\(\) called ..." .. tostring(nextgettime))
	config.nextgettime = nextgettime
        internal.confPersistReqd = true
end

-- [[
-- Function: get_pcs_ver()
-- Gets the pcs ver from the datastore
-- Parameters: None
-- Return value: pcs ver
-- ]]
function get_pcs_ver()
	print("Datastore: get_pcs_ver\(\) called ...".. tostring(config.pcs_ver))
	return config.pcs_ver
end

-- [[
-- Function: set_pcs_ver(pcs_ver)
-- Sets the pcs ver into the datastore
-- Parameters: The pcs ver
-- Return value: None
-- ]]
function set_pcs_ver(pcs_ver)
	print("Datastore: set_pcs_ver\(\) called ..." .. tostring(pcs_ver))
	config.previous_pcs_ver = config.pcs_ver or pcs_ver
	config.pcs_ver = pcs_ver
	
	local info = debug.getinfo(1, "Sl")
	if config.previous_pcs_ver then
		print ( string.format("[%s]:%d set_pcs_ver curr[%s]prev[%s]", info.short_src, info.currentline,(config.pcs_ver or "nil"),(config.previous_pcs_ver or "nil")) )
	else
		print ( string.format("[%s]:%d set_pcs_ver curr[%s]prev[NIL]", info.short_src, info.currentline,(config.pcs_ver or "nil")) )
	end
    internal.confPersistReqd = true
end

-- [[
-- Function: get_next_url()
-- Gets the next url from the datastore
-- Parameters: None
-- Return value: next url
-- ]]
function get_next_url()
	print("Datastore: get_next_url\(\) called ...".. tostring(config.next_url))
	return config.next_url
end

-- [[
-- Function: set_next_url(next_url)
-- Sets the next url into the datastore
-- Parameters: The next url
-- Return value: None
-- ]]
function set_next_url(next_url)
	print("Datastore: set_next_url\(\) called ..." .. tostring(next_url))
	config.next_url = next_url
        internal.confPersistReqd = true
end

-- [[
-- Function: get_pcs_token()
-- Gets the pcs token from the datastore
-- Parameters: None
-- Return value: pcs token
-- ]]
function get_pcs_token()
	print("Datastore: get_pcs_token\(\) called ...".. tostring(config.pcs_token))
	return config.pcs_token
end

-- [[
-- Function: set_pcs_token(pcs_token)
-- Sets the pcs token into the datastore
-- Parameters: The pcs token
-- Return value: None
-- ]]
function set_pcs_token(pcs_token)
	print("Datastore: set_pcs_token\(\) called ..." .. tostring(pcs_token))
	config.pcs_token = pcs_token
        internal.confPersistReqd = true
end

-- [[
-- Function: get_http_timeout()
-- Gets the http timeout from the datastore
-- Parameters: None
-- Return value: http timeout
-- ]]
function get_http_timeout()
	print("Datastore: get_http_timeout\(\) called ...".. tostring(config.http_timeout))
	return config.http_timeout
end

-- [[
-- Function: set_http_timeout(http_timeout)
-- Sets the http timeout into the datastore
-- Parameters: The http timeout
-- Return value: None
-- ]]
function set_http_timeout(http_timeout)
	print("Datastore: set_http_timeout\(\) called ..." .. tostring(http_timeout))
	config.http_timeout = http_timeout
        internal.confPersistReqd = true
end

-- [[
-- Function: get_http_status_code()
-- Returns the http status code stored in datastore.config
-- Parameters: none
-- Return value: http status code
-- ]]
function get_http_status_code()
	return config.httpStatusCode
end

-- [[
-- Function: set_http_status_code()
-- Sets the http status code into the datastore.config
-- Parameters: the http status code to be set
-- Return value: none
-- ]]
function set_http_status_code(status_code)
	config.httpStatusCode = status_code
        internal.confPersistReqd = true
end

--[[
-- Function: get_last_update_time()
-- Returns the last update time in seconds stored in the datastore.config table
-- Parameters: None
-- Return value: Last update time in seconds
-- ]]
function get_last_update_time()
	return config.lastUpdateTime
end

--[[
--Function: set_last_update_time()
--Sets the last update time in seconds into the datastore.config table
--Parameters: the value to be set for last update time in seconds
--Return value: None
--]]
function set_last_update_time(lastUpdateTime)
	config.lastUpdateTime = lastUpdateTime
         internal.confPersistReqd = true
end

--[[
--Function: get_last_pathid()
--Get the last path id from the datastore.config table
--Parameters: None
--Return value: The value for the last path id
--]]
function get_last_pathid()
	if config.lastPathID then
		return config.lastPathID
	else
		return 0
	end
end

--[[
--Function: set_last_pathid()
--set the last pathid into the datastore
--Parameters: the last pathid to be set
--Return value: None
--]]
function set_last_pathid(last_path_id)
	config.lastPathID = last_path_id
        internal.confPersistReqd = true
end

--[[
--Function: get_automatic_enable()
--Get the automatic enable flag from the datastore.config table
--Parameters: None
--Return value: Automatic enable flag
--]]
function get_automatic_enable()
	return config.automatic_enable
end

--[[
--Function: set_automatic_enable(enable)
--set the Automatic enable flag into the datastore
--Parameters: Automatic enable flag
--Return value: None
--]]
function set_automatic_enable(enable)
	config.automatic_enable = enable
        internal.confPersistReqd = true
end

--[[
--Function: get_last_view()
--Get the last view timestamp from the datastore.config table
--Parameters: None
--Return value: last view timestamp
--]]
function get_last_view()
	return config.last_view
end

--[[
--Function: set_last_view(last_view)
--set the last view timestamp into the datastore
--Parameters: last view timestamp
--Return value: None
--]]
function set_last_view(last_view)
	config.last_view = last_view
        internal.confPersistReqd = true
end

--[[

Function: getMDN
  Returns the MDN stored in the datastore
  
Parameters: None

Return Value:
   Actual value of MDN (integer) if successful
   FAILURE, otherwise
   

--]]
function get_mdn()
    return config.MDN 
 end

--[[

Function: setMDN
  Sets the MDN into datastore
  
Parameters: 


Return Value:
   SUCCESS, if successful
   FAILURE, otherwise   

--]]


function set_mdn(MDN)
	config.MDN = MDN
        internal.confPersistReqd = true
end


--[[

Function: getZipCode
  Returns the current zip code as an integer
  
Parameters: 


Return Value:
   If no zipcode is in DB, returns FAILURE
   FAILURE, otherwise
   

--]]

function getZipCode()
    if not config or not config.zipcode then
	return nil
    else
    	return config.zipcode
    end	
end
  
function setZipCode(zipcode)
	config.zipcode = zipcode
        internal.confPersistReqd = true
end

--[[

Function: set_miui_base
  Sets the miui base trig version into datastore

Parameters:
    string: miui base trig version

Return Value:

--]]
function set_miui_base(miui_base)
	config.miui_base = miui_base
    internal.confPersistReqd = true
end

--[[

Function: get_miui_base
  Gets the miui base trig version into datastore

Parameters:

Return Value:
    string: miui base trig version

--]]
function get_miui_base()
    return (config.miui_base or "0")
end


--[[

Function: set_miui_triglet
  Sets the miui triglet version into datastore

Parameters:
    string: miui triglet version

Return Value:

--]]
function set_miui_triglet(miui_triglet)
	config.miui_triglet = miui_triglet
    internal.confPersistReqd = true
end


--[[

Function: get_miui_triglet
  Gets the miui triglet version into datastore

Parameters:

Return Value:
    string: miui triglet version

--]]
function get_miui_triglet()
	return (config.miui_triglet or "0")
end


--[[

Function: set_ondemand_triglet
  Sets the ondemand triglet version into datastore

Parameters:
    string: ondemand triglet version

Return Value:

--]]
function set_ondemand_triglet(ondemand_triglet)
	config.ondemand_triglet = ondemand_triglet
    internal.confPersistReqd = true
end

--[[

Function: get_ondemand_triglet
  Gets the ondemand triglet version into datastore

Parameters:

Return Value:
    string: ondemand triglet version

--]]
function get_ondemand_triglet()
	return (config.ondemand_triglet or "0")
end

-- removeContent() is a wrapper around datastore.clear()
-- It does the extra job of notifying interface that the datastore
-- is cleared
function removeContent(clearAllTables)
	if clearAllTables then
        	initNewStore() 
	else
		internal.IsFakeData = true
		-- Remove alerts, as clear does not remove it
		weather.alerts = {}
		clear()
	end

	if interfaceCB then
		interfaceCB(0,false)
	end
end

function registerInterfaceCallback(cbFunction)
  interfaceCB = cbFunction
end

function getDefaultNewsCategory()
  return news.defaultCategory
end

function getDefaultWeatherLocation()
	return weather.defaultLocation
end


--returns true if the datastore is empty
function IsEmpty()
   return internal.IsFakeData
end


--[[
--    Function: resetWeatherFlag
--    Intended usage: Reset the "new alert" flag when the user has seen a weather alert
--    Parameters: alert_id - The alert ID for which the flag is to be reset
--    Return value: SUCCESS if alert_id exists, FALSE otherwise
--]]


function resetWeatherAlertFlag(alert_id)

  if weather.alerts[alert_id] == nil then
    return FAILURE
  end
  
  weather.alerts[alert_id].flag = false
  internal.persistReqd = true
  
  return SUCCESS

end

--Sets the datastore persistReqd flag 
--The persistReqd flag states whether the data store contents
--are consistent with the persisted store
--This flag is set to true whenever the contents are not current,
--and the datastore needs to actually do a persist, when datastore.persist() is called

function setPersist()
	internal.persistReqd = true
end
-- Pesists data store to the FS location

function setScriptsPersist()
  internal.scriptPersistReqd = true
end

if not _pclua then


--[[ 
-- Function: persist
-- Persists the datastore to the FS. 
-- Pesists the following tables:
-- config{}, marketing{}, internal{}, news{}, weather{}, sports{}, money{}, movies{} and extras{} (if present)
-- Parameters: None
-- Return value: SUCCESS if the operation succeeds
-- error code otherwise
-- Failure may occur due to FS errors/ persist errors
-- ]]
function persist()

  -- This is done if the user presses ##ONDEMANDCLR# and does not power cycle
  if config ~= nil and config.MDN == nil and internal.persistReqd then
     -- We need to persist conf file
	 internal.confPersistReqd = true
	 
	 -- Set the MDN
     set_mdn(sys.get_deviceinfo_string(AEE_DEVICEITEM_MDN))
  end

  if not internal.confPersistReqd then
	  print("Datastore: config information is current, not persisting datastore_conf.dat")
  else
          print( "Datastore: Persisting datastore_conf.dat" )
	  
	  local confTable = {}
	  confTable.internal = internal
	  confTable.config = config
  
	 file.remove("datastore_conf.dat")

	 local confTables, err = io.open('datastore_conf.dat', 'w') --create the file if it's not there already
	  if confTables == nil then
            print("Datastore: Could not open datastore_conf.dat")
	    return err
	 end

	 local bufTable = lpersist.persist({}, confTable)
	 confTables:write(bufTable)
  	 internal.confPersistReqd = false
	 io.close(confTables)
	 print("Datastore: Finished persisting datstore_conf.dat")
	 
 end

 print("Datastore: Now checking to see if persist needed for datastore_data.dat")
 if not internal.persistReqd then 
	print( "Datastore data is unchanged, not persisting datastore_data.dat" )
 else
          print( "Datastore: Persisting datastore_data.dat" )
 local dataTables, err = io.open('datastore_data.dat', 'w') --create the file if it's not there already
  if dataTables == nil then
    return err
 end
  
  local dataTable = {}
  dataTable.marketing = marketing
  dataTable.images = images
  dataTable.downloadImages = downloadImages
  dataTable.news = news
  dataTable.weather = weather
  dataTable.sports = sports
  dataTable.money = money 
  dataTable.movies = movies

 local bufTable2 = lpersist.persist({}, dataTable)
 dataTables:write(bufTable2)
 io.close(dataTables)

 internal.persistReqd = false
 end

 if not internal.scriptPersistReqd then
	print("Datastore script is unchanged, not persisting datastore_script.dat")
 else
        print( "Datastore: Persisting datastore_script.dat" )
	local scriptTables, err = io.open('datastore_script.dat', 'w') --create the file if it's not there already
	if scriptTables == nil then
		return err
	end

	local bufTable3 = lpersist.persist({}, scripts)
	err = scriptTables:write(bufTable3)
	if err == nil then
        	print( "Datastore: Write to datastore_script.dat failed" )
	else
		internal.scriptPersistReqd = false
	end
	io.close(scriptTables)
 end
end -- persist()

function unpersist()
  print("Datastore:: datastore.unpersist()")	

  local confTables, err1 = io.open('datastore_conf.dat', 'r')
   if confTables == nil then
     print( "Datastore:: Could not open datastore_conf.dat")
     return false 
  end

  local bufTables = confTables:read('*a')
  io.close(confTables)


  local confTable = lpersist.unpersist({} , bufTables)
 
  if not confTable then
	 print("Datastore:: Could not unpersist the conf table")
	 return false
  end

  internal = confTable.internal
  config = confTable.config

  
 
  
  local dataTables, err1 = io.open('datastore_data.dat', 'r')
  if dataTables == nil then
    print( "Datastore:: Could not open datastore_data.dat")
    return false 
  end

  local bufTables2 = dataTables:read('*a')
  io.close(dataTables)


  local dataTable = lpersist.unpersist({} , bufTables2)
 
  if not dataTable then
	 print("Datastore:: Could not unpersist the data table")
	 return false
  end

  marketing = dataTable.marketing
  images = dataTable.images
  downloadImages = dataTable.downloadImages
  news = dataTable.news
  weather = dataTable.weather
  sports = dataTable.sports
  money = dataTable.money 
  movies = dataTable.movies

 -- assumption: internal and config are the only key tables that have to be in the persisted FS store ,
 -- it is possible that the remaining tables were really not present in persisted store
 
  if (not internal) or (not config) then
	 print("Datastore:: Error in unpersisting internal and/or config - datastore_conf.dat could be corrupt")
	 return false
  end

  local scriptTables, err1 = io.open('datastore_script.dat', 'r')

  if scriptTables == nil then
	print( "Datastore:: Could not open datastore_script.dat")
	scripts = nil
  else
	local bufTables3 = scriptTables:read('*a')
	io.close(scriptTables)

	scripts = lpersist.unpersist({} , bufTables3)
  end

  print("Successfully initialized all the tables from unpersisted files")
 
  internal.IsBeingUpdated = false
  internal.persistReqd = false
  internal.confPersistReqd = false
  internal.scriptPersistReqd = false

  return true

 end -- unpersist()


end -- not _pclua

--main ()

 -- Only if running on PC Lua (for testing)
if _pclua then
	initNewStore()
end

-- end main()
