OSDN Git Service

2d7de5b8e2482d3a492a916ef3e985d3b1f58a06
[pettanr/pettanr.git] / app / models / panel.rb
1 class Panel < ActiveRecord::Base
2   belongs_to :comic
3   belongs_to :author
4   belongs_to :resource_picture
5 #  belongs_to :background_picture, :class_name => 'ResourcePicture'
6   has_many :panel_pictures, :dependent => :destroy
7   has_many :balloons, :dependent => :destroy
8   accepts_nested_attributes_for :panel_pictures, :allow_destroy => true
9   accepts_nested_attributes_for :balloons, :allow_destroy => true
10
11   validates :comic_id, :presence => true, :numericality => true, :existence => true, :uniqueness => {:scope => :t} 
12   validates :resource_picture_id, :numericality => {:allow_blank => true}
13   validates :width, :presence => true, :numericality => true, :natural_number => true
14   validates :height, :presence => true, :numericality => true, :natural_number => true
15   validates :border, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
16   validates :x, :numericality => {:allow_blank => true}
17   validates :y, :numericality => {:allow_blank => true}
18   validates :z, :numericality => {:allow_blank => true, :greater_than => 0}
19   validates :t, :presence => true, :numericality => {:greater_than_or_equal_to => 0}
20   validates :author_id, :presence => true, :numericality => true, :existence => true
21   
22   def supply_default au
23     c = self.comic_id ? Comic.show(self.comic_id, au) : nil
24     if c
25       self.width = c.width if self.width.blank?
26       self.height = c.height if self.height.blank?
27       self.t = Panel.new_t(c.id) if self.t.blank? and self.new_record?
28     end
29     self.border = 0 if self.border.blank?
30     self.author_id = au.id
31   end
32   
33   def self.new_t comic_id
34     r = Panel.max_t(comic_id)
35     r.blank? ? 0 : r.to_i + 1
36   end
37   
38   def self.max_t comic_id
39     Panel.maximum(:t, :conditions => ['comic_id = ?', comic_id])
40   end
41   
42   def self.find_t comic_id, t
43     Panel.find(:first, :conditions => ['comic_id = ? and t = ?', comic_id, t])
44   end
45
46   #更新する時にPanelIDをチェックしとかないと勝手に所属先を変えられるゾ!?
47
48   def vdt_save
49     f = nil
50     f = Panel.find_t(self.comic_id, self.t) if self.t
51     if f
52       Panel.update_all('t = t + 1', ['comic_id = ? and t >= ?', self.comic_id, self.t])
53     else
54       self.t = Panel.new_t self.comic_id
55     end
56     self.save
57   end
58   
59   def move_to new_t
60     return true if self.t == new_t
61     if self.t > new_t
62       Panel.update_all('t = t + 1', ['comic_id = ? and (t >= ? and t < ?)', self.comic_id, new_t, self.t])
63     else
64       nf = Panel.find_t(self.comic_id, new_t)
65       max_t = Panel.max_t.to_i self.comic_id
66       new_t = max_t if new_t > max_t
67       Panel.update_all('t = t - 1', ['comic_id = ? and (t > ? and t <= ?)', self.comic_id, self.t, new_t])
68     end
69     self.t = new_t
70     self.save
71   end
72   
73   def destroy_and_shorten
74     Panel.update_all('t = t - 1', ['comic_id = ? and (t > ?)', self.comic_id, self.t])
75     self.destroy
76   end
77   
78   def self.default_page_size
79     25
80   end
81   
82   def self.max_page_size
83     100
84   end
85   
86   def self.page prm = nil
87     page = prm.to_i
88     page = 1 if page < 1
89     page
90   end
91   
92   def self.page_size prm = self.default_page_size
93     page_size = prm.to_i
94     page_size = self.max_page_size if page_size > self.max_page_size
95     page_size = self.default_page_size if page_size < 1
96     page_size
97   end
98   
99   def self.offset cnt, prm = nil
100     offset = prm.to_i
101     offset = cnt - 1 if offset >= cnt
102     offset = cnt - offset.abs if offset < 0
103     offset = 0 if offset < 0
104     offset
105   end
106   
107   def self.list opt = {}, page = 1, page_size = self.default_page_size
108     opt.merge!(self.list_opt) unless opt[:include]
109     opt.merge!({:order => 'updated_at desc', :limit => page_size, :offset => (page -1) * page_size})
110     Panel.find(:all, opt)
111   end
112   
113   def self.list_opt
114     {:include => {
115       :comic => :author, 
116       :panel_pictures => {
117         :resource_picture => {:artist => {}, :license => {}}
118       }, 
119       :balloons => {:speaches => {}},
120       :author => {}
121     }}
122   end
123   
124   def self.list_json_opt
125     {:include => {
126       :comic => :author, 
127       :panel_pictures => {
128         :resource_picture => {:artist => {}, :license => {}}
129       }, 
130       :balloons => {:speaches => {}},
131       :author => {}
132     }}
133   end
134   
135   def self.show rid, au, opt = {}
136     r = Panel.find(rid, :include => self.show_include_opt(opt))
137     raise ActiveRecord::Forbidden unless r.visible?(au)
138     r
139   end
140   
141   def self.show_include_opt opt = {}
142     res = {
143       :comic => :author, 
144       :panel_pictures => {
145         :resource_picture => {:artist => {}, :license => {}}
146       }, 
147       :balloons => {:speaches => {}},
148       :author => {}
149     }
150     res.merge!(opt[:include]) if opt[:include]
151     res
152   end
153   
154   def self.show_json_include_opt
155     {:include => {
156       :comic => :author, 
157       :panel_pictures => {
158         :resource_picture => {:artist => {}, :license => {}}
159       }, 
160       :balloons => {:speaches => {}},
161       :author => {}
162     }}
163   end
164   
165   def visible? au
166     return false unless au
167     return false unless self.comic
168     self.comic.visible?(au) or self.author_id == au.id
169   end
170   
171   def own? author
172     return false unless author
173     self.author_id == author.id
174   end
175   
176   def sort_by_time
177     pe = []
178     self.panel_pictures.each do |picture|
179       pe[picture.t] = picture
180     end
181     self.balloons.each do |balloon|
182       pe[balloon.t] = balloon
183     end
184     pe
185   end
186   
187   def each_element
188     self.sort_by_time.each do |e|
189       yield e
190     end
191   end
192   
193   def panel_elements
194     res = []
195     self.each_element do |elm|
196       if elm.kind_of?(PanelPicture)
197         res[elm.t] = elm.to_json({:include => :resource_picture})
198       end
199       if elm.kind_of?(Balloon)
200         res[elm.t] = elm.to_json({:include => :speaches})
201       end
202     end
203     res
204   end
205   
206   def to_json_play
207     self.to_json :methods => :panel_elements
208   end
209 end