# require 'ish/premium_item'
# require 'ish/utils'
class WcoGame::Location
include Mongoid::Document
include Mongoid::Timestamps
# include Ish::PremiumItem
include Mongoid::Paranoia
include Wco::Utils
store_in collection: 'gameui_maps'
field :name
field :newsitems_page_size, default: 25
field :slug
validates :slug, uniqueness: true, presence: true
field :description
has_many :markers, :class_name => '::Gameui::Marker', inverse_of: :map
has_many :from_markers, :class_name => '::Gameui::Marker', inverse_of: :destination
has_many :newsitems, inverse_of: :map, order: :created_at.desc
# @TODO: remove field, replace with relation. _vp_ 2022-09-13
field :parent_slug
belongs_to :parent, class_name: '::Gameui::Map', inverse_of: :childs, optional: true
has_many :childs, class_name: '::Gameui::Map', inverse_of: :parent
has_one :image, class_name: '::Ish::ImageAsset', inverse_of: :location
belongs_to :creator_profile, class_name: '::Ish::UserProfile', inverse_of: :my_maps
has_and_belongs_to_many :bookmarked_profiles, class_name: '::Ish::UserProfile', inverse_of: :bookmarked_location
# shareable, nonpublic
field :is_public, type: Boolean, default: true
scope :public, ->{ where( is_public: true ) }
has_and_belongs_to_many :shared_profiles, :class_name => 'Ish::UserProfile', :inverse_of => :shared_locations
field :version, type: String, default: '0.0.0'
## @TODO: or self, right? and refactor this, seems N+1. _vp_ 2022-09-13
field :map_slug
def map
::Gameui::Map.where( slug: map_slug ).first
end
RATED_OPTIONS = [ 'pg-13', 'r', 'nc-17' ]
field :rated, default: 'pg-13' # 'r', 'nc-17'
## Possible keys: description, map, markers, newsitems,
field :labels, type: Object, default: <<~AOL
{ "description":"Description", "map":"Map", "markers":"Markers", "newsitems":"Newsitems"
}
AOL
## Possible keys:
## config.description.collapsible
field :config, type: Object, default: <<~AOL
{ "map_panel_type": "ThreePanelV1",
"studio": { "hasFloor": true, "studioLength": 2500, "studioWidth": 2500 }
}
AOL
# @deprecated, dont use!
field :img_path
## Not used! See config.map_panel_type instead.
# MAP_TYPES = [ :map_2d, :map_3d, :map_geospatial, :map_gallery, :map_toc ] ## Mostly not implemented. _vp_ 2022-09-06
# field :map_type, default: :map_2d
## Make sure to use x,y,z and w,h as appropriate.
## @TODO: abstract this into a module
field :x, type: Float
field :y, type: Float
field :z, type: Float
## Make sure to use x,y,z and w,h as appropriate.
field :w, type: Integer
validates :w, presence: true
field :h, type: Integer
validates :h, presence: true
# @TODO: this is shared between map and marker, move to a concern.
before_validation :compute_w_h
def compute_w_h
return if !image ## @TODO: test this
begin
geo = Paperclip::Geometry.from_file(Paperclip.io_adapters.for(image.image))
self.w = geo.width
self.h = geo.height
rescue Paperclip::Errors::NotIdentifiedByImageMagickError => e
puts! e, 'Could not #compute_w_h'
# @TODO: do something with this
end
end
ORDERING_TYPE_ALPHABETIC = 'alphabetic'
ORDERING_TYPE_CUSTOM = 'custom'
ORDERING_TYPE_TIMESTAMP = 'timestamp'
ORDERING_TYPES = [ ORDERING_TYPE_ALPHABETIC, ORDERING_TYPE_CUSTOM, ORDERING_TYPE_TIMESTAMP ]
field :ordering_type, type: String, default: 'custom' # timestamp, alphabetic, custom
validates :ordering_type, presence: true
def self.list conditions = { is_trash: false }
out = self.order_by( created_at: :desc )
[[nil, nil]] + out.map { |item| [ item.name, item.id.to_s ] }
end
def breadcrumbs
out = [{ name: self.name, slug: self.slug, link: false }]
p = self.parent
while p
out.push({ name: p.name, slug: p.slug })
p = p.parent
end
out.reverse
end
##
## @TODO: move the export func, below, to a module. _vp_ 2022-09-20
##
def empty_export
return {
galleries: {},
image_assets: {},
maps: {}, markers: {},
newsitems: {},
photos: {}, profiles: {},
reports: {},
videos: {},
}
end
def self.empty_export; Gameui::Map.new.empty_export; end
def empty_export_arr
return {
galleries: [],
image_assets: [],
maps: [], markers: [],
newsitems: [],
photos: [], profiles: [],
reports: [],
videos: [],
}
end
def export_key_to_class
return {
galleries: 'Gallery',
image_assets: 'Ish::ImageAsset',
maps: 'Gameui::Map',
markers: 'Gameui::Marker',
newsitems: 'Newsitem',
photos: 'Photo',
profiles: 'Ish::UserProfile',
reports: 'Report',
videos: 'Video',
# 'galleries' => 'Gallery',
# 'image_assets' => 'Ish::ImageAsset',
# 'maps' => 'Gameui::Map',
# 'markers' => 'Gameui::Marker',
# 'newsitems' => 'Newsitem',
# 'photos' => 'Photo',
# 'profiles' => 'Ish::UserProfile',
# 'reports' => 'Report',
# 'videos' => 'Video',
}.with_indifferent_access
end
def self.export_key_to_class
Map.new.export_key_to_class
end
def export_fields
%w|
creator_profile_id config
deleted_at description
h
is_public
labels
map_slug
name
ordering_type
parent_slug
rated
slug
version
w
|
end
## This is the starting point _vp_ 2022-03-12
##
def export_subtree
collected = collect(empty_export)
exportable = empty_export_arr
collected.map do |k, v|
if v.present?
v.map do |id|
id = id[0]
item = export_key_to_class[k].constantize.unscoped.find id
export = item.export
exportable[k].push( export )
end
end
end
JSON.pretty_generate exportable
end
def collect export_object
map = self
export_object[:maps][map.id.to_s] = map.id.to_s
if map.markers.present?
map.markers.map do |marker|
id = marker.id.to_s
if !export_object[:markers][id]
marker.collect( export_object )
end
export_object[:markers][id] = id
end
end
if map.newsitems.present?
map.newsitems.map do |newsitem|
id = newsitem.id.to_s
export_object[:newsitems][id] = id
newsitem.collect export_object
end
end
## @TODO: maybe implement this later, maybe not. _vp_ 2022-03-12
# if map.childs.present?
# export_object[:maps].push( map.childs.map &:id )
# map.childs.map do |child|
# child.collect export_object
# end
# end
if map.creator_profile.present?
export_object[:profiles][map.creator_profile.id.to_s] = map.creator_profile.id.to_s
end
if map.image.present?
export_object[:image_assets][map.image.id.to_s] = map.image.id.to_s
end
export_object
end
## endExport
end